【基础知识】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 byXSS
1
2// 单从前端搜索关键词
<%=文件上传
1
2
3
4getFileExtension
fileType
getFileName
getInputStream文件包含/读取
1
2
3
4
5include
BufferedReader
FileReader
readLine
readAllLines文件删除
1
2
3
4File.delete()
Files.delete()
Files.deleteIfExists()
FileSystem.delete()文件下载
1
2
3getOutputStream
buffer
filename代码执行
1
2
3
4
5Runtime.getRuntime().exec()
System.exec()
ProcessBuilder.start()
java.lang.reflect.Method.invoke()
ScriptEngineManager.getEngineByName()命令执行
1
2
3
4Runtime.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的小窝!
评论