{{#include ../../../banners/hacktricks-training.md}} ### PostgreSQL 대용량 객체 PostgreSQL는 **대용량 객체**로 알려진 구조를 제공하며, 이는 `pg_largeobject` 테이블을 통해 접근할 수 있으며, 이미지나 PDF 문서와 같은 대형 데이터 유형을 저장하기 위해 설계되었습니다. 이 접근 방식은 **데이터를 파일 시스템으로 다시 내보내는** 기능을 제공하므로, 원본 파일의 정확한 복제본이 유지됩니다. 이 테이블 내에서 **전체 파일을 저장하기 위해**, `pg_largeobject` 테이블에 객체를 생성해야 하며(LOID로 식별됨), 그 다음에 각 2KB 크기의 데이터 청크를 이 객체에 삽입해야 합니다. 이러한 청크는 내보내기 기능이 올바르게 작동하도록 보장하기 위해 정확히 2KB 크기여야 합니다(마지막 청크는 예외일 수 있음). **이진 데이터를** 2KB 청크로 나누기 위해 다음 명령을 실행할 수 있습니다: ```bash split -b 2048 your_file # Creates 2KB sized files ``` 각 파일을 Base64 또는 Hex로 인코딩하기 위해 아래의 명령어를 사용할 수 있습니다: ```bash base64 -w 0 # Encodes in Base64 in one line xxd -ps -c 99999999999 # Encodes in Hex in one line ``` **중요**: 이 프로세스를 자동화할 때, 2KB의 일반 텍스트 바이트 청크를 전송해야 합니다. Hex 인코딩된 파일은 크기가 두 배로 증가하기 때문에 청크당 4KB의 데이터가 필요하며, Base64 인코딩된 파일은 `ceil(n / 3) * 4` 공식을 따릅니다. 대용량 객체의 내용은 디버깅 목적으로 다음을 사용하여 볼 수 있습니다: ```sql select loid, pageno, encode(data, 'escape') from pg_largeobject; ``` #### Using `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('', 'base64')); INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 1, decode('', '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') where loid=173454 and pageno=0; update pg_largeobject set data=decode('', '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 ``` ### 제한 사항 **대형 객체는 ACL(Access Control Lists)을 가질 수 있으며**, 이는 사용자에 의해 생성된 객체에 대한 접근을 제한할 수 있습니다. 그러나 허용적인 ACL을 가진 오래된 객체는 여전히 콘텐츠 유출을 위해 접근할 수 있을 수 있습니다. {{#include ../../../banners/hacktricks-training.md}}