码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 4.3 x64dbg 搜索内存可利用指令


    合集 - 灰帽黑客:攻守道(83)
    1.1.13 导出表劫持ShellCode加载09-012.1.12 进程注入ShellCode套接字09-013.1.10 内存ShellCode注入与格式化08-314.1.9 动态解密ShellCode反弹08-315.1.8 运用C编写ShellCode代码08-306.1.7 完善自定位ShellCode08-307.1.6 编写双管道ShellCode08-298.1.5 编写自定位ShellCode弹窗08-299.1.4 编写简易ShellCode弹窗08-2810.1.3 Metasploit 生成SSL加密载荷08-2811.1.1 Metasploit 工具简介08-2812.5.14 汇编语言:仿写Switch选择结构08-2413.5.13 汇编语言:仿写For循环语句08-2414.5.12 汇编语言:仿写While循环语句08-2415.5.11 汇编语言:仿写IF条件语句08-2416.5.10 汇编语言:汇编过程与结构08-2417.5.9 汇编语言:浮点数操作指令08-2318.5.8 汇编语言:汇编高效除法运算08-2319.5.7 汇编语言:汇编高效乘法运算08-2320.5.6 汇编语言:汇编高效数组寻址08-2321.5.5 汇编语言:函数调用约定08-2222.5.4 汇编语言:算数运算指令集08-2223.5.3 汇编语言:字符串操作指令08-2224.5.2 汇编语言:标志位测试指令08-2225.5.1 汇编语言:汇编语言概述08-2226.4.9 C++ Boost 命令行解析库08-2227.4.8 C++ Boost 应用JSON解析库08-2228.4.7 C++ Boost 多线程并发库08-2129.4.6 C++ Boost 函数绑定回调库08-2130.4.5 C++ Boost 文件目录操作库08-2131.4.4 C++ Boost 数据集序列化库08-2132.4.3 C++ Boost 日期时间操作库08-1833.4.2 C++ Boost 内存池管理库08-1834.4.1 C++ Boost 字符串处理库08-1835.11.1 C++ STL 应用字典与列表08-1736.10.1 C++ STL 模板适配与迭代器08-1737.9.1 C++ STL 排序、算数与集合08-1738.8.1 C++ STL 变易拷贝算法08-1639.7.1 C++ STL 非变易查找算法08-1640.6.1 C++ STL 序列映射容器08-1641.5.1 C++ STL 集合数据容器08-1642.4.1 C++ STL 动态链表容器08-1643.3.1 C++ STL 双向队列容器08-1644.2.1 C++ STL 数组向量容器08-1645.1.1 C++ STL 字符串构造函数08-1646.7.5 C/C++ 实现链表队列08-1547.7.4 C/C++ 实现链表栈08-1548.7.3 C/C++ 实现顺序栈08-1549.7.2 C/C++ 实现动态链表08-1550.7.1 C/C++ 实现动态数组08-1551.9.0 Python 内置模块应用08-1452.8.0 Python 使用进程与线程08-1453.7.0 Python 面向对象编程08-1454.6.0 Python 使用函数装饰器08-1455.5.0 Python 定义并使用函数08-1356.4.0 Python 变量与作用域08-1357.3.0 Python 迭代器与生成器08-1258.2.0 Python 数据结构与类型08-1159.21.1 使用PEfile分析PE文件08-1060.1.0 Python 标准输入与输出08-0961.1.8 运用C编写ShellCode代码07-1362.5.2 基于ROP漏洞挖掘与利用07-1263.5.1 缓冲区溢出与攻防博弈07-1264.2.0 熟悉CheatEngine修改器07-1165.4.9 x64dbg 内存处理与差异对比07-1166.4.10 x64dbg 反汇编功能的封装07-1167.4.8 x64dbg 学会扫描应用堆栈07-1068.4.7 x64dbg 应用层的钩子扫描07-1069.4.6 x64dbg 内存扫描与查壳实现07-0970.4.5 x64dbg 探索钩子劫持技术07-0971.4.4 x64dbg 绕过反调试保护机制07-08
    72.4.3 x64dbg 搜索内存可利用指令07-07
    73.4.2 x64dbg 针对PE文件的扫描07-0774.4.1 探索LyScript漏洞挖掘插件07-0675.1.5 为x64dbg编写插件07-0676.1.1 熟悉x64dbg调试器07-0677.1.7 完善自定位ShellCode后门07-0578.1.6 编写双管道ShellCode后门07-0479.1.5 编写自定位ShellCode弹窗07-0380.1.4 编写简易ShellCode弹窗07-0281.1.3 Metasploit 生成SSL加密载荷07-0182.1.1 Metasploit 工具简介06-3083.2.1 PE结构:文件映射进内存09-04
    收起

    发现漏洞的第一步则是需要寻找到可利用的反汇编指令片段,在某些时候远程缓冲区溢出需要通过类似于jmp esp等特定的反汇编指令实现跳转功能,并以此来执行布置好的ShellCode恶意代码片段,LyScript插件则可以很好的完成对当前进程内存中特定函数的检索工作。

    一般而言远程缓冲区溢出攻击通常利用的是一些具有缓冲区溢出漏洞的函数或是特定的汇编指令片段,如:

    • strcpy:该函数将一个字符串复制到另一个字符串缓冲区中,但不会检查缓冲区的大小,因此很容易导致缓冲区溢出。
    • gets:该函数将用户输入的数据读入字符串缓冲区中,但不会检查缓冲区的大小,因此很容易导致缓冲区溢出。
    • sprintf:该函数将一个字符串格式化到字符串缓冲区中,但不会检查缓冲区的大小,因此很容易导致缓冲区溢出。

    在远程缓冲区溢出攻击中,攻击者也可以利用汇编指令jmp esp来实现对攻击代码的执行。该指令允许攻击者跳转到堆栈中的任意位置,并从那里执行恶意代码。

    4.3.1 搜索可利用汇编指令集

    在默认情况下,LyScript插件并不具备搜索连续指令的能力,虽然提供了get_disasm_code()系列的反汇编函数,但此类函数通常仅仅只能实现简单的反汇编功能,读者如果需要实现其他附加功能,含需要自行动手去实现,首先我们自行实现一个简单的汇编指令检索功能,用于寻找可利用的指令片段"pop esp","jmp esp","jmp eax","pop ecx"等指令集。

    这段代码实现的机制可总结为如下步骤;

    • 1.调用connect函数来连接到要调试的程序,并使用get_local_base和get_local_size函数获取程序的内存范围。
    • 2.定义一个名为search_asm的列表,该列表包含要搜索的汇编指令。
    • 3.使用一个while循环来遍历内存范围中的每一个地址,并调用get_disasm_one_code函数获取该地址处的反汇编代码。
    • 4.使用另一个for循环来遍历search_asm列表中的每一个指令,并检查当前反汇编代码是否与列表中的指令匹配。如果匹配,则输出该地址和反汇编代码。

    代码很容易被理解和实现,本质上仅仅只是提取所内存中所有的汇编指令集,并依次枚举对比是否符合列表中的条件,其最终实现代码如下所示;

    from LyScript32 import MyDebug
    
    if __name__ == "__main__":
        dbg = MyDebug()
        dbg.connect()
    
        local_base_start = dbg.get_local_base()
        local_base_end = local_base_start + dbg.get_local_size()
        print("开始地址: {} --> 结束地址: {}".format(hex(local_base_start),hex(local_base_end)))
    
        search_asm = ["pop esp","jmp esp","jmp eax","pop ecx"]
    
        while local_base_start <= local_base_end:
            disasm = dbg.get_disasm_one_code(local_base_start)
            # print("地址: 0x{:08x} --> 反汇编: {}".format(local_base_start,disasm))
    
            # 寻找指令
            for index in range(0, len(search_asm)):
                if disasm == search_asm[index]:
                    print("地址: {} --> 反汇编: {}".format(hex(local_base_start), disasm))
    
            # 递增计数器
            local_base_start = local_base_start + dbg.get_disasm_operand_size(local_base_start)
    
        dbg.close()
    

    如上代码被运行后,则会输出当前进程内所有可被利用的指令片段,其输出效果图如下图所示;

    4.3.2 搜索可利用机器码

    机器码的搜索与汇编指令集的搜索方式基本保持一致,但庆幸的是搜索指令集可使用scan_memory_all()这个官方函数,该函数可用于扫描当前EIP所处位置,也就是当前EIP所在模块的所有符合条件的机器码,需要注意的是,在搜索具有漏洞函数时,通常我们会搜索进程内的完整模块,则此时应该先得到该模块的入口地址,并通过set_register()设置到该模块所在内存,然后再次对该内存区域进行搜索,代码中opcode用于指定一段机器码序列,此处读者可指定搜索多种机器码,并将搜索结果放入到该列表内进行存储。

    这段代码的实现原理可总结为如下所示的步骤;

    • 定义一个名为opcode的列表,该列表包含要搜索的机器码。
    • 然后使用一个for循环来遍历每个模块,并调用get_all_module函数获取程序中的模块列表。对于每个模块,它将eip寄存器设置为该模块的入口点,然后调用scan_memory_all函数搜索该模块中是否存在要搜索的机器码。
    • 如果找到了指定的机器码,则输出模块名称、匹配个数以及机器码,并输出该机器码所在的地址。

    根据上述流程可总结为如下所示的代码片段;

    from LyScript32 import MyDebug
    import time
    
    if __name__ == "__main__":
        dbg = MyDebug()
        dbg.connect()
    
        # 需要搜索的指令集片段
        opcode = ['ff 25','ff 55 fc','8b fe']
    
        # 循环搜索指令集内存地址
        for index,entry in zip(range(0,len(opcode)), dbg.get_all_module()):
            eip = entry.get("entry")
            base_name = entry.get("name")
            if eip != 0:
                dbg.set_register("eip",eip)
                search_address = dbg.scan_memory_all(opcode[index])
    
                if search_address != False:
                    print("搜索模块: {} --> 匹配个数: {} --> 机器码: {}"
                .format(base_name,len(search_address),opcode[index]))
                    # 输出地址
                    for search_index in search_address:
                        print("[*] {}".format(hex(search_index)))
    
            time.sleep(0.3)
        dbg.close()
    

    以strcpy函数为例,读者只需要搜索特征['57 8b 7c 24 08 eb 6e','ff 55 fc','8b fe']即可定位到当前模块内所有调用该函数机器其他函数的内存地址。

    运行后即可输出当前模块内所有被调用机器码的详细地址,输出效果如下图所示;

    本文作者: 王瑞
    本文链接: https://www.lyshark.com/post/af00a46a.html
    版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

  • 相关阅读:
    VMware三种网络模式
    MEIS —— 前端部分基本配置
    如何给照片添加水印?请看下面3个简单教程
    学历证书查询 易语言代码
    美容院冬季拓客方法大全
    gson如何序列化子类
    Spring Boot集成阿里云视频点播服务的过程记录
    延迟加载!
    Java如何解决浮点数计算不精确问题
    阿里云服务器企业级和入门级实例规格有何区别?如何选择?
  • 原文地址:https://www.cnblogs.com/LyShark/p/17535906.html
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号