文章来源:
win32堆栈溢出入门
版本号1.0
文档作者netxfly
更新日期2007 年5 月10 日
版本号1.0
文档作者netxfly
更新日期2007 年5 月10 日
关键字:
overflow、debug、Shellcode、Win32 Exploit
综述:
本文通过几个实例介绍了如何利用已知的poc 进行漏洞调试的基本方法。
Windbg 下载:
overflow、debug、Shellcode、Win32 Exploit
综述:
本文通过几个实例介绍了如何利用已知的poc 进行漏洞调试的基本方法。
Windbg 下载:
http://microsoft.com/whdc/devtools/debugging/installx86.Mspx
Metasploit 下载:
Metasploit 下载:
http://metasploit.com
POC 下载:
POC 下载:
http://milw0rm.com/
XnView 1.90.3 下载地址:
XnView 1.90.3 下载地址:
http://www.crsky.com/soft/1187.html
ACDSee v9.0 官方简体中文版:
ACDSee v9.0 官方简体中文版:
如上代码所示,为局部变量分配10bytes,然后copy 10
个字节进去,程序
会正常输出。当我们把要拷贝到缓冲区的字符加大到20,就会发生缓冲区溢出,
如图2 所示。
会正常输出。当我们把要拷贝到缓冲区的字符加大到20,就会发生缓冲区溢出,
如图2 所示。
事实上,win32 的堆栈是默认4
字节对齐的,操作系统为buffer 分配的缓冲
区大小为12 字节,随后的4 字节为保存在堆栈中EBP 的值,接下来的的4 字
节便是主函数的返回地址RET 了。我们将第16 至20 个字节改为BBBB 后再编
译运行一次程序。如图3 所示,提示出错的地址为42424242,这正好是BBBB
的ASCII 值。
区大小为12 字节,随后的4 字节为保存在堆栈中EBP 的值,接下来的的4 字
节便是主函数的返回地址RET 了。我们将第16 至20 个字节改为BBBB 后再编
译运行一次程序。如图3 所示,提示出错的地址为42424242,这正好是BBBB
的ASCII 值。
■ Exploit It!
由于这个程序的缓冲区太小,没法放我们ShellCode,我们把buffer 数组的
容量改为2000 就足以存放我们的ShellCode 了。
由于这个程序的缓冲区太小,没法放我们ShellCode,我们把buffer 数组的
容量改为2000 就足以存放我们的ShellCode 了。
根据前面的知识,我们推算出溢出点在2005
的位置,我们用JMP ESP 来
覆盖溢出点,最后EIP 就会跳转到RET 后面中的SHELLCODE 中。利用方式
如下:
NNNNNNN + EBP + RET + ShellCode + NNNNN
N 表示Nop,但是在这个程序中,我们的ShellCode 太长了,放在RET 后
面就会覆盖到程序中的一些其他地址,导致函数无数返回,结果却触发不了溢出
点。所以我们只能把ShellCode 放在溢出点前面,然后让EIP 往前跳,跳到我
们的ShellCode 中,利用示意图为:
NNNNN + ShellCode + NN + EBP + RET + JMP -x +NNN
JMP -x 表示往前跳X 个字节,RET 处我们用中文Win2000/xp/2003 通用
JMP ESP 地址7ffa4512。
在本例中,我们的ShellCode 是由http://metasploit.com 自动生成的,
win32_adduser - PASS=security EXITFUNC=thread USER=security
Size=244 Encoder=PexFnstenvSub,添加一个用户名和口令都为security 的管
理员。
缓冲区大小为2008,我们让EIP 往前跳1000 bytes,后面还有1000 bytes
可以容纳我们的ShellCode,其实也不用这么精确的,只要让能容纳下
ShellCode,然后让EIP 跳转到ShellCode 前面的一大堆空指令中,EIP 就会顺
着这些空指令一直执行到我们的ShellCode 中,最后我们构造的exp 如下图所
示:
覆盖溢出点,最后EIP 就会跳转到RET 后面中的SHELLCODE 中。利用方式
如下:
NNNNNNN + EBP + RET + ShellCode + NNNNN
N 表示Nop,但是在这个程序中,我们的ShellCode 太长了,放在RET 后
面就会覆盖到程序中的一些其他地址,导致函数无数返回,结果却触发不了溢出
点。所以我们只能把ShellCode 放在溢出点前面,然后让EIP 往前跳,跳到我
们的ShellCode 中,利用示意图为:
NNNNN + ShellCode + NN + EBP + RET + JMP -x +NNN
JMP -x 表示往前跳X 个字节,RET 处我们用中文Win2000/xp/2003 通用
JMP ESP 地址7ffa4512。
在本例中,我们的ShellCode 是由http://metasploit.com 自动生成的,
win32_adduser - PASS=security EXITFUNC=thread USER=security
Size=244 Encoder=PexFnstenvSub,添加一个用户名和口令都为security 的管
理员。
缓冲区大小为2008,我们让EIP 往前跳1000 bytes,后面还有1000 bytes
可以容纳我们的ShellCode,其实也不用这么精确的,只要让能容纳下
ShellCode,然后让EIP 跳转到ShellCode 前面的一大堆空指令中,EIP 就会顺
着这些空指令一直执行到我们的ShellCode 中,最后我们构造的exp 如下图所
示:
Exp 执行后成功添加security
管理员,如理图所示:
■ ACDSEE9 溢出学习
在拜读了Cloie 大牛的二篇大作后,对Win32 堆栈溢出有了更深入的认识,
同时也学到了一种很方便的溢出点定位方法,窃喜中,
首先根据作者提供的poc,自已照着写个代码风格清晰的,用6600 个'A'填
充缓冲区,然后生成一个XPM 文件摆放在桌面上。如图所示:
在拜读了Cloie 大牛的二篇大作后,对Win32 堆栈溢出有了更深入的认识,
同时也学到了一种很方便的溢出点定位方法,窃喜中,
首先根据作者提供的poc,自已照着写个代码风格清晰的,用6600 个'A'填
充缓冲区,然后生成一个XPM 文件摆放在桌面上。如图所示:
用ACDSEE9 浏览桌面上的XPM 文件,ACDSEE
进程崩溃了,再次运行
ACDSEE9.exe,然后用CDB 加载其进程,如下图所示:
ACDSEE9.exe,然后用CDB 加载其进程,如下图所示:
ACDSEE9 会自动中断在程序的入口点处,输入g
继续运行程序,然后用
ACDSEE9 再次去浏览桌面上的XPM 文件,这时cdb 会自动中断,并提示地址
41414141 处不可执行,41 就是我们填充的A 的ASCII 码值了。使用dd esp 命
ACDSEE9 再次去浏览桌面上的XPM 文件,这时cdb 会自动中断,并提示地址
41414141 处不可执行,41 就是我们填充的A 的ASCII 码值了。使用dd esp 命
令发现esp
中的值正好是我们填充的垃圾数据A,所以我们可以采用JMP ESP
的方式来利用这个漏洞,接下来就来定位它的溢出点。
先用Cloie 牛写的patternCreate.pl 生成一个长度为6600 的不重复字符串
于文件xxx.txt 中,如下图所示:
的方式来利用这个漏洞,接下来就来定位它的溢出点。
先用Cloie 牛写的patternCreate.pl 生成一个长度为6600 的不重复字符串
于文件xxx.txt 中,如下图所示:
然后将这些字符加入到我们填充缓冲区的数组中,如图所示:
然后再用cdb 加载ACDSEE9 并浏览桌面上的XPM
文件,cdb 会自动中断
在如下的地方。
在如下的地方。
记下37694636
这个地址值,然后再用patternOffset.pl 37694636 6600 就
可确定溢出点的位置,为第4160 个字节处,如下图所示:
可确定溢出点的位置,为第4160 个字节处,如下图所示:
■ Exploit ACDSEE9
用http://metasploit.com 生成一个绑定本地4444 端口的ShellCode,如下
构造Exp,
4160 个N + RET + ShellCode
其实ShellCode 的位置也不用精确的,只要是放在RET 后面就行了,中间插入
几个空指令是不影响ShellCode 的执行的,空指令包括NOP、A、B、C、D。
最后我们写出来的Exp 如下:
用http://metasploit.com 生成一个绑定本地4444 端口的ShellCode,如下
构造Exp,
4160 个N + RET + ShellCode
其实ShellCode 的位置也不用精确的,只要是放在RET 后面就行了,中间插入
几个空指令是不影响ShellCode 的执行的,空指令包括NOP、A、B、C、D。
最后我们写出来的Exp 如下:
编译exp 重新生成一个XPM
文件置于桌面上,然后用ACDSEE9 浏览,连
接本机4444 端口成功得到一个Shell,如下图所示:
接本机4444 端口成功得到一个Shell,如下图所示:
■ xnView 溢出学习
首先根据作者提供的poc,自已照着写个代码风格清晰的,用6600 个'A'填
充缓冲区,然后生成一个XPM 文件摆放在桌面上。如图所示:
首先根据作者提供的poc,自已照着写个代码风格清晰的,用6600 个'A'填
充缓冲区,然后生成一个XPM 文件摆放在桌面上。如图所示:
用xnview 浏览时,发现其进程崩溃了,用cdb
加载xnview.exe 后浏览桌
面上的XPM 文件,cdb 会检测到异常,不予理会,输入g 继续执行,最终会断
在下面的地方,
面上的XPM 文件,cdb 会检测到异常,不予理会,输入g 继续执行,最终会断
在下面的地方,
说明我们填充的A 覆盖到了溢出点,但是ESP
中并没有我们填充的字符A,
而是在与ESP 相邻的地址0172ffa4 中,说明我们覆盖到的是SEH,在Winxp
而是在与ESP 相邻的地址0172ffa4 中,说明我们覆盖到的是SEH,在Winxp
以前可以用JMP/CALL EBX 方式利用,但在Win xp
之后,EBX 的值被设为0
了,无法再使用这种方式来覆盖异常点了,现在常用的是POP/POP/RET 方式。
了,无法再使用这种方式来覆盖异常点了,现在常用的是POP/POP/RET 方式。
覆盖POP/POP/RET 的地址后,EIP
会跳转到其前面的4 个字节处,而这
里的POP/POP/RET 之后的内存会被截断,不适合放较长的ShellCode,我们
可以考虑放置JMP -x 指令往前面跳。所以可以这样构造ShellCode:
NNNN + ShellCode + NNN + JMP 04 + Pop/Pop/RET + Jmp -x + NN
再次利用Cloie 牛传授的溢出点定位大法来定位溢出点,先用
patternCreate.pl 生成一个长度为6600 的不重复字符串于文件xxx.txt 中,如下
图所示:
里的POP/POP/RET 之后的内存会被截断,不适合放较长的ShellCode,我们
可以考虑放置JMP -x 指令往前面跳。所以可以这样构造ShellCode:
NNNN + ShellCode + NNN + JMP 04 + Pop/Pop/RET + Jmp -x + NN
再次利用Cloie 牛传授的溢出点定位大法来定位溢出点,先用
patternCreate.pl 生成一个长度为6600 的不重复字符串于文件xxx.txt 中,如下
图所示:
用xxx.txt
中的不重复字符串填充缓冲区,编译运行exp,将生成
xnviewdbg.xpm 文件并放置于桌面上,然后用cdb 加载xnview.exe 进程,浏览
桌面上的xnviewdbg.xpm,cdb 会中断在如下地方,如下图所示:
xnviewdbg.xpm 文件并放置于桌面上,然后用cdb 加载xnview.exe 进程,浏览
桌面上的xnviewdbg.xpm,cdb 会中断在如下地方,如下图所示:
记下非法地址34764533,然后再用patternOffset.pl
便可得到溢出点的位置为
3761,如下图所示:
3761,如下图所示:
所以我们的ShellCode 可以如下构造:
(3761 - 4)个NOP + Jmp 04 + Pop/Pop/RET + Jmp -x
真正的ShellCode 放置于(3761 - 4)个NOP 中,假如我这里向前跳转3000 个字
节,用metasploit 3 自带的NASM SHELL 把Jmp -3000 指令转换为机器码,如
下图所示:
(3761 - 4)个NOP + Jmp 04 + Pop/Pop/RET + Jmp -x
真正的ShellCode 放置于(3761 - 4)个NOP 中,假如我这里向前跳转3000 个字
节,用metasploit 3 自带的NASM SHELL 把Jmp -3000 指令转换为机器码,如
下图所示:
EXP 的构造为:
编译运行exp,将生成的XnView.xpm
置于桌面上,然后用XnView.exe 浏
览,成功在本地4444 端口绑定一个Shell,不过被防火墙拦截了,如下图所示:
览,成功在本地4444 端口绑定一个Shell,不过被防火墙拦截了,如下图所示:
■ CCProxy6.0
溢出学习
CCProxy6.0 曾经被公布过一个处理HTTP 请求的远程溢出漏洞,先自已写
一个简单的Socket 程序,对目标主机的808 端口发送大量的字符A,如下图所
示:
CCProxy6.0 曾经被公布过一个处理HTTP 请求的远程溢出漏洞,先自已写
一个简单的Socket 程序,对目标主机的808 端口发送大量的字符A,如下图所
示:
编译并执行poc,目标主机的CCProxy
进程崩溃了,然后用cdb 加载
CCProxy 后,再次执行Poc。Cdb 截获到如下异常,
CCProxy 后,再次执行Poc。Cdb 截获到如下异常,
说明我们已经覆盖到溢出点,ESP
中有我们填充的数据A,但是被截断了,
如下图所示:
如下图所示:
所以我们的ShellCode
不能放在后面,只能放在RET 的前面,再度利用Cloie
传授的溢出点定位大法再定位溢出点。用patternCreate.pl 生成5000 个不重复
的字符串并保存于文件CCProxy.txt 中,如下图所示:
传授的溢出点定位大法再定位溢出点。用patternCreate.pl 生成5000 个不重复
的字符串并保存于文件CCProxy.txt 中,如下图所示:
用这些字符串填充缓冲区,重新得到的EXP
如下图所示:
再次用CDB 加载CCProxy.exe
的进程,然后执行exp,目标主机中的CDB
截获异常并中断,如下图所示:
截获异常并中断,如下图所示:
31664630 就是溢出点位置,用patternOffset.pl
查询得知其为4052,如下
图所示:
图所示:
我们的ShellCode 构造如下:
NNNN + ShellCode + NNN + RET + NN
NNNN + ShellCode + NNN + RET + NN
用metasploit.com
生成一个添加用户名和密码都为security 的管理员的
ShellCode,
ShellCode,
执行我们的EXP,可成功在目标主机上添加Security
管理员,如下图所示:
插入表情