Notes Site.
post @ 2023-11-10

Java反序列化-WebGoat

源项目:webgoat-server-8.2.2(https://github.com/WebGoat/WebGoat/releases)

Jdk:>=15(11不行)

启动命令:

1
java -jar webgoat-server-8.2.2.jar

http://127.0.0.1:8080/WebGoat/login

image-20231112185914293

题目java文件:webgoat-server-8.2.2.jar 解包,webgoat-server-8.2.2/BOOT-INF/lib/insecure-deserialization-8.2.2.jar再次解包,org/org.owasp.webgoat.deserialization下的文件

分析源码

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// InsecureDeserializationTask
package org.owasp.webgoat.deserialization;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.util.Base64;
import org.dummy.insecure.framework.VulnerableTaskHolder;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@AssignmentHints({"insecure-deserialization.hints.1", "insecure-deserialization.hints.2", "insecure-deserialization.hints.3"})
public class InsecureDeserializationTask extends AssignmentEndpoint {
public InsecureDeserializationTask() {
}

@PostMapping({"/InsecureDeserialization/task"})
@ResponseBody
public AttackResult completed(@RequestParam String token) throws IOException {
String b64token = token.replace('-', '+').replace('_', '/');

long before;
long after;
try {
label71: {
// base64解码,通过字节流反序列化对象
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(b64token)));

AttackResult var10;
label64: {
label63: {
try {
before = System.currentTimeMillis();
Object o = ois.readObject();
// 类必须是VulnerableTaskHolder
if (!(o instanceof VulnerableTaskHolder)) {
if (o instanceof String) {
var10 = this.failed(this).feedback("insecure-deserialization.stringobject").build();
break label64;
}

var10 = this.failed(this).feedback("insecure-deserialization.wrongobject").build();
break label63;
}

after = System.currentTimeMillis();
} catch (Throwable var12) {
try {
ois.close();
} catch (Throwable var11) {
var12.addSuppressed(var11);
}

throw var12;
}

ois.close();
break label71;
}

ois.close();
return var10;
}

ois.close();
return var10;
}
} catch (InvalidClassException var13) {
return this.failed(this).feedback("insecure-deserialization.invalidversion").build();
} catch (IllegalArgumentException var14) {
return this.failed(this).feedback("insecure-deserialization.expired").build();
} catch (Exception var15) {
return this.failed(this).feedback("insecure-deserialization.invalidversion").build();
}

int delay = (int)(after - before);
if (delay > 7000) {
return this.failed(this).build();
} else {
return delay < 3000 ? this.failed(this).build() : this.success(this).build();
}
}
}

Read More
post @ 2023-10-17

Java反序列化原理

Serializable 接口的使用

类需要被序列化和反序列化,需要实现接口 java.io.Serializable

Java 提供的序列化接口 Serializable ,是一个空接口,没有成员方法和变量

1
2
public interface Serializable { 
}
1
2
3
4
5
6
import java.io.Serializable;

public class Example implements Serializable{
private String name;
....
}

序列化 调用 ObjectOutputStream 类的 writeObject 方法

反序列化 调用 ObjectInputStream 类的 readObject 方法

注意:

只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列,否则会抛出异常。Externalizable 接口继承自Serializable接口,实现 Externalizable接口的类完全由自身来控制序列化的行为,而仅实现 Serializable 接口的类可以采用默认的序列化方式。

  1. 它是Java 提供的序列化接口,是一个空接口,没有成员方法和变量
  2. 一个类要想序列化就必须继承java.io.Serializable接口,同时它的子类也可以序列化(不用再继承Serializable接口)
  3. 一个实现Serializable 接口的子类也是可以被序列化的。在反序列化过程中,它的父类如果没有实现序列化接口,那么父类将需要提供无参构造函数来重新创建对象,这样做的目的是重新初始化父类的属性,父类对应的属性不会被序列化
  4. 序列化只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且序列化保存的只是变量的值,对于变量的任何修饰符都不能保存。即序列化是保存对象的状态(对象属性)
  5. transient 标识的对象成员变量不参与序列化
  6. Serializable 在序列化和反序列化过程中大量使用了反射,因此其过程会产生的大量的内存碎片

注:JAVA会被称为八股文,原因在于它的一个小知识点里会有很多细节在里面

Person

Read More
⬆︎TOP