代码审计之Java[ING]

Published: 二 15 三月 2022

In Vuln.

慢慢更新,现在还看不得!!!!

准备

工具

漏洞挖掘第一步当然是把环境搭起来,然后安装一些必要的工具:

1.Idea:不会还有人用eclipse吧?!!

2.jclasslib/fernflower/bytecodeviewer/jd-gui:各种反编译工具

3.arthas/btrace:各种插桩工具,动态分析工具

4.javaassist/asm:字节码修改工具

由于jar和class不便于搜索,所以可以将其先反编译为java文件,此处使用fernflower,可下载最新版编译,idea也自带此jar包:

git clone https://github.com/fesh0r/fernflower.git  # 下载软件
gradlew.bat  # 安装gradle
gradlew.bat build  # 编译项目,最新版默认使用jdk11,可修改build.gradle里的配置

cd workdir  # 切换到项目目录
mkdir src  # 创建新文件夹存放源码
java -jar fernflower.jar ./class ./src  #反编译

知识

1.Java基础语法

2.Java EE语法,就JSP/Servlet/MVC这些

3.其他高级语法:反射,动态代理(proxy/cglibc),动态代码生成,注解,类加载

注解:类似于注释但在多个阶段可使用,如可创建运行时有效的注解,运行时使用反射获取其值并进行相应动作。

img

语言特性漏洞

JAVA安全编码与代码审计:https://github.com/Cryin/JavaID/blob/master/JAVA%E5%AE%89%E5%85%A8%E7%BC%96%E7%A0%81%E4%B8%8E%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1.md

java代码审计手书:http://wiki.ioin.in/post/group/74mW

技术分享|浅谈Java Web漏洞分析:https://mp.weixin.qq.com/s/S4UEHy-JTVJ23VcPjooqcQ

sun.net.www.protocol.包下面可以看到所支持的协议:gopher file ftp http https jar mailto netdoc

将库和类文件添加到项目里,如一般项目会把classeslib放入WEB-INF目录下,另外可能需要调试J2EE相关的库,可以将其添加到项目结构里:

img

XXE

XXE 漏洞代码及修复代码整理:https://zhuanlan.zhihu.com/p/265402618

Java XXE Vulnerability:https://docs.ioin.in/writeup/joychou.org/_web_java_xxe_vulnerability_html/index.html

一篇文章读懂Java代码审计之XXE:https://blog.csdn.net/sun1318578251/article/details/104426472

SMTP over XXE − how to send emails using Java's XML parser:https://shiftordie.de/blog/2017/02/18/smtp-over-xxe/

SAXBuilder
SAXParserFactory
SAXReader
SAXTransformerFactory
TransformerFactory
ValidatorSample
XMLReader
Unmarshaller
SchemaFactory
.....

SSRF

SSRF in JAVA:https://docs.ioin.in/writeup/joychou.org/_index_php_web_javassrf_html/index.html

JAVA代码审计之XXE与SSRF:https://xz.aliyun.com/t/2761

模板注入

搜Freemarker和Velocity

