让攻击代码执行

直接覆盖返回地址
在栈空间中放置shellcode 最后把该函数的返回地址设置为我的shellcode的返回地址就能让程序返回时执行我的代码。


利用jmp esp
如果shellcode只能放到dll的缓冲区中,或者有PE重定位,载入基地址会改变,这样我们用来覆盖return的地址就不能准确定位shellcode了。

  1. 把shellcode填入缓冲区
  2. 找到内存中任意一个jmp esp指令的地址覆盖掉原本的返回地址。
  3. 函数返回后被重定向执行jmp esp
  4. 因为这时候的esp指向了shellcode的起始地址所以会执行shellcode

这里shellcode是从低地址到高地址存放的。
这种shellcode用jmp esp作为跳板,这样就不用担心重定位问题了
下面是在dll中查找该语句的函数。

#include
#include
#define DLL_NAME L"user32.dll"
void main()
{
    BYTE* ptr;
    int position, address;
    HINSTANCE handle;
    BOOL done_flag = FALSE;
    handle = LoadLibrary(DLL_NAME);//loadLibrary函数默认是宽字符,用TEXT("string")或者L"string"
    if (!handle)
    {
        printf("load dll erro!");
        exit(0);
    }
    ptr = (BYTE*)handle;//转化指针类型用来控制指针++所指向的位置
    for (position = 0; !done_flag; position++)//用position来表示偏移
    {
        try
        {
            if (ptr[position] == 0xFF && ptr[position + 1] == 0xE4)//0xffe4是jmp esp的机器码
            {
                int address = (int)ptr + position;//输出地址要强制转化为int
                printf("%x\n", address);
            }
        }
        catch (...)
        {
            int address = (int)ptr + position;
            printf("end of 0x%x", address);
            done_flag = TRUE;
        }
    }
}

存放shellcode
如何安全地存放shellcode也是一个重要的问题
存放的一般方法:
1. 存放在缓冲区中例如buff[44]存进去很显然缺点是shellcode必须足够小
2.放在返回地址之后,这样可以存放大量代码,但是会破坏原程序尽量不要用的好
3.放在esp上边注意要用一部分空白来填充不然入栈指令会破坏shellcode
除了jmp esp之外,mov eax,esp jmp eax也能达到跳转的目的


碰运气
如果不允许使用jmp而静态覆盖地址来覆盖又不太准确,这时候可以淹没一大片内存区域把shellcode放到一大片nop后面这样如果程序会走到任意一个nop这里就会执行shellcode了
用一大片返回地址来覆盖真正的返回地址,总有一个会命中的

补充:strcat(*str1,*str2)把str2链接到str1后面(中间没有\0) 一般情况下str1是在缓冲区中的
这就给我们的溢出构造了条件


你可能感兴趣的:(溢出攻击,shellcode)