freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

web安全战技102之JavaScript静态分析
sec875 2021-09-01 21:42:14 129203

讲故事

某人邮件收到,预订酒店50%折扣活动。

预订过程中出现了问题,信用卡已过期,某人试图联系银行。 银行回应的是需要15个工作日。

image

某人开打浏览器中的开发人员工具在网站上进行长时间的探索。发现了以下内容:

某人查看了几个变量,有的值是日期,有的值是时间戳。

image

修改后,某人的卡被接受了。最后收到满意的邮件。感谢JavaScript。

image

image

实战:收集JavaScript文件

有很多方法收集js文件,这里已burpsuite为例。

这里操作没必要重造轮子,很简单,就用材料里的图了。

专业版

image

image

免费版

image

image

复制这些URL保存到文本文件中:targetJS.txt。然后批量下载。

for i in $(cat targetJS.txt);do wget $i;done

js文件提取工具

从列表URL中提取js文件的工具

https://github.com/Mesh3l911/JS_Scrapper

其他工具

在js文件里查找端点

https://github.com/GerbenJavado/LinkFinder

存档:索引参数是 url

https://web.archive.org/cdx/search/cdx?url=google.com&matchType=domain&fl=original&collapse=urlkey&output=text&filter=statuscode:200

image

注意:测试时,将响应状态码从403改成200,有时可以bypass 403。

当然,这里仅是部分。还有更多的方法与工具

实战:寻找DOM XSS

从js文件里索引innerHTML,将js文件集中到test文件夹里,一起找。没什么有趣的内容出现。

grep "innerHTML" -r test

image

索引 document.location

image

针对这个场景的练习例子为:https://github.com/Ph33rr/attack/blob/main/Javascript/mctaps.js

我们在这个练习js文件中发现了有趣的内容。

image

找到了这个函数。调试和跟踪它,这是整篇文章的灵魂所在。

方法很简单:试图追踪一个特定的函数或变量时,打印输出它的值

假设我们进入了一个带有 javascript 文件的站点,该文件在浏览器中打印了一个帐户名称。我们如何跟踪该变量?

第一步是查看页面源码,打印输出前,js源码有没有执行。没执行哪里来的调试。

练习场景:https://github.com/Ph33rr/attack/blob/main/Javascript/test.html

查看源码:

image

整个练习过程中就只有一个变量,因此打印它。当js文件很多,代码量很大时,也只有打印它们。。

image

在 JavaScript打印功能是 console.log()

让我们重新修改源码,将变量的变化情况观察得更仔细。

image

这样,我们就可以更好的发现与跟踪这个变量在不同的阶段中,它是否存在漏洞。

image

再回到练习的js文件中,我们修改一下源码,来观察每一次变化情况。将函数里面的代码提出来调试。

image

调试结果如下: 两个变量第一次打印是 无定义 和 路径;第二次打印是 -1 和 路径;-1 使得if语句没有被执行。

image

让我们检查一下为啥是 -1 。没查到 # 所以返回 -1

image

我们手动在URL加上#去调试。然后就发现这里的函数与变量可以在URL被我们控制与利用。

image

最后 ,我们返回跟踪整个函数以及脚本中需要利用的位置。

最后,不要忘记了正则表达式在手动搜索漏洞中的重要性。

这里用一个例子来举一反三。其他函数的索引可以参考一下备忘单:

https://raw.githubusercontent.com/Ph33rr/attack/main/Javascript/Javascript2.png

可以通过,IDE phpstrom等 调试js代码。利用IDE插件里的代码质量与静态漏洞扫描等,检查js代码。这种方法更快更容易。

库与框架

关于库与框架的介绍

https://3alam.pro/mnsor-alaatyby/articles/javascript-libraries-and-frameworks

收集有关使用的库和框架的信息

使用网站来收集是最简单的方式:

https://www.wappalyzer.com/

https://www.similartech.com/

还有kali的whatweb,建议多用。

image

还有查看源代码

image

公共库检测版本poc

https://www.exploit-db.com/

https://snyk.io/vuln?type=any

https://snyk.io/test/npm/jquery/1.11.2

查看项目中关于bug的讨论,这里面的内容都在告诉您怎么定位,排查。。全都有用。

https://github.com/jquery

image

image

image

代码质量分析与POC

https://rules.sonarsource.com/javascript/RSPEC-5696?search=xss

当我们一时半会儿找不到什么实例与场景时,可以来这里看看。

image

原型污染

