▷ 【基础知识】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注入
1234567891011121314151617181920212223242526// 1、关键字搜索select、insert、update、delete// 2、JDBC审计// 预编译搜索.prepareStatementPreparedStatement 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
12// 单从前端搜索关键词<%=
文件上传
1234getFileExtensionfileTypegetFileNamegetInputStream
文件包含/读取
12345includeBufferedReaderFileReaderreadLinereadAllLines
文件删除
1234File.delete()Files.delete()Files.deleteIfExists()FileSystem.delete()
文件下载
123getOutputStreambufferfilename
代码执行
12345Runtime.getRuntime().exec()System.exec()ProcessBuilder.start()java.lang.reflect.Method.invoke()ScriptEngineManager.getEngineByName()
命令执行
1234Runtime.getRuntime().exec()System.exec()ProcessBuilder.start()ProcessBuilder.command()
参数接收关键字
1234567891011121314151617181920212223242526272829303132333435363738// 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代码审计工具都是需要出网的。