1.5.1 ShellCode的定位

老师说:“现在我们有了前两步,返回点定位和ShellCode的编写,现在只需完成第三步——把返回点覆盖成ShellCode的地址,就可成功利用缓冲区溢出了!”

“哈哈,太好了!”玉波的口水都要流出来啦……

“现在的问题就是:ShellCode所在地址是多少呢?即我们把返回地址覆盖成多少?”

“呜……好像不好办啊……”

“嗯,在以前很多朋友提出了不少方法来定位ShellCode,但都不精确。随着技术的发展,1999年dark spyrit AKA Barnaby Jack提出了一个天才的想法:用系统核心dll里的指令来完成跳转!这一技巧开创了一个崭新的Windows缓冲区溢出思路!”

小知识:

过去(尤其是在Unix下),提出过的覆盖方法主要有两种:

1.NNNNNNNNNSSSSSSSSSSSRRRRRRRRRRRRRR型。适合于大缓冲区,“N”代表空指令,也就是0x90,在实际运行中,程序将什么也不做,而是一直延着这些NOPS运行下去,直到遇到不是NOPS的指令再执行之;“S”代表ShellCode;“R”代表覆盖的返回地址,思路是把返回地址R覆盖为nops的大概位置,这样就会跳到Nop中,然后继续执行,直到我们的ShellCode中。但这种方法由于定位不准确,所以使用起来也不准确。

2.RRRRRRRRRRNNNNNNNNNNNSSSSSSSSSS型。是用大量的“R”填满整个缓冲区,然后大量的Nop,最后是ShellCode。这里,“R”往后跳到Nop中,再顺着往下执行就会到ShellCode中。但在Windows下,“R”中必定会含有0,这样,整个构造就会被截断,只能用于Unix中。

Windows的系统核心dll包括kernel32.dll、user32.dll、gdi32.dll。这些dll一直位于内存中,而且对应于固定的版本,Windows加载的位置是固定的。

老师继续说:“我们来看看在Windows下如何利用系统核心dll里的指令来完成跳转吧。我们用系统核心dll中的jmp esp地址来覆盖返回地址,而把ShellCode紧跟在后面,这样就可跳转到我们的ShellCode中。其利用格式是 NNNNNNRSSSSSS,N=Nop, S=ShellCode, R=jmp esp的地址 ”

同学们急了:“等一下,为什么用JMP ESP的地址覆盖就可以跳到后面的ShellCode中呢?”

“这里是关键的地方,理解了这个就理解了整个缓冲区溢出攻击!下面是详细的讲解,大家注意跟上。你们看,覆盖后的缓冲区如图1-8所示:‘N’表示NOP,存原EIP的地方覆盖成了JMP ESP的地址,接下去的‘S0’、‘S1’等表示ShellCode开始的0字节、1字节等。”

“嗯,这个没有问题。”

老师说:“函数执行完毕,要返回时堆栈指针ESP会指向保存原EIP的地方,而指令指针EIP指向Ret指令。如图1-9。”

“Ret?Ret是什么?”有人问道。

“Ret相当于 Pop EIP ,就是把栈顶指针ESP指向的值弹出来给EIP。所以在正常情况下,Ret执行后,就可把原来的EIP恢复,从而回到中断前的流程。”

“哦!”

“但是,保存的EIP已经被我们覆盖成JMP ESP指令的地址了。这样执行 Pop EIP 后,EIP会被改为JMP ESP的地址,即指向JMP ESP。而堆栈指针ESP往下移一位,指向ShellCode的第一个字节(即图1-9中的‘S0’)了。如图1-10。”

“计算机不知道我们做了手脚,继续往下执行EIP指向的指令——JMP ESP,而ESP指向的是‘S0’,这样就JMP到了‘S0’中,开始执行我们的ShellCode了!如下图1-11。”

小知识:

EIP指令指针指向下一条要执行的命令,一般会自动加1。ESP堆栈顶指针指向堆栈的顶部。在PUSH时,ESP往上走,减1;在POP时,ESP往下走,加1。

“哦!有点感觉了,但还不是非常清楚。”

“我再用具体的数字重复一下这个过程吧!”老师耐心的讲解道,“‘FF E4’是JMP ESP的机器码,而在Windows 2000 SP2下,地址0x77e0492b里正好就是‘FF E4’。所以我们用0x77e0492b(即JMP ESP指令的地址)来覆盖保存的EIP,如图1-12。”

“当程序返回时,执行 Ret=POP EIP ,EIP就变成0x77e0492b了,而ESP往下走,指向ShellCode的第一个字节中,如图1-13。”

“系统不知道我们做了手脚,继续执行。执行EIP指向的指令,就是‘FF E4’,即JMP ESP。而此时的ESP指向后面ShellCode的第一个字节,执行‘FF E4’(即JMP ESP)就正好进入到我们的ShellCode中啦!”老师万般耐心的说道,生怕大家有一点不懂。

“下来大家再仔细想想,多看看上面的图和讲解。我们先实际感受一下。”