4.3 x64dbg 搜索内存可利用指令

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
公网NAT网关,每月750个小时 15CU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 发现漏洞的第一步则是需要寻找到可利用的反汇编指令片段,在某些时候远程缓冲区溢出需要通过类似于`jmp esp`等特定的反汇编指令实现跳转功能,并以此来执行布置好的`ShellCode`恶意代码片段,`LyScript`插件则可以很好的完成对当前进程内存中特定函数的检索工作。在远程缓冲区溢出攻击中,攻击者也可以利用汇编指令`jmp esp`来实现对攻击代码的执行。该指令允许攻击者跳转到堆栈中的任意位置,并从那里执行恶意代码。

发现漏洞的第一步则是需要寻找到可利用的反汇编指令片段,在某些时候远程缓冲区溢出需要通过类似于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_baseget_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

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
高可用应用架构
欢迎来到“高可用应用架构”课程,本课程是“弹性计算Clouder系列认证“中的阶段四课程。本课程重点向您阐述了云服务器ECS的高可用部署方案,包含了弹性公网IP和负载均衡的概念及操作,通过本课程的学习您将了解在平时工作中,如何利用负载均衡和多台云服务器组建高可用应用架构,并通过弹性公网IP的方式对外提供稳定的互联网接入,使得您的网站更加稳定的同时可以接受更多人访问,掌握在阿里云上构建企业级大流量网站场景的方法。 学习完本课程后,您将能够: 理解高可用架构的含义并掌握基本实现方法 理解弹性公网IP的概念、功能以及应用场景 理解负载均衡的概念、功能以及应用场景 掌握网站高并发时如何处理的基本思路 完成多台Web服务器的负载均衡,从而实现高可用、高并发流量架构
相关文章
|
6月前
|
Linux
|
6月前
|
存储 Java
百度搜索:蓝易云【Java语言之float、double内存存储方式】
由于使用IEEE 754标准进行存储,float和double类型可以表示非常大或非常小的浮点数,并且具有一定的精度。然而,由于浮点数的特性,它们在进行精确计算时可能会存在舍入误差。在编写Java程序时,需要注意使
96 0
|
存储 缓存
百度搜索:蓝易云 ,CPU、内存、缓存的关系详细解释!
总结起来,CPU、内存和缓存之间的关系可以概括为:CPU是计算机的处理器,内存是用于存储数据的设备,缓存则是位于CPU和内存之间的高速存储器,用于提高数据的读取速度。它们共同协作,以提供高效的计算机性能。
104 0
|
1月前
|
程序员 Windows
程序员必备文件搜索工具 Everything 带安装包!!! 比windows自带的文件搜索快几百倍!!! 超级好用的文件搜索工具,仅几兆,不占内存,打开即用
文章推荐了程序员必备的文件搜索工具Everything,并提供了安装包下载链接,强调其比Windows自带搜索快且占用内存少。
37 0
|
5月前
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
|
6月前
|
Rust 监控 安全
【专栏】`ripgrep`(rg)是Linux下快速、内存高效的文本搜索工具,用Rust编写,支持PCRE2正则表达式
【4月更文挑战第28天】`ripgrep`(rg)是Linux下快速、内存高效的文本搜索工具,用Rust编写,支持PCRE2正则表达式。相比`grep`,它在处理大文件和复杂模式时更具优势。安装`rg`可通过软件包管理器,如在Debian系系统中使用`sudo apt install ripgrep`。基本用法包括简单搜索、递归搜索、忽略大小写、显示行号等。高级功能包括固定字符串搜索、多文件匹配、并行搜索、排除选项和区域搜索。适用于日志分析、代码审查等场景,是提升工作效率的利器。
515 4
|
6月前
|
存储 程序员 数据处理
【汇编】mov和add指令、确定物理地址的方法、内存分段表示法
【汇编】mov和add指令、确定物理地址的方法、内存分段表示法
672 1
【汇编】mov和add指令、确定物理地址的方法、内存分段表示法
|
6月前
|
存储
【汇编】数据在哪里?有多长、div指令实现除法、dup设置内存空间
【汇编】数据在哪里?有多长、div指令实现除法、dup设置内存空间
133 1
|
6月前
|
缓存 Linux
百度搜索:蓝易云【Linux系统中查看内存信息的方法有哪些?】
这些是在Linux系统中查看内存信息的常见方法。根据您的需求和具体环境,您可以选择适合您的方法来查看内存信息。
106 0
|
存储 安全 API
4.9 x64dbg 内存处理与差异对比
LyScript 插件中针对内存读写函数的封装功能并不多,只提供了最基本的`内存读取`和`内存写入`系列函数的封装,本章将继续对API接口进行封装,实现一些在软件逆向分析中非常实用的功能,例如ShellCode代码写出与置入,内存交换,内存区域对比,磁盘与内存镜像比较,内存特征码检索等功能,学会使用这些功能对于后续漏洞分析以及病毒分析都可以起到事半功倍的效果,读者应重点关注这些函数的使用方式。
73 2
4.9 x64dbg 内存处理与差异对比