天天看點

pg通過自定義函數_Pgsql堆疊注入場景下通過`CREATE FUNCTION`來實作指令執行

pg通過自定義函數_Pgsql堆疊注入場景下通過`CREATE FUNCTION`來實作指令執行

前言 在本篇文章中我将分享如何在

PostgreSQL

堆疊注入場景中通過

CREATE FUNCTION

關鍵字來實作指令執行的思路。 簡要資訊如下:

  • CVE:N/A
  • CVSS:4.1 (AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:L)
  • 适用環境:Windows、Linux、Unix

在新版的

PostgreSQL

中:

  • 12.3
  • 11.8
  • 10.13
  • 9.6.18
  • 9.5.22

其資料庫超管使用者被限制隻允許從預設目錄讀取字尾為

.dll

.so

動态庫檔案,舉例如下:

  • Windows:C:\Program Files\PostgreSQL\11\lib
  • Unix/Linux:/var/lib/postgresql/11/lib

此外,預設情況下

NETWORK_SERVICE

postgres

這兩個系統使用者對該目錄均無寫入權限。但是經過鑒權的資料庫超管使用者可以通過調用

lo_import

函數将檔案寫入

pg_largeobject

系統表,再更新對應的資料内容将原本的内容替換為我們的惡意代碼(通常是反彈個shell),随後通過

lo_export

函數轉儲資料至動态庫目錄,最終生成我們的惡意動态庫檔案。

CREATE FUNCTION

的另一個騷操作就是可以接收指定目錄來周遊其動态庫中的相關函數。是以隻要已鑒權使用者可以将動态庫檔案寫入對應的存儲目錄,然後通過

CREATE FUNCTION

的目錄周遊特性來加載動态庫檔案就可以實作指令執行。   利用流程

1. 通過

lo_import

獲得一個

OID

pg_largeobject

系統表儲存了那些标記為

large object(大對象)

的資料。每個

大對象

都會關聯其被建立成功時配置設定的

OID

标志。此後

大對象

都分解成足夠小的資料塊并關聯

pageno

字段來存儲

pg_largeobject

裡。每頁的資料定義為

LOBLKSIZE(目前是BLCKSZ/4或者通常是 2K 位元組)

該過程需使用

lo_import

函數,舉例如下:

在Windwos場景下這裡我們還可以使用

UNC路徑

,如果使用該項技術則可跳過3.3,但我希望相容Unix/Windows平台,所有沒有使用。

2. 基于

OID

來進行資料替換

現在,我們基于

OID

的值來替換

pg_largeobject

表中的資料,将其對應内容替換為我們的惡意代碼。這些

惡意代碼

最終需要基于目标資料庫的完整版本來進行編譯還要比對對應的系統架構。對于超過2048位元組大小的檔案,

pg_largeobject

表需使用

pageno

字段來将檔案分割成大小為2048位元組大小的資料塊。分割示例如下:

通過使用PostgreSQL中的

object identifier types

,可以跳過第1階段(并且僅對第2階段執行單個語句執行),但是我沒有時間确認這一點。

3. 使用

lo_export

函數生成惡意動态庫

現在我們可以通過

lo_export

來轉儲之前變相導入的資料來生惡意的動态庫檔案。不過這一步不能指定目錄,因為這樣做會觸發

PostgreSQL

内置的安全檢查,而且就算能繞過該檢查,

NETWORK_SERVICE

(Unix/Linux場景下為

postgres

)帳戶也存在路徑限制,搞不定搞不定。

4. 基于惡意動态庫檔案建立函數

我在以往的研究中提到過,可以使用絕對路徑(包括

UNC

)來加載基于

Postgresql 9.x

的擴充進而執行系統指令。

@zerosum0x0

師傅也有相關的 操作筆記 。不過那個時候對系統使用者的檔案操作權限并沒有那麼多的限制。

如今幾年過去了,PostgreSQL官方決定禁用

CREATE FUNCTION

時使用絕對路徑導緻現在這種技術已經失效了。不過現在我們可以很友善地從對應的預設動态庫目錄中周遊并加載我們轉儲的惡意動态庫檔案,舉例如下:

4. 反彈shell

成功建立

connect_back

函數後,直接通過

select

指令來調用:

  問題現狀

ZDI團隊

咨詢過PostgreSQL官方對該問題的意見,但無後文,後來我得知官方并不打算修複此問題,因為官方認為該問題屬于正常系統功能而不是漏洞。   造個輪子 代碼如下,将生成poc.sql檔案,以超管使用者在資料庫上逐漸執行,或将poc.sql中的sql指令逐個通過注入點執行:

跑一下展示下效果:

譯文聲明

譯文僅供參考,具體内容表達以及含義原文為準。

pg通過自定義函數_Pgsql堆疊注入場景下通過`CREATE FUNCTION`來實作指令執行

戳“閱讀原文”檢視更多内容