# Big Binary Files Upload (PostgreSQL)

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来**分享您的黑客技巧**。

</details>

#### PostgreSQL大对象

PostgreSQL提供了一种称为**大对象**的结构，可通过`pg_largeobject`表访问，旨在存储大数据类型，如图像或PDF文档。这种方法优于`COPY TO`函数，因为它可以将数据**导出回文件系统**，确保原始文件的精确副本得以保留。

要在此表中**存储完整文件**，必须在`pg_largeobject`表中创建一个对象（由LOID标识），然后将每个2KB大小的数据块插入到此对象中。这些块的大小必须确切为2KB（最后一个块可能有例外），以确保导出功能正常运行。

要将您的**二进制数据分成2KB块**，可以执行以下命令：

```bash
split -b 2048 your_file # Creates 2KB sized files
```

对于将每个文件编码为Base64或Hex，可以使用以下命令：

```bash
base64 -w 0 <Chunk_file> # Encodes in Base64 in one line
xxd -ps -c 99999999999 <Chunk_file> # Encodes in Hex in one line
```

**重要提示**：在自动化此过程时，请确保发送2KB清晰文本字节的块。由于大小加倍，十六进制编码文件每个块需要4KB数据，而Base64编码文件遵循公式 `ceil(n / 3) * 4`。

可以使用以下方法查看大型对象的内容以进行调试：

```sql
select loid, pageno, encode(data, 'escape') from pg_largeobject;
```

**使用 `lo_creat` & Base64**

要存储二进制数据，首先创建一个 LOID：

```sql
SELECT lo_creat(-1);       -- Creates a new, empty large object
SELECT lo_create(173454);  -- Attempts to create a large object with a specific OID
```

在需要精确控制的情况下，比如利用盲注入（Blind SQL Injection），首选使用 `lo_create` 来指定固定的 LOID。

然后可以按以下方式插入数据块：

```sql
INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 0, decode('<B64 chunk1>', 'base64'));
INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 1, decode('<B64 chunk2>', 'base64'));

```

要导出并在使用后可能删除大型对象：

```sql
SELECT lo_export(173454, '/tmp/your_file');
SELECT lo_unlink(173454);  -- Deletes the specified large object
```

**使用 `lo_import` & Hex**

`lo_import` 函数可用于创建和指定大对象的 LOID：

```sql
select lo_import('/path/to/file');
select lo_import('/path/to/file', 173454);
```

在创建对象后，每页插入数据，确保每个数据块不超过2KB：

```sql
update pg_largeobject set data=decode('<HEX>', 'hex') where loid=173454 and pageno=0;
update pg_largeobject set data=decode('<HEX>', 'hex') where loid=173454 and pageno=1;
```

为了完成这个过程，数据被导出并且大对象被删除：

```sql
select lo_export(173454, '/path/to/your_file');
select lo_unlink(173454);  -- Deletes the specified large object
```

#### 限制

注意到**大对象可能有ACLs**（访问控制列表），可能会限制甚至是您的用户创建的对象的访问。然而，具有宽松ACL的旧对象仍然可以通过内容外泄来访问。


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
