0x01前言

XNUCA的资格赛,难度很大,全场没多少解,总共四个Web只出了两个的解,我们队做出了两题(cgtql),在这里复盘下总结下。

0x02正文

一.Hardjs

审计源码,server.js主要负责处理后台逻辑,发现调用了lodash,并且版本较低,可能有原型链污染漏洞,在182行发现调用lodash.defaultDeep函数,这个函数类似merge,从而会造成js原型链污染漏洞,这里不再赘述原理,具体文章可以看深入理解 JavaScript Prototype 污染攻击,js的继承具体可以看这篇文章理解prototype、proto和constructor等关系

然后我们看下逻辑,连续post /add五次后,在get访问/get就可以触发defaultDeep函数,从而触发原型链污染,但是这里我们卡主一会,因为没找到类似template渲染函数的返回,然后因为整个项目是由ejs这个进行模板渲染的,所以就是要审计ejs,逐步跟进,寻找未定义并且将会拼接如返回值的变量,将他进行污染。

开始我们的跟进,我们发现整个模板是由res.render函数渲染,跟进到response.js,发现调用了app.render

跟进到application.js发现app.render调用了tryRender函数,之后tryRender又调用了view.render函数,继续跟进

到了view.js发现调用了engine引擎,也就是ejs引擎

ejs.js中renderFile函数调用了tryHandleCache函数

接着调用了handleCache函数

观察handleCache的返回值是如何产生的,func当不存在时由compile函数产生,继续跟进

compile由Template这个类产生,跟进这个Template看comoile这个成员方法

这里的outputFunctionName这个参数未定义,并且被拼接入一路回传给prepended,this.source,src一路回传,所以这里可以进行污染,payload如下:

改下ip和端口号,post /add6下,/get触发原型链污染,/触发redener函数,拿到shell,根据FLAG在环境变量中,cat /proc/self/environ 拿到flag

这里使用的是constructor->prototype,没有用__proto__构造成功,我实验猜测了下,应该是在json进行解析时,__proto__被直接当做构造类的属性,没有没当做键值,在传输的时候是没有成功的。

这题还有一个正解是同样利用到前端漏洞.extend绕过sandbox,从而利用xss打,具体看下面官方wphttps://github.com/NeSE-Team/OurChallenges/tree/master/XNUCA2019Qualifier/Web/hardjs

二.easyphp

源码很简单

这里两次unlink很严格,然后题目说了不是条件竞争,这里最后是重写覆盖.htaccess文件,然后注意apache的规则是注释要另起一行的所以为了要解决后面的脏数据的影响要利用 # \来将后面拼接的东西绕过,然后怎么绕关键词过滤也是利用反斜杠的拼接

这里利用预包含,将.htaccess中的内容包含到任意文件中,然后访问index.php触发

这里的payload是

然后访问/就可以反弹shell了,这里要注意下&要编码为%26(一些特殊字符最好都变下url码)。打到flag

 

这里是一个最简单的非预期解,还有一个非预期解是利用.htaccess设置preg_match的回溯次数

导致preg_match返回False,继而绕过了正则判断,filename即可通过伪协议绕过前面stristr的判断实现Getshell。

正规解是利用.htaccess修改include_path,利用error_log往fl3g.php中,但是error_log会html编码,需要利用utf-7编码绕过

具体看这两个:

https://xz.aliyun.com/t/6111#toc-6

 

https://www.anquanke.com/post/id/185377#h3-5

0x03总结

这次比赛感觉学到了很多东西,感谢出题的师傅们。