【基础知识】Java代码审计(持续更新)
一、Java代码审计的前提
Java代码审计要有明确的审计思路,不然就只会呆呆的看着代码,抓不住重点。
Java代码审计有几个常用的思路,汇总如下:
- 按照接口往下排查
- 针对风险功能点审计
- Java常用的风险第三方组件
- 黑盒测试 + 白盒审计方法
- 搜索危险函数/关键字上下回溯法
- 静态代码审计工具 + 人工研判
- 如果能出网,可以使用AI插件等审计
二、接口排查思路
一个大型的Java项目,通常有很多接口,审计下来要花费不少时间,且难以抓到风险接口。
通常可以问运维相关人员有无接口文档或汇总表内容,一般会有像swagger这种集中式文档,可以将接口提取出来放入Apifox工具,联动burpsuite和xray,再手工排查风险接口。
三、风险功能点审计
这个需要我们通读整个项目代码,了解项目的功能都有哪些,然后再做出功能针对性的审计。
但是这个方法耗时耗力,收效还不大,通常和黑盒+白盒审计、危险函数/关键字相结合使用。
四、风险第三方组件
Java 中常见的风险第三方组件有,通常去pom.xml 中搜索即可:
- Fastjson(小于1.2.83、1.2.83_noneautotype)
- Apache Struts(struts2-core < 6.4.0)
- Jackson(jackson-core < 2.15.0,2.15.0-rc3、2.15.0-rc2、2.15.0-rc1)
- Log4j(log4j-core < 2.17.1)
- Apache Commons Collections(commons-collections < 3.2.2)
- Jetty(12.0.0 <= jetty-server < 12.0.9;11.0.0 <= jetty-server < 11.0.24;10.0.0 <= jetty-server < 10.0.24)
- JFinal(jfinal < 5.1.1)
- Hibernate(hibernate-core < 5.4.24.Final、5.5.0.Alpha1)
- MyBatis(mybatis < 3.5.6)
- junit(4.6 < junit < 4.13.1)
五、黑盒 + 白盒审计
由于代码无法直观的给出功能点代码所在的位置,这时候可以加上黑盒,从站点的界面入手,相关功能点一目了然,再根据路由接口等信息找到代码中功能点所在的位置,然后再进行审计。
六、危险函数/关键字上下回溯法
这个方法可谓是最常用的一种方法,通过关键字上下回溯到相关功能点进行审计。常见的函数/关键字有:
- SQL注入 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26- // 1、关键字搜索 
 select、insert、update、delete
 // 2、JDBC审计
 // 预编译搜索
 .prepareStatement
 PreparedStatement
 CallableStatement
 // 可预编译可非预编译,看内部使用的具体是什么
 execute(
 executeQuery(
 // 3、MyBatis审计
 搜索Mapper.xml文件中的${
 // 无漏洞写法
 SELECT * FROM tbuser where id = #{id}
 SELECT * FROM tbuser where username like concat('%',#{username},'%')
 // 有漏洞写法
 SELECT * FROM tbuser where username = '${username}'
 SELECT * FROM tbuser where id in (${ids})
 SELECT * FROM tbuser where username like '%${username}%'
 SELECT * FROM tbuser where id in (${ids})
 SELECT * FROM tbuser where order by ${colName} //这里如果用#是没有排序效果的
 //在mybatis中,order by 、in 、like 几种场景不能使用预编译
 // 因此对于Mybatis 的SQL注入,我们可以在IDEA中直接搜索如下关键字:
 $、like、in、order by
- XSS - 1 
 2- // 单从前端搜索关键词 
 <%=
- 文件上传 - 1 
 2
 3
 4- getFileExtension 
 fileType
 getFileName
 getInputStream
- 文件包含/读取 - 1 
 2
 3
 4
 5- include 
 BufferedReader
 FileReader
 readLine
 readAllLines
- 文件删除 - 1 
 2
 3
 4- File.delete() 
 Files.delete()
 Files.deleteIfExists()
 FileSystem.delete()
- 文件下载 - 1 
 2
 3- getOutputStream 
 buffer
 filename
- 代码执行 - 1 
 2
 3
 4
 5- Runtime.getRuntime().exec() 
 System.exec()
 ProcessBuilder.start()
 java.lang.reflect.Method.invoke()
 ScriptEngineManager.getEngineByName()
- 命令执行 - 1 
 2
 3
 4- Runtime.getRuntime().exec() 
 System.exec()
 ProcessBuilder.start()
 ProcessBuilder.command()
- 参数接收关键字 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38- // Servlet中的请求参数处理 
 request.getParameter(String name)
 request.getParameterValues(String name)
 request.getParameterMap()
 request.getAttribute(String name)
 request.getHeader(String name)
 // MVC中的请求参数出处理
 @RequestParam("paramName") String param
 @RequestParam(value = "paramName", required = false)
 @RequestParam(value = "paramName", defaultValue = "defaultValue")
 @RequestBody MyObject obj
 @RequestMapping("/api/{id}")
 public void getItem(@PathVariable("id") Long id)
 @RequestHeader("User-Agent") String userAgent
 @CookieValue("JSESSIONID") String sessionId
 // Spring Boot 中的关键字
 @RequestParam
 @RequestBody
 @PathVariable
 @RequestHeader
 @RequestMapping
 // 其他
 request.getInputStream()
 request.getReader()
 @ModelAttribute
 @ModelAttribute("user") User user
 @Validated
 @RequestParam("age") @Min(18) int age
 // 前端jsp渲染
 ${
七、静态代码审计工具
这里推荐使用 Fortify 这款Java静态代码审计工具,无需出网安装即可开始审计。
八、出网工具
那就很多了,AI插件包含其他很多Java代码审计工具都是需要出网的。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Lusenの小窝!
 评论
