5.1.1 Exploit失败原因分析
“攻击失败会有很多原因,我们不考虑对方打了补丁,没有漏洞的情况;也不考虑网络通信问题(如防火墙阻断等)。只从编写Exploit的技术角度出发,分析攻击程序会失败的原因。”
“我们编写攻击程序时有三大步骤,有谁说说是哪三步呢?”老师问道。
“第一、覆盖点的定位;第二、ShellCode的编写;第三、跳转到ShellCode中。”大家都烂熟于胸,一口便答了出来。
“很好!”老师满意的说,“我们就根据这三点来分析攻击程序的失败原因及造成原因吧!”
失败原因一、覆盖点偏差
“这有可能是漏洞公告上分析的版本和大家实际攻击的版本不同造成的;也有些软件由于安装目录不同,其漏洞的覆盖点位置也不同。还有,大家在写Exploit时,有可能自己数错了覆盖的字符个数,这也是初学者经常犯的错误。”
“嗯!有时候累了就是容易数错啊!”同学们说道。
“要解决这个问题只有仔细些。”老师说道,“认真看清楚公告的内容,数清楚覆盖字符的个数。”
失败原因二、错误的跳转地址
“有些公布出来的程序,为了避免滥用,给的只是针对某个系统的跳转地址,甚至有的程序连地址都没有,只有0xAAAAAAAA或0xXXXXXXXX这样的形式在覆盖点位置,这要我们自己去修改。”
“前面在讲堆溢出时也说过,有时地址是正确的,但所属的dll没有被加载,这样地址所在的地方根本没有指令,也就没有我们想要的JMP ESP或CALL [esi+0x4c]啦!”
“也有这种情况,有时候昏头了,我们把0x7FFA4512在字符串里直接写成‘\x7F\xFA\x45\x12’。”老师笑道,“但这是错误的!应该是‘\x12\x45\xFA\x7F’,这一点大家要小心。”
小知识:为什么0x7FFA4512要写成“\x12\x45\xFA\x7F”
在Intel系列的计算机下,数据的排列规则是:高位数据在高地址,低位数据在低地址。7F是最高位数据,所以要放在最高地址——就是“\x12\x45\xFA\x7F”的最后;而12是最低位数据,因此要放在最前面——最低地址。
失败原因三、ShellCode被截断或改写
老师强调道,“这是最常见的问题,随时都可能遇到。”
“哦?ShellCode被谁改写了呢?”玉波问道。
“被目标程序自己!”老师说,“任何目标程序都有一些特殊字符不能使用,比如IIS里面不能有0x20,如有,就会把后面的数据截断;而Cmail的漏洞不能有大写字母,如有,会自动转为小写字母。这样,我们的ShellCode有可能被截断或替换,当然就完不成攻击功能了。”
判断Exploit失败原因的方法
“无论是覆盖地址错误,还是ShellCode被改变,表现出来的现象都是不能完成我们想要的功能。”老师说道,“在这种情况下,我们就需要知道究竟是覆盖地址错误了,还是ShellCode被改变了?”
“如何判断呢?”
“要确定是哪种原因,有一个比较菜鸟的办法:就是在ShellCode的最前面加上‘\xEB\xFE’,即JMP –1的机器码。这样构造一个死循环。”
“哦!我们在堆栈溢出利用时,将JMP ESP改为JMP EBX方式,用的也是\xEB\xFE来寻找异常点的啊!”宇强说道。
“是啊!可不要小瞧了它,在调试中是很有用的。”老师说道,“我们运行写好的Exploit攻击程序,如果返回地址正确,就会跳入‘\xeb\xfe’这句死循环中,我们按Ctrl+D调出SoftIce,就会发现系统一直陷入这句指令不走了。然后对照跟在后面的ShellCode,看其是否和我们编写的一样,这样比较容易发现问题。”
“如果发现没有陷入‘\xeb\xfe’这句死循环,可以肯定覆盖的地址是错的,需要重新定位覆盖点,或换成通用的覆盖地址。”
“而进入了‘\xeb\xfe’死循环,那么我们的苦力活就来了,要一个字节一个字节地同原ShellCode核对,直到发现是哪个字节被改变了。”
“哦,这个工作我喜欢!”古风乐呵呵地说,“就是核对内存数据嘛!像‘大家来找茬’游戏一样,我可是高手哦!”
“好啊,以后像什么劈柴之类的苦力活就交给你啦!”玉波狡黠地说,“我可不擅长这类工作。”
“好了,我举个亲身例子吧,”老师说道,“我最早在测试Foxmail漏洞时,就是用该方法来发现别人程序的返回地址在自己机器上是无效的,溢出后进入不了‘\xeb\xfe’这句死循环,之后我就换了一个返回地址,终于可以进入‘\xeb\xfe’了,但还是完成不了功能。然后我就对照ShellCode,发现原来是ShellCode中的‘/’被替换了。知道问题就好办了,换了一个符合要求的就OK了。”
“在调试RtlAllocate堆溢出漏洞时,我也是这样发现user32.dll根本没有加载,因此就没有call [esi+0x4c]的指令了。所以我提醒大家要先LoadLibrary("user32.dll")加载user32.dll,这样才能利用成功。”
大家听得津津有味。
“有时经验是可遇不可求的,所以这里花点时间讲,希望对大家有用。”
“嗯,对我们很有帮助啦!收下了!”同学们说道。
“哈哈,好的!当Exploit失败,是因为ShellCode里不能有某些字符时我们就需要对ShellCode进行编码变换。”