PostgreSQL exposes a structure called** large object (**`pg_largeobject` table), which is used for storing data that would be difficult to handle in its entirety (like an image or a PDF document). As opposed to the `COPY TO` function, the advantage of **large objects** lies in the fact that the **data **they **hold **can be **exported back **to the **file system **as an** identical copy of the original imported file**.
In order to **save a complete file inside this table** you first need to **create an object** inside the mentioned table (identified by a **LOID**) and then** insert chunks of 2KB** inside this object. It's very important that all the **chunks have 2KB** (except possible the last one) **or **the **exporting **function to the file system **won't work**.
When exploiting this remember that you have to send **chunks of 2KB clear-text bytes** (not 2KB of base64 or hex encoded bytes). If you try to automate this, the size of a **hex encoded **file is the **double **(then you need to send 4KB of encoded data for each chunk) and the size of a **base64 **encoded file is `ceil(n / 3) * 4`
If you are abusing a **Blind SQLinjection** you will be more interested on using `lo_create` with a **fixed LOID** so you **know where **you have to **upload **the **content**.\
Note the in newest versions of postgres you may need to **upload the extensions without indicating any path** at all. [**Read this for more information**.](rce-with-postgresql-extensions.md#rce-in-newest-prostgres-versions)
{% endhint %}
You possible may be interested in delete the large object created after exporting it:
```sql
SELECT lo_unlink(173454); -- deletes large object with OID 173454
In this scenario lo_import is going to be used to create a large object object. Fortunately in this case you can (and cannot) specify the LOID you would want to use:
select lo_unlink(173454); -- deletes large object with OID 173454
```
{% hint style="info" %}
Note the in newest versions of postgres you may need to **upload the extensions without indicating any path** at all. [**Read this for more information**.](rce-with-postgresql-extensions.md#rce-in-newest-prostgres-versions)
After reading the documentation of large objects in PostgreSQL, we can find out that **large objects can has ACL **(Access Control List). It's possible to configure **new large objects** so your user **don't have enough privileges** to read them even if they were created by your user.