原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

admin 2024年1月11日12:41:39评论37 views字数 2248阅读7分29秒阅读模式
原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

免责声明

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任。

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

CVE-2019-10744

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

漏洞CVE-2019-10744指出,JS库lodash中lodash.mergeWith、lodash.merge、lodash.set等方法存在原型链污染的问题,我们以lodash.set为例,研究一下在实际情况下原型链污染是怎么发生的。

写一个函数测试的脚本:

var lodash = require('lodash');var result = lodash.set({}, "__proto__.evil", "evil!!!!");console.log({}.evil);

运行代码,可以看到原型链已经遭到污染,任何一个对象都有了evil属性:

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

我们跟踪set()函数,看看漏洞如何发生:

  1.  进入set函数,随后进入baseSet

function set(object, path, value) {      return object == null ? object : baseSet(object, path, value);}

2. 进入baseSet,关键在这一行assignValue(nested, key, newValue);,其中,nested就是我们输入的object,key就是我们输入的key路径中的每一条路径,newValue就是我们输入的value。在我们构造了payload:"__proto__.evil", "evil!!!!"后,path = castPath(path, object);会把我们的key变为[’__proto__’,’evil’]的Array,然后遍历这个Array,分别对__proto__和evil执行两次assignValue,当没有遍历到数组最后一个值,也就是evil时,会直接复制为object原本的值。

function baseSet(object, path, value, customizer) {  if (!isObject(object)) {    return object;  }  path = castPath(path, object);  var index = -1,      length = path.length,      lastIndex = length - 1,      nested = object;  while (nested != null && ++index < length) {    var key = toKey(path[index]),        newValue = value;    if (index != lastIndex) {      var objValue = nested[key];      newValue = customizer ? customizer(objValue, key, nested) : undefined;      if (newValue === undefined) {        newValue = isObject(objValue)          ? objValue          : (isIndex(path[index + 1]) ? [] : {});      }    }    assignValue(nested, key, newValue);    nested = nested[key];  }  return object;}

3. 进入assignValue,随后进入baseAssignValue

function assignValue(object, key, value) {  var objValue = object[key];  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||      (value === undefined && !(key in object))) {    baseAssignValue(object, key, value);  }}

4. 进入最关键的函数baseAssignValue,注意看代码object[key] = value;,是不是就是文章开头给出的obj[a][b] = value;样式?只是在baseSet中,把obj[a][b] = value分解了: obj[a] = obj[a],obj[a][b] = value两次执行

function baseAssignValue(object, key, value) {  if (key == '__proto__' && defineProperty) {    defineProperty(object, key, {      'configurable': true,      'enumerable': true,      'value': value,      'writable': true    });  } else {    object[key] = value;  }}

5. 因此,在我们构造了payload:"__proto__.evil", "evil!!!!"后,会执行两次baseAssignValue,第一次是baseAssignValue(object, __proto__, object.__proto__),第二次是baseAssignValue(object, __proto__.evil, evil!!!)

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

总结

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

本文介绍了JavaScript原型链污染中有名的漏洞CVE-2019-10744,让我们对JavaScript原型链污染有了直观的认识。下一章我们将介绍如何自己写代码批量刷原型链污染漏洞,自动化刷洞的方法已经放在Github,点击原文链接可以直达。

原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

原文始发于微信公众号(赛博安全狗):原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月11日12:41:39
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   原型链污染:从原理分析到批量刷洞(三)—— CVE-2019-10744https://cn-sec.com/archives/2214156.html

发表评论

匿名网友 填写信息