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],其结构如下图:
一般来说,在xp平台上kernel32.dll是挂在链表的第一位,win7平台以后第一位则是kernelbase.dll,kernel32.dll位于链表的第二位。