免责声明
本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任。
原型链污染原理
obj[a][b] = value;
obj[a][b][c] = value;
-
递归合并对象的属性和方法 -
克隆对象 -
路径定义输入可控
递归合并对象的属性和方法
典型的源码如下:
function merge(target, source) {
for (let key in source) {
if (key in source && key in target) {
merge(target[key], source[key])
} else {
target[key] = source[key]
}
}
}
我如传入形如:'{"__proto__":{"test":123}}'的输入,那么就会得到target[”__proto__”][”test”] = 123的执行:
克隆对象
典型的源码如下:
function clone(obj) {
return merge({}, obj);
}
本质上还是利用了merge的功能,只不过此处的target是一个空对象,用于克隆source对象。
路径定义输入可控
典型源码如下:
function theFunction(obj, path, value) {
let parts = path.split('.');
let last = parts.pop();
let current = obj;
for(let part of parts) {
if(!current[part]) current[part] = {};
current = current[part];
}
current[last] = value;
}
我们通过设计path为__proto__.myValue和value实现对obj的污染,典型的污染输入:
let attackerControlledValue = '__proto__.myValue';
let obj = {};
theFunction(obj, attackerControlledValue, 'This is a controlled value');
利用方法
常见的三种利用方法:
-
Denial-of-service攻击
-
属性注入
-
代码执行
Denial-of-service攻击
1. var _ = require('lodash');
2. var express = require('express');
3. var app = express();
4. var bodyParser = require('body-parser');
5.
6. app.use(bodyParser.json({ type: 'application/*+json' }))
7. app.get('/', function (req, res) {
8. res.send("Use the POST method !");
9. });
10.
11. app.post('/', function (req, res) {
12. _.merge({}, req.body);
13. res.send(req.body);
14. });
15.
16. app.listen(3000, function () {
17. console.log('Example app listening on port 3000!')
18. });
属性注入
对于特定的程序,我们可以污染程序中一些有价值的属性来控制程序的运行。以Express程序为例,Express程序存在属性cookie,也就是我们熟知的Http Cookie。我们通过污染Express的cookie属性,就可以让所有的访问都使用我们污染的cookie。
代码执行
假设我们上述的Express程序中存在如下代码,通过for循环获取所有的属性,如果__proro__中也包含属性,会一同获取。
1.var execSync = require('child_process').execSync;
2.
3.function runJobs() {
4. var commands = {
5. "script-1" : "/bin/bash /opt/my-script-1.sh",
6. "script-2" : "/bin/bash /opt/my-script-2.sh"
7. };
8.
9. for (var scriptname in commands) {
10. console.log("Executing " + scriptname);
11. execSync(commands[scriptname]);
12. }
13.}
那么,我们只需要提交这样的payload:'{"__proto__":{"payload":"whoami > output"}}',就可实现代码执行。
总结
本章介绍了JavaScript原型链攻击的原理和利用方法,并且每个方法都给出了样例。下一章我们将介绍漏洞CVE-2019-10744的原理,以及自动化刷JavaScript原型链漏洞的方法。自动化刷洞的方法已经放在Github,点击原文链接可以直达。
原文始发于微信公众号(赛博安全狗):原型链污染:从原理分析到批量刷洞(二) —— 污染原理和利用方式
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论