0x01 前言

Java Sec Code项目地址:https://github.com/JoyChou93/java-sec-code
如该项目的Readme所说,该项目是学习java漏洞代码非常强大且友好的项目。
将项目部署好后就可以进行审计了,该项目采用Springboot搭建。
工具:IDEA
插件:RestfulToolkit

0x02 代码审计

ProcessBuilder命令执行

ctrl+alt+n,搜索inject,选择/codeinject即可跳转到命令执行漏洞代码处。
image.png
从代码可以看到filepath参数直接拼接到命令中,ProcessBuilder最终导致命令执行。在filepath参数值为.%26ipconfig,这里使用&拼接命令,在windows中,&指令为并且。对&进行url编码的原因在于服务端会将&当作参数分割符而不是该符号本身。
image.png
codeInjectHost方法获取HTTP header中的host字段并拼接到命令中,也存在命令注入。
image.png
image.png
可以看到作者给的安全的方法,作者使用了正则白名单进行过滤。
image.png
image.png
对于ProcessBuilder和Runtime.exec两种命令执行的操作,以下对能否执行命令注入进行讨论。

  1. // 不可注入
  2. String path = request.getParameter("path");
  3. String[] cmd = new String[] {"ls","-lh",path};
  4. ProcessBuilder builder= new ProcessBuilder(cmd);
  5. // 可注入
  6. String path = request.getParameter("path");
  7. String[] cmd = new String[] {"/bin/sh","-c","ls -lh "+path};
  8. ProcessBuilder builder= new ProcessBuilder(cmd);
  9. // 可注入
  10. String path = request.getParameter("path");
  11. List<String> commands=new ArrayList();
  12. commands.add("/bin/sh");
  13. commands.add("-c");
  14. commands.add("ls -lh "+path);
  15. ProcessBuilder builder= new ProcessBuilder(commands);
  16. // 可注入
  17. String command = request.getParameter("command");
  18. ProcessBuilder builder= new ProcessBuilder(command);
  19. builder.redirectErrorStream(true);
  20. Process process = builder.start();
  21. // 可注入
  22. String command = request.getParameter("command");
  23. Process process = Runtime.getRuntime().exec(command);
  24. // 不可注入
  25. String url = request.getParameter("url");
  26. Process process = Runtime.getRuntime().exec("curl "+url);
  27. // 可注入
  28. String filename = request.getParameter("filename");
  29. Process process = Runtime.getRuntime().exec("sh -c ./shell/"+filename);

URL跳转漏洞

ctrl+alt+n,搜索/urlRedirect,可以看到漏洞代码,可见使用图中三种方式进行网页跳转都是不安全的。
image.png
而使用以下两种方式进行跳转是安全的。第一种只能跳转到存在的路径无法跳转到其它url,而第二种对参数进行了过滤操作,过滤操作的思路是先使用URI.getHost方法提取host,再判断host是否在黑白名单中。
image.png

XSS漏洞

以下是反射型和存储型XSS漏洞代码。
image.png
以下是安全的代码,对特殊符号进行了实体化编码。
image.png

目录遍历漏洞

存在漏洞和安全的代码如下,安全代码对../进行了过滤。
image.png
image.png

CORS漏洞

测试CORS的payload如下,需要注意一点的是,不可以直接打开html,这样使用的file协议打开文件,在进行跨域操作时无法携带cookie。需要将html放在服务器上再通过网页打开。

  1. <script>
  2. var req = new XMLHttpRequest();
  3. req.onload = reqListener;
  4. req.open('get','http://127.0.0.1:8080/cors/vuln/origin',true);
  5. req.withCredentials = true;
  6. req.send();
  7. function reqListener() {
  8. alert(this.responseText);
  9. };
  10. </script>
  1. <!-- demo1.html -->
  2. <script>
  3. var req = new XMLHttpRequest();
  4. req.onload = reqListener;
  5. req.open('POST','https://xxx/opUser/query',true);
  6. req.withCredentials = true;
  7. req.send();
  8. function reqListener() {
  9. alert(this.responseText);
  10. };
  11. </script>
  12. <!-- demo2.html -->
  13. <script>
  14. var req = new XMLHttpRequest();
  15. req.onload = reqListener;
  16. req.open('POST','https://xxx/application/list',true);
  17. req.withCredentials = true;
  18. req.setRequestHeader('content-type', 'application/json');
  19. var sendData = {pageNo:1,pageSize:10};
  20. req.send(JSON.stringify(sendData));
  21. function reqListener() {
  22. alert(this.responseText);
  23. };
  24. </script>

对于反射型origin,并且存在ACAC头且为true,可以直接使用以上的payload。
image.png
对于以下情况,设置ACAO头为*,那么对于需要cookie校验的url就无法获得相关信息,但是我认为它还有一种用法,用于获取内网url的敏感信息,通过js外带到攻击者的服务器,有ssrf的味了。
image.png

JSONP漏洞

JSONP的script类型的payload如下:

  1. <html>
  2. <head>
  3. <meta charset="utf-8">
  4. <title>JSONP劫持测试</title>
  5. </head>
  6. <body>
  7. <script type="text/javascript">
  8. function vulkey(data){alert(JSON.stringify(data));}
  9. </script>
  10. <script src="http://192.168.3.196:8080/jsonp/vuln/referer?callback_=vulkey"></script>
  11. </body>
  12. </html>

存在jsonp漏洞的代码如下,使用上述payload即可触发jsonp劫持,但是需要注意的是,我测试的时候在Edge和Chrome浏览器中会失败,而Firefox浏览器则可以,很奇怪,网上也没搜到这种情况。
image.png
对于以下漏洞代码,没有考虑到referer为null的情况,所以可以通过两种方式让referer头为空,一种是在html文件添加元信息,一种是通过iframe实现。

  1. <meta name="referrer" content="no-referrer" />
  2. <iframe src="javascript:'<script>function test(data){alert(data.name);}</script><script src=http://localhost:8080/jsonp/emptyReferer?callback=test></script>'"></iframe>

image.png
Spring Framework 5.0 to 5.0.6Spring Framework 4.1 to 4.3.17中如果使用MappingJackson2JsonView自动渲染也会导致jsonp劫持。
image.png
以下是通过fastjson将json转换为jsonp的实现,在该过程中并未对referer进行校验,也存在jsonp劫持漏洞。
image.png
image.png
总之,要判断jsonp劫持存不存在,就需要看返回的响应是否是application/javascript
image.png

0x03 CodeQL