一、Java代码审计的前提

Java代码审计要有明确的审计思路,不然就只会呆呆的看着代码,抓不住重点。

Java代码审计有几个常用的思路,汇总如下:

  1. 按照接口往下排查
  2. 针对风险功能点审计
  3. Java常用的风险第三方组件
  4. 黑盒测试 + 白盒审计方法
  5. 搜索危险函数/关键字上下回溯法
  6. 静态代码审计工具 + 人工研判
  7. 如果能出网,可以使用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代码审计工具都是需要出网的。