Metasploit 生成的 Shellcode 的导入函数解析以及执行流程分析(1)
dezehang 2024-11-22 13:04 1 浏览
2021 年 4 月,研究人员深入分析了 Cobalt Strike渗透测试技术,以及它的一些签名规避技术是如何在检测技术下失效的。在本文中,我们将深入讨论Metasploit,这是一个可以与Cobalt Strike互操作的常用框架。
在本文中,我们将讨论以下主题:
shellcode的导入解析——Metasploit shellcode如何定位来自其他DLL的函数,以及我们如何预先计算这些值来解析来自其他有效载荷变体的任何导入;
逆向shell的执行流程——该过程非常简单;
破坏 Metasploit 导入解析——一种非侵入性欺骗技术(不涉及钩子),让 Metasploit 以高可信度通知防病毒软件 (AV)。
对于这个分析,研究人员在 v6.0.30-dev 版本下使用 Metasploit 生成了研究人员自己的 shellcode。使用以下命令生成的恶意样本的结果为 3792f355d1266459ed7c5615dac62c3a5aa63cf9e2c3c0f4ba036e6728763903 的 SHA256 哈希值,并且可以在 VirusTotal 上找到,供愿意自己尝试的读者使用。
msfvenom -p windows/shell_reverse_tcp -a x86 > shellcode.vir
在整个分析过程中,我们重新命名了函数、变量和偏移量,以反映它们的作用并提高清晰度。
初步分析
在本节中,研究人员将概述确定下一步分析(导入解析和执行流分析)所遵循的初始逻辑。
虽然典型的可执行文件包含一个或多个入口点(导出的函数、TLS 回调等),但 shellcode 可以被视为最原始的代码格式,其中初始执行从第一个字节开始。
从初始字节分析生成的 shellcode 概述了两个操作:
从分析的角度来看,①处的第一条指令可以忽略。cld操作清除方向标志,确保字符串数据是向前读取而不是向后读取(例如:cmd与dmc的区别)。② 处的第二个调用操作将执行转移到研究人员命名为 Main 的函数中,该函数将包含 shellcode 的主要逻辑。
调用 Main 函数的反汇编 shellcode
在Main函数中,我们观察到额外的调用,比如下图中突出显示的四个调用(③、④、⑤和⑥)。这些调用针对一个尚未识别的函数,其地址存储在ebp寄存器中。要理解这个函数的位置,我们需要退后一步并了解调用指令的操作方式。
Main 函数的反汇编
调用指令通过执行两个操作将执行转移到目标目的地:
它将返回地址(位于调用指令之后的指令的内存地址)压入堆栈。该地址稍后可以被 ret 指令用于将执行从被调用函数(被调用者)返回到调用函数(调用者);
它将执行转移到目标目的地(被调用者),就像 jmp 指令一样;
因此,来自Main函数③的第一个pop指令将调用者的返回地址存储到ebp寄存器中。这个返回地址随后被作为函数调用,在偏移量0x99、0xA9和0xB8(④、⑤和⑥)处调用。这种模式,在每次调用之前出现类似的推送,往往表明存储在 ebp 中的返回地址是动态导入解析函数。
“普通”可执行文件(例如:Windows上的可移植可执行文件)包含必要的信息,因此,一旦被操作系统(OS)加载程序加载,代码就可以调用导入的例程,比如那些来自Windows API的例程(例如:LoadLibraryA)。为了实现此默认行为,可执行文件应具有操作系统可以解释的特定结构。由于shellcode是代码的一个基本版本(它没有预期的结构),操作系统加载程序无法帮助它解析这些导入的函数,更严重的是,操作系统加载程序将无法“执行”shellcode文件。为了解析这个问题,shellcode 通常会执行“动态导入解析”。
执行“动态导入解析”的最常见技术之一是对每个可用的导出函数进行哈希,并将其与所需导入的哈希进行比较。由于shellcode开发者不能总是预测一个特定的DLL(例如:ws3_32.dll for Windows Sockets)及其导出是否已经加载,观察shellcode加载DLL并不罕见,首先调用LoadLibraryA函数(或它的一个替代方法)。在调用其他dll的导出之前依赖于LoadLibraryA(或替代)是一种稳定的方法,因为这些库加载函数是kernel32.dll的一部分,是少数几个可以加载到每个进程中的 DLL 之一。
为了证实研究人员的上述理论,研究人员可以搜索所有调用指令,如下图所示(例如:在搜索菜单下使用 IDA 的文本等选项)。除了第一次调用 Main 函数外,所有实例都引用 ebp 寄存器。这一观察结果与研究人员将在下一节中观察到的众所周知的常量一起,支持了研究人员的理论,即存储在 ebp 中的地址持有一个指向执行动态导入解析的函数的指针。
shellcode中的所有调用指令
对ebp寄存器的大量调用表明它确实持有一个指向导入解析函数的指针,我们现在知道该函数位于对Main的第一次调用之后。
导入解析方案分析
到目前为止,我们注意到在最初调用Main之后的指令起到了至关重要的作用,因为我们希望它成为导入解析例程。在分析shellcode的逻辑之前,让我们先分析这个解析例程,因为它将简化对其余调用的理解。
从导入哈希到函数
直接位于Main初始调用之后的代码是导入解析开始的地方,要解析这些导入,例程首先定位加载到内存中的模块列表,因为这些模块包含它们可用的导出函数。
为了找到这些模块,一种常用的shellcode技术便是与Process Environment Block(简称PEB)进行交互。
在计算过程中,进程环境块(缩写为 PEB)是 Windows NT 操作系统家族中的一种数据结构。它是操作系统内部使用的不透明数据结构,其大部分字段不供操作系统以外的任何其他使用。PEB包含应用于整个进程的数据结构,包括全局上下文、启动参数、程序映像加载程序的数据结构、程序映像基地址,以及用于为整个进程的数据结构提供互斥的同步对象。
如下图所示,为了访问PEB, shellcode访问线程环境块(TEB),它可以通过寄存器(⑦)立即访问。TEB结构本身包含指向PEB(⑦)的指针。在PEB中, shellcode可以定位PEB_LDR_DATA结构(⑧),它反过来包含对多个双链接模块列表的引用。正如在(⑨)中所观察到的,Metasploit shellcode利用这些双链列表(InMemoryOrderModuleList)中的一个来随后遍历包含已加载模块信息的LDR_DATA_TABLE_ENTRY结构。
一旦识别出第一个模块,shellcode 在⑩ 处检索模块的名称(BaseDllName.Buffer)和在? 处的缓冲区的最大长度(BaseDllName.MaximumLength),这是必需的,因为缓冲区不能保证以 NULL 结尾。
初始模块检索的反汇编
值得强调的一点是,与通常的指针(TEB.ProcessEnvironmentBlock、PEB.Ldr 等)相反,双链表指向下一项的列表条目。这意味着列表中的指针将指向非零偏移量,而不是指向结构的起始位置。因此,虽然在下图中 LDR_DATA_TABLE_ENTRY 在偏移量为 0x2C 处具有 BaseDllName 属性,但从列表条目的角度来看,偏移量为 0x24 (0x2C-0x08)。这可以在上图中观察到,其中必须减去 8 的偏移量才能访问 ⑩ 和 ? 处的两个 BaseDllName 属性。
从TEB到BaseDllName
恢复了DLL名称的缓冲区和最大长度后,shellcode继续生成一个哈希。为此,shellcode对最大名称长度内的每个ASCII字符执行一组如下操作:
如果字符是小写的,它会被修改为大写。该操作是根据字符的ASCII表示来执行的,这意味着如果值是0x61或更高(a或更高),就会减去0x20以进入大写范围;
生成的哈希(最初为0)向右旋转13位(ROR) (0x0D);
大写字符被添加到现有哈希中;
描述KERNEL32.DLL的第一个字符(K)的哈希循环的模式
在固定的注册表大小(在edi的情况下是32位)上重复旋转和添加,字符最终将开始重叠。这些重复和重叠的组合使操作不可逆,因此产生给定名称的32位哈希/校验和。
一个有趣的发现是,虽然LDR_DATA_TABLE_ENTRY中的BaseDllName是unicode编码的(每个字符2个字节),但代码通过使用 lodsb(见?)将其视为 ASCII 编码(每个字符 1 个字节)。
模块名称哈希例程的反汇编
哈希生成算法可以在Python中实现,如下面的代码片段所示。虽然我们前面提到过,根据 Microsoft 文档,BaseDllName 的缓冲区不需要以 NULL 终止,但大量测试表明,NULL 终止总是如此,并且通常可以假设。这个假设是使 MaximumLength 属性成为有效边界的原因,类似于 Length 属性。因此,以下代码片段期望传递给 get_hash 的数据是一个由以null结尾的Unicode字符串生成的Python 字节对象。
上述函数可用于计算 KERNEL32.DLL 的哈希值,如下所示。
生成 DLL 名称的哈希后,shellcode 继续识别所有导出的函数。为此,shellcode 首先检索 LDR_DATA_TABLE_ENTRY 的 DllBase 属性(?),该属性指向 DLL 的内存地址。此时,IMAGE_EXPORT_DIRECTORY 结构通过遍历可移植可执行文件的结构(? 和 ?)并将相对偏移量添加到 DLL 的内存中基地址来识别。最后一个结构包含导出函数名称的数量(?)以及指向这些名称的指针表(?)。
导出检索的反汇编
上述操作的架构如下,其中虚线表示从相对偏移量计算出的地址,该偏移量增加了 DLL 的内存基地址。
从LDR_DATA_TABLE_ENTRY到IMAGE_EXPORT_DIRECTORY
一旦确定了导出名称的数量及其指针,shellcode 就会按降序枚举该表。具体就是,名称的数量用作?处的递减计数器。对于每个导出函数的名称并且没有匹配,shellcode 执行一个哈希例程(?上的hash_export_name),与研究人员之前观察到的类似,唯一的区别是保留了字符大小写(hash_export_character)。
最后的哈希是通过将最近计算的函数哈希(ExportHash)添加到?处之前获得的模块哈希(DllHash)中获得的。这是在寻求哈希和?之间的区别,除非他们匹配,否则操作重新开始下一个函数。
导出名称哈希的反汇编
如果导出的函数都不匹配,例程将在InMemoryOrderLinks双链表中检索下一个模块,并再次执行上述操作,直到找到匹配项。
反汇编到下一个模块的循环过程
上面的遍历双链表的架构如下图所示:
遍历InMemoryOrderModuleList
如果找到匹配,shellcode将继续调用导出的函数。从前面确认IMAGE_EXPORT_DIRECTORY检索其地址,代码将首先需要映射函数的名字的顺序(?),顺序导出数量。一旦顺序从AddressOfNameOrdinals表中恢复过来,地址可以通过使用序数AddressOfFunctions表中的索引(?)。
导入“调用”的反汇编
最后,一旦导出的地址被恢复,shellcode通过确保返回地址首先在堆栈上(删除它正在在?搜索的哈希)来模拟调用行为,其次是所有参数根据默认的Win32 API __stdcall调用协定(?)。然后代码在 ? 处执行 jmp 操作,将执行转移到动态解析的导入,在返回时,将从初始调用 ebp 操作发生的位置恢复。
总的来说,可以将动态导入解析架构为嵌套循环。主循环按照内存中的顺序遍历模块(下图中的蓝色),而对于每个模块,第二个循环遍历导出函数,在所需的导入和可用的导出之间寻找匹配的哈希(下图中的红色)。
导入解析流
【网络安全学习资料获取方式】
相关推荐
- WIN10系统如何安装UG10.0
-
随着科技的不断进步与更新,现在有很多公司己经安装上了WIN10的系统以及使用UG10.0了,但很多人反映WIN10系统安装UG10.0不好装,以下详细介绍一下1如果WIN10系统没有自带有JAVA需...
- 自学UG编程的心得分享
-
为什么有的人3个月学会基本的UG建模画图编程,有的断断续续3——5年才学会,还有的人干了7年的加工中心还不会电脑画图编程。这是什么原因?1.顾虑太多,什么都想得到,什么都想一起抓,总是上班加班没时间,...
- UG/NX 绘制一个捞笊(zhào)模型,或者也可以叫它漏勺?
-
今天我们来看看这个模型,起因是群里有小伙伴说要做一个捞笊的模型,看见这名字直接给我整懵了,然后他发了张家里漏勺的图片才知道原来这玩意还有个这种名字。这东西相信每个小伙伴家里都有吧,它的建模方法也比较...
- 再也不用为学UG编程发愁了!380集最新UG资料免费送
-
上期发的UG教程很多粉丝都领到了,收获越来越多的好评!有你们一直陪伴真的很高兴,谢谢各位粉丝!为了给大家提供更优质的资源,这两个月都在整理你们最关心的UG资源,都是多位编程工厂老师傅的工厂实战精华,真...
- 优胜原创UG_3-4-5轴后处理下载
-
反复上机调试,安全稳定可靠,请放心使用2020.11.21,修复YSUG4-5轴后处理锁轴输出...
- 青华模具学院-UG10.0安装文件说明
-
青华模具学院分享:今天我们来跟大家一起学习NX10.0版本的安装方法,网上有很多这个版本的安装视频以及方法图文,但到最终安装软件时仍有很多新手对安装仍然感到头痛,基于这样的情况,我们特别就NX10.0...
- UGnx10安装说明
-
温馨提示,安装前,请退出杀毒软件,关闭防火墙,因为这些软件可能阻断NX主程序和许可程序间的通信,导致安装后,软件无法启动。1、解压下载后的压缩包,右键,选择‘’解压到UGNX10_64位正式版(csl...
- 正版UG软件,正版UG代理,正版软件和盗版软件的区别
-
大家都知道,UG软件是制造业必不可少的一款三维软件,广泛应用于:CAE(有限元分析),CAD(产品设计/模具设计),CAM(计算机辅助制造编程),那么有人不禁要问了,正版软件和盗版软件在使用上有明显区...
- 非常全面的UG加工模块中英对照(图标注释)
-
大家好,我是粥粥老师,听说很多同学都在学习UG但是没有学习资料和安装包,今天粥粥老师就全部打包好免费发放给你们,那么怎么获取全套资料图档安装包呢领取途径①关注②评论、点赞、转发③私信“UG或者...
- 腾讯自研Git客户端 UGit|Git 图形界面客户端
-
支持平台:#Windows#macOS腾讯推出的一款Git图形界面客户端,简化了Git的使用流程,特别适合处理大型项目和文件。支持直接提交和推送操作,避免在大规模项目中由于远程频繁变更而导致...
- 经典收藏:UG重用库的一些不为人知小技巧
-
免费领取UG产品编程、UG多轴UG模具编程、安装包安装教程图档资料关注私信我“领取资料”,即可免费领取完整版,感谢支持,爱你们哟,么么主题:UG后处理+仿真+外挂UG重用库的正确使用方法:首先有...
- UG编程常用指令G、M代码,快收藏好
-
今天给大家分享数控编程常用的指令代码,希望对正在学习路上的你带来一丝丝帮助。最好的方法就是转发到自己空间,方便以后学习。对了,如果你还需要其他UG教程学习资料,CNC加工中心的一些参数,以及UG画图,...
- UG NX7.0中文版从入门到精通
-
Unigraphics(简称UG)是一套功能强大的CAD/CAE/CAM应用软件,UGNX7是其最新版本。《UGNX7从入门到精通(中文版)》以UGNX7为平台,从工程应用的角度出发,通过基...
- 经典UG建模基础练习图纸
-
UG是目前工作中比较优秀拥有大量用户的一款机械模具产品行业三维设计软件,cam加工丶软件支持全中文汉化;能够带给用户更为非凡的设计与加工新体验。很多朋友私信小编问有没有UG建模练习图纸,今天给大家分享...
- UG NC软件基础操作,如何设置UG草图精度
-
默认情况下我们绘制草图一般只保留一位小数,即使你输入多位小数软件也会自动四舍五入,这个你做一些国标的图还好,国标以毫米为单位,一般保留小数点后一位就够了,但如果你做的图是英制单位,那么保留一位小数肯定...
- 一周热门
- 最近发表
- 标签列表
-
- 微信开发者工具 (41)
- amd驱动 (55)
- 下载qqhd (28)
- cad2014 (75)
- cad2014注册机 (30)
- 魔兽争霸官方对战平台 (43)
- cad2007 (31)
- directx下载 (29)
- 桌面备忘录 (51)
- msvcr100.dll下载 (24)
- office2010下载 (42)
- ipscan (20)
- 思源黑体下载 (38)
- kernel32.dll下载 (63)
- office2010下载免费完整版 (28)
- 微信开发者工具下载 (54)
- powerdesigner下载 (46)
- python3下载 (23)
- photoshop官方免费版 (55)
- ch340串口驱动 (52)
- 爱奇艺万能播放器官方下载 (30)
- ps软件官方下载中文版 (51)
- ultraedit下载 (32)
- 360一键root (32)
- ug下载 (64)