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

实验目的

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

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

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

实验内容

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

实验指令

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

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

objdump -d pwn1将pwn1反汇编,得到以下代码

 

 

系统调用foo函数对应机器指令为e8 d7ffffff,则如果想调用getShell函数,就要对e8 d7ffffff进行修改。

  • 输入命令 cp pwn1 pwn2对pwn1中的内容进行拷贝至pwn2
  • vi打开pwn2,输入:%!xxd将显示模式切换为十六进制
  • 进入插入模式,修改d7c3
  • 输入:%!xxd -r将十六进制转换为原格式
  • 使用:wq保存并退出

然后进行运行

因权限不够需要输入命令chmod +x pwn2

实验2 通过构造输入参数,造成BOF攻击

  • 利用缓存区溢出进行攻击,是利用输入的数据将返回值进行覆盖。如果用getShell函数的地址进行覆盖,就会使程序调用getShell函数实现BOF攻击。
  • 调用函数的时候,就会将函数的地址作为返回值压栈,即放入栈顶。字符串字节数足够大的时候就能覆盖返回值。
  • 理清思路,使用gdb进行调试,弄清楚是哪几个字节会覆盖返回地址。

      确认输入字符串哪几个字符会覆盖到返回地址

 

关于Perl:
Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。
使用输出重定向“>”将perl生成的字符串存储到文件input中。

然后将input的输入,通过管道符“|”,作为pwn1的输入。

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

  • shellcode就是一段机器指令
  • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
  • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
  • 首先使用apt-get install execstack命令安装execstack。
  1. 关闭堆栈保护(gcc -fno-stack-protector)
  2. 关闭堆栈执行保护(execstack -s)
  3. 关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)
  4. 在x32环境下
  5. 在Linux实践环境

      


在另一个终端查看pwn1这个进程,用gdb来调试pwn1这个进程。

通过设置断点,来查看注入buf的内存地址

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

最后执行程序:

实验收获与感想

这次实验难度还是很大的,主要是一些相关汇编只是没有完全掌握好,参考了学长的博客,初步理解了缓冲区溢出攻击的原理,理解了堆栈是这么被恶意代码覆盖的,覆盖后是怎么实现跳转的,跳转后是怎么执行的。希望下次实验能有所进步!

posted @ 2019-03-16 11:29  必然帅666  阅读(139)  评论(0编辑  收藏  举报