创建最简单的对象。我们可以看到多个属性返回一些东西

var obj = {};

这些东西的完整列表可以在这里查看

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

image

image

要理解这一部分,我们需要查看 JavaScript 语言中的类是如何存在的。

JavaScript 中类的概念始于函数。 函数本身充当类的构造函数。

function MyClass() {   # 函数
}
var inst = new MyClass();   #类的构造

MyClass所有实例上可用的函数都在原型上声明。原型在运行时可以被修改。

MyClass.prototype.myFunction = function () { 
return 42; 
};
var inst = new MyClass(); 
var theAnswer = inst.myFunction();

image

属性访问

在 JavaScript 中,属性和实例函数之间没有区别。访问方式都一样。

两种访问方式:obj.a 和 obj["a"]

var obj = { “a” : 1, “b” : function() { return 41; } }; 

var name1 = “a”; 
obj.a // 1 
obj[“a”] // 1 
obj[name1] // 1 

var name2 = “b”; 
obj.b() // 41 
obj.b // function. 
obj[“b”] // function 
obj[name2] // function

image

魔术属性

对象原型上存在大量属性,这里探索两个。constructor构造函数 和__proto__.

构造函数是一个魔法属性,它返回创建对象的函数。在每个构造函数上都有一个属性“prototype”,它指向类的原型。

image

function MyClass() { 
}
MyClass.prototype.myFunc = function () { 
return 7; 
}

var inst = new MyClass(); 
inst.constructor // returns the function MyClass 
inst.constructor.prototype // returns the prototype of MyClass 
inst.constructor.prototype.myFunc() // returns 7

__proto__是一个魔法属性,它返回对象的类的“原型”。

这个属性在 JavaScript 语言中不是标准的,但它在 NodeJS 环境中完全支持。

这个属性是作为一个 getter/setter 属性实现的,它在读/写时调用 getPrototypeOf/setPrototypeOf。

为属性__proto__分配一个新值不会影响原型上定义的继承值。改变这种情况的唯一方法是使用 Object.defineProperty

image

image

image

function MyClass() { 
}
MyClass.prototype.myFunc = function () { 
return 7; 
}

var inst = new MyClass();
inst.__proto__ // returns the prototype of MyClass 
inst.__proto__.myFunc() // returns 7
inst.__proto__ = { “a” : “123” }; // changing the prototype at runtime.
inst.hasOwnProperty(“__proto__”) // false. We haven’t redefined the property. It’s still the original getter/setter magic property

识别易受攻击的库

攻击者至少可以控制以下形式的任何表达式的参数和value。

obj[a][b] = value obj[a][b][c] = value

攻击者将a设置为__proto__。其实就是属性的访问。__proto__.myFunc()这样放入同一个地方也行。

payload可以放入键或值中:

{“__proto__”:{“cookie”:”sess=fixedsessionid; garbage=”}}

image

拒绝服务POC

wget --header="Content-Type: application/javascript+json" --post-data='{"__proto__":{"toString":"123","valueOf":"It works !"}}' http://localhost:3000/ -O- -q

运行漏洞利用脚本时,“toString”和“valueOf”函数被破坏,随后的每个请求都将返回 500 错误。

for循环污染

for循环调用key

{“__proto__”:{“my malicious command”:”echo yay > /tmp/evil”}}

属性注入

NodeJS http模块支持多个同名的头部,污染了例如键cookie,那么request.headers.cookie的值将始终以我们污染的值开头。形成了会话固定攻击。

{“__proto__”:{“cookie”:”sess=fixedsessionid; garbage=”}}

危害

如上所述:从对象的具体使用情况来看,受到从拒绝服务到RCE等不同程度的影响。

缓解

NPM 上的多个库(例如:avj5)为 JSON 数据提供模式验证。在 avj 中,将“additionalProperties”设置为“false”来拒绝不需要的属性。

使用Map:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

使用Object.create(null) 创建没有任何原型的对象

其他参考资料

https://github.com/BlackFan/client-side-prototype-pollution

结尾

感谢师傅们很有耐心的看到了这里。

我们还会再见面的。

共勉。

# xss # web安全 # javascript
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 sec875 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
sec875 LV.5
这家伙太懒了,还未填写个人描述!
  • 28 文章数
  • 52 关注者
海外赏猎之举一反三
2024-12-30
SMB 攻击威胁模拟与防御
2022-10-26
恶意软件分析102之零门栏“上头”分析
2022-08-29
文章目录