[模板注入一例(]http://gv7.me/articles/2019/apache-solr-velocity-rce-20191031/)

LDAP注入

浅谈LDAP注入攻击:https://www.anquanke.com/post/id/212186

表达式注入

EL/OGNL/SPEL

浅析 OGNL 的攻防史:https://paper.seebug.org/794/

由浅入深SpEL表达式注入漏洞:http://rui0.cn/archives/1043

Bean Stalking: Growing Java beans into RCE:https://securitylab.github.com/research/bean-validation-RCE/

文件包含

动态包含:<jsp:include page="<%=file%>"></jsp:include><c:import url="<%= url%>"></c:import>

命令注入

常见的会使用new ProcessBuilder.commandRuntime.getRuntime.exec

文件上传

multipartfileUploadgetParts获取文件上传点[1],看文件名能不能穿越或传恶意文件,再看文件内容能不能造成危害。

对于spring可搜索multipartResolver看是否修改了默认解析器,它的StandardMultipartFile(默认)不过滤目录穿越而CommonsMultipartFile会过滤[0]。

参考

[0] Spring MultipartFile 文件上传的潜在威胁 -- JOHNSON (2021)

[1] 任意文件上传漏洞 -- 园长

框架

spring

现在遇到的基本都是spring,包括spring,spring mvc, spring boot, spring cloud等,它们有各自的应用场景,关系如下:

理解spring需要懂它的面向切面编程(AOP)/控制反转(IOC)/依赖注入(DI)等概念

现在遇到的一般都是基于Spring框架的,Spring家族里有很多东西,但只需理解它的核心概念:

IOC:控制反转,将对象的生成交由Spring实现,这样方便实现DI和AOP

AOP:面向切面编程,可用于避免面向对象编程时必须的层级关系,作为补充它通过功能来复用代码

DI:依赖注入,可自动根据属性类型,名称等注入所需的实例

img

spring mvc一般了解它的处理流程即可,可见“Spring MVC的介绍与执行流程”:

img

spring在查找handler时,可能会做一些奇怪的操作(如可匹配//),或者开发自行添加了路径匹配规则,从而绕过一些限制。

历史漏洞

  1. CVE-2022-22965:利用参数绑定修改Tomcat的日志配置实现写马
  2. CVE-202X-XXXXX: 和Shiro一起造成的各种问题
  3. ...

参考

  1. SpringBoot内置tomcat启动原理
  2. 一些spring源码解读

  3. 设计模式角度解读

Java框架级SSM代码审计思路:https://paper.seebug.org/1075/

struts

struts和struts2有些区别,但都很少见了,在我开始挖Java应用后只见过一次,关于它的基础可看W3school,现在一般也就是学它的那一系列漏洞,主要是ognl表达式的问题,可见如下链接:

  1. 从零开始学java web - struts2 RCE分析
  2. struts2(一)之初识struts2

  3. struts2(二)之配置文件详解与结果视图

  4. struts2(三)之表单参数自动封装与参数类型自动转换

  5. struts2(四)之输入校验

  6. struts2(五)之struts2拦截器与自定义拦截器

  7. struts2(六)之ognl表达式与ActionContext、ValueStack

  8. Struts2 S2-059 漏洞分析

  9. Struts2-059 远程代码执行漏洞(CVE-2019-0230)分析

webservice

这一类没有特别的,就是要六节web service协议,常见的框架有WebService,xfire(cxf),axis。

组件

持久化

mybatis

mybatis是半自动化的,需要开发编写SQL语句,此时参数可用#{}和${}方式放置,后者直接替换如SQL语句再预编译因此存在SQLi,有三种情况无法用#{},因此易出问题[1]

1.like后无法直接用,可like concat('%', #{}, '%')的方式

2.in后的参数

3.oder by后的参数,可用白名单限制

hibernate

  1. ysoserial Java 反序列化系列第二集 Hibernate1
  2. ysoserial Java 反序列化系列第三集 Hibernate2

H2

它可以执行Java命令,堆叠注入(猜测未验证),注意每次修改后函数名也需要修改:

// http://www.h2database.com/html/commands.html?highlight=alias&search=alias#create_alias
CREATE ALIAS DDrrArr AS $$void replace() throws java.io.IOException{new java.io.File("webapps/ROOT/weixin.jsp").renameTo(new java.io.File("webapps/ROOT/weixin.jsp.bak"));java.io.FileWriter writer = new java.io.FileWriter("webapps/ROOT/weixin.jsp");writer.write("<%=123;%>");writer.close();}$$;
CALL DDrrArr();

JavaWeb中的信息泄漏——H2 database:https://www.sec-in.com/article/827

Ehcache

。。。

MYSQL-JDBC反序列化入口

使用MySQL JDBC连接器在连接可控时可能存在反序列化入口点(版本小于8.0.23),若再存在利用链则可RCE,原因是它的结果集封装了反序列化操作getObject,如下:

    public Object getObject(int columnIndex) throws SQLException {
        int columnIndexMinusOne = columnIndex - 1;

        Field field = this.fields[columnIndexMinusOne];

        switch (field.getSQLType()) {
            /* 当SQL类型与域类型如下时,将会调用getObjectDeserializingIfNeeded*/
            case Types.BIT:
                if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT && !field.isSingleBit()) {
                    return getObjectDeserializingIfNeeded(columnIndex);
                }
                return Boolean.valueOf(getBoolean(columnIndex));
            ...
            case Types.BINARY:
            case Types.VARBINARY:
            case Types.LONGVARBINARY:
                if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_GEOMETRY) {
                    return getBytes(columnIndex);
                }
                return getObjectDeserializingIfNeeded(columnIndex);
            ...
        }
    }

    private Object getObjectDeserializingIfNeeded(int columnIndex) throws SQLException {
        final Field field = this.fields[columnIndex - 1];

        if (field.isBinary() || field.isBlob()) {
            byte[] data = getBytes(columnIndex);

            if (this.connection.getAutoDeserialize()) {  // 设置了自动反序列化
                Object obj = data;

                if ((data != null) && (data.length >= 2)) {
                    if ((data[0] == -84) && (data[1] == -19)) {  // 数据以ACED开始
                        try {
                            ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
                            ObjectInputStream objIn = new ObjectInputStream(bytesIn);
                            obj = objIn.readObject();
            ...
    }

如果我们能(1)控制MySQL查询的返回数据且(2)设置了自动反序列化,而且(3)会对结果集调用getObject,就能在此处进行反序列化。这个连接器支持的一个拦截器满足条件(3):

public class ServerStatusDiffInterceptor implements StatementInterceptor {

    public ResultSetInternalMethods postProcess(String sql, Statement interceptedStatement, ResultSetInternalMethods originalResultSet, Connection connection)
            throws SQLException {

        if (connection.versionMeetsMinimum(5, 0, 2)) {
            populateMapWithSessionStatusValues(connection, this.postExecuteValues);
        ...
    }
    private void populateMapWithSessionStatusValues(Connection connection, Map<String, String> toPopulate) throws SQLException {

        try {
            stmt = connection.createStatement();
            rs = stmt.executeQuery("SHOW SESSION STATUS");
            Util.resultSetToMap(toPopulate, rs);
            ...
    }

    public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs) throws SQLException {
        while (rs.next()) {
            mappedValues.put(rs.getObject(1), rs.getObject(2));
        }
    }

漏洞点能指定连接器,连接器能指定拦截器,拦截器会在查询前后自动执行于是满足了条件(3),这个漏洞点又满足条件(1)(2),串起来就是个反序列化点了,接下来就是找利用链,至于如何构造数据包可参考[1][2][3]。

安全

Shiro

密钥不正确或者反序列化后类不正确会返回rememberMe=deleteMe

CVE-2020-11989,CVE-2020-13933权限绕过漏洞

shiro < 1.6.0的认证绕过漏洞分析(CVE-2020-13933):https://www.anquanke.com/post/id/214964

Spring Security

漏洞利用

回显

Java 反序列化回显的多种姿势:https://xz.aliyun.com/t/7740

木马

  • https://www.anquanke.com/post/id/214435
  • https://www.anquanke.com/post/id/214483#h2-6

自动化

漏洞挖掘

类型 说明 参考
tabby 白猪写的,用图数据库存储调用关系,通过写查询语句就可以自动化完成利用链查找工作
CodeQL [0]代码分析引擎 CodeQL 初体验,[1]使用 CodeQL 分析闭源 Java 程序
RASP 运行时应用自保护,一般通过Agent侵入待保护进程,根据规则对危险操作进行检测与拦截 [0]Java RASP浅析——以百度OpenRASP为例,[1]浅谈 RASP
IAST 聊聊对目前Passive IAST的思考

探索先进自动化漏洞挖掘技术中的不足:https://paper.seebug.org/1404/

插桩技术在Java安全中的应用简述:http://rui0.cn/archives/1063

Java 反序列化工具 gadgetinspector 初窥:https://paper.seebug.org/1034/

Java动态追踪技术探究:https://juejin.cn/post/6844903785219751943

[译]使用ASM对Java字节码插桩:https://c0d3p1ut0s.github.io/%E8%AF%91-%E4%BD%BF%E7%94%A8ASM%E5%AF%B9Java%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9/

00