天天看点

shellcode的两个关键技术1.shellcode代码重定向 2.在内存中寻找kernel32.dll位置

1.shellcode代码重定向

当我们获得一个溢出缓冲区,要向其中注入代码时,为保证shellcode代码在任意机器上正常运转,我们必须获得shellcode

注入的地址,在此我们要用到的一个关键的技术:代码重定向

  • call指令本质包含两个步骤:压栈和跳转
  • call指令后接跳转地址,在二进制表示时使用的是相对地址
//汇编指令
call 40400

//等同于
push current //call指令当前所处位置
jmp   40400

//利用实例
begin:
       call entry   //E8 00000000
entry:pop ebx   //ebx中所存为注入点地址
       // do something ...
           

2.在内存中寻找kernel32.dll位置

当我们重定向了代码,开始进行系统调用是,问题来了,函数地址在哪呢?

因为dll的加载都是任意的,你无法在事先确定函数地址,所以我们只能通过GetProcAddress()函数来动态获得函数地址

但是GetProAddress()的地址也不知道啊,可能有人会问了大笑

这不是死循环吗?

我们强大的帽子总是有办法的,先给出实例代码,稍后解释。

mov eax, fs:[30]                  //PEB

     mov eax,[eax+0ch]                 //PEB_LDR_DATA

     mov  esi,[eax+1ch]                //InInittializationOrderModuleList

     lodsd

     mov ebx,[eax+08h]                //base address

     if base.name=="kernel32.dll"     //xp and more

          jmp  ok

     then                              //win7

          mov esi,eax

          lodsd

          mov ebx,[eax,08h]

ok:                                    //到此ebx所存即为kernel32.dll的内存地址

    //do something....
           

通过以上代码可以从任意平台动态获取kernel32.dll的加载地址。

了解PE结构的人就了解,知道了kernel32.dll的人就会知道如何通过这地址获得GetProAddress()地址,进而获得Windows平台下任意API函数地址。

PE结构不再此博文讨论之列,若读者不清楚可自行学习,不难但繁琐。

先对以上代码解释:

PEB结构----枚举用户模块列表

它所处位置为 fs:[30],其结构如下图:

shellcode的两个关键技术1.shellcode代码重定向 2.在内存中寻找kernel32.dll位置

一般来说,在xp平台上kernel32.dll是挂在链表的第一位,win7平台以后第一位则是kernelbase.dll,kernel32.dll位于链表的第二位。

继续阅读