以下內(nèi)容來自《白帽子講web安全》一書
Step
查找注入點
-
輸入單引號
'
,如果Web服務(wù)器開啟了錯誤回顯惊豺,那定是極好的,可以給我們提供很多有用的信息揩页,如果沒有錯誤回顯烹俗,我們可以通過盲注來判斷是否可以注入。比如數(shù)字型注入
http://newspaper.com/items.php?id=2
我們構(gòu)造http://newspaper.com/items.php?id=2 and 1=2
兔仰,這里后面永遠是假蕉鸳,所以我們會看到頁面是空或者是出錯的頁面。接下來无虚,再來驗證這一點,構(gòu)造
http://newspaper.com/items.php?id=2 and 1=1
友题,如果此時頁面正常返回了,那么就可以判斷id
參數(shù)存在SQL注入了度宦。-
盲注中一個非常隱蔽的技巧:
TimingAttack
戈抄。在MySQL中有一個
BENCHMARK(count,expr)
函數(shù),它是用于測試函數(shù)性能的划鸽。它將表達式expr執(zhí)行count次。我們可以利用這個函數(shù)嫂用,讓它執(zhí)行若干次丈冬,使得結(jié)果返回的時間比平時要長;通過時間長短的變化往弓,來判斷注入語句是否執(zhí)行成功蓄氧。在不同的數(shù)據(jù)庫中都有著類似BENCHMARK()的函數(shù)匀们。
-
MySQL BENCHMARK(10000000,md5(1)) or SLEEP(5) PostgreSQL PG_SLEEP(5) or GENERATE_SERIES(1,1000000) MS SQL Server WAITFOR DELAY '0:0:5'
- 常見的注入攻擊技巧
- 判斷數(shù)據(jù)庫對應(yīng)版本、表的結(jié)構(gòu)重抖、username祖灰、password等一系列信息,雖然可以通過手工一次次判斷局扶,但是使用工具是更明智的選擇,比如sqlmap.py
- 讀寫文件的技巧畜埋,比如在MySQL中悠鞍,可以通過
LOAD_FILE()
讀取系統(tǒng)文件,并通過INTO DUMPFILE
寫入本地文件咖祭。當然這要求當前數(shù)據(jù)庫用戶有讀寫系統(tǒng)相應(yīng)文件或目錄的權(quán)限么翰。.....union select 1,1, LOAD_FILE('/etc/passwd'),1,1;
- 如果要將文件讀出后牺汤,再返回給攻擊者浩嫌,則可以將系統(tǒng)文件讀出、寫入系統(tǒng)固该、然后通過
LOAD DATA INFILE
將文件導(dǎo)入常見的表中糖儡,最后就可以通過一般的注入攻擊技巧直接操作表數(shù)據(jù)了伐坏。 CREATE TABLE protatoes(lline BLOB);
UNION SELECT 1,1,HEX(LOAD_FILE('/etc/passwd')),1,1 INTO DUMPFILE '/tmp/potatoes';
LOAD DATA INFILE '/tmp/potatoes' INTO TABLE potatoes;
- 除了
INTO DUMPFILE
握联,還有INTO OUTFILE
,兩者區(qū)別是前者是用于二進制文件金闽,它會將目標文件寫入同一行內(nèi);二后者更適用于文本文件代芜。
- 命令執(zhí)行:在MySQL中,除了可以通過導(dǎo)出webshell間接地執(zhí)行命令挤庇,還可以利用“用戶自定義函數(shù)”技巧,及UDF(User-Defined Functions)來執(zhí)行命令嫡秕。原理是在流行的數(shù)據(jù)庫中,一般都支持從本地文件系統(tǒng)中導(dǎo)入一個共享庫文件作為自定義函數(shù)昆咽,使用如下語法可以常見UDF
CREATE FUNCTION f_name RETURNS INTEGER SONAME shared_library
- 有研究者給出了代碼可以通過UDF執(zhí)行系統(tǒng)命令牙甫,但是這段代碼在MySQL 5及后版本中受到限制。但是我們也可以用另一種方法——通過
lib_mysqludf_sys
提供的幾個函數(shù)執(zhí)行系統(tǒng)命名窟哺,其中最主要的是sys_eval()
和sys_exec()
技肩。- sys_eval 脏答,執(zhí)行任意命令亩鬼,并將輸出返回。
- sys_exec 雳锋,執(zhí)行任意命令,并將退出碼返回玷过。
- sys_get ,獲取一個環(huán)境變量辛蚊。
- sys_set ,創(chuàng)建或修改一個環(huán)境變量袋马。
- 自動化注入工具已經(jīng)集成了此功能。
python sqlmap.py -u "http://192.168.136.131/sqlmap/pgsql/get_init.php?id=1" --os-cmd id -v 1
- 攻擊存儲過程:存儲過程位數(shù)據(jù)庫提供了強大的功能虑凛,它與UDF很像,但存儲過程必須使用CALL或者EXECUTE來執(zhí)行桑谍。在MS SQL Server和Oracle數(shù)據(jù)庫中,都有大量內(nèi)置的存儲過程锣披。
- 比較"臭名昭著"的有“xp_cmdshell”、“xp_regread”等雹仿。還有很多有幫助的存儲過程,詳細的在書中P164盅粪。
- 編碼問題:當MySQL使用GBK編碼是,0xbf27和0xbf5c都會被認為是一個字符(雙字節(jié)字符)票顾。而在進入數(shù)據(jù)庫之前帆调,在Web語言中則沒有考慮到雙字節(jié)字符問題豆同,雙字節(jié)字符會被認為是兩個字節(jié)番刊。比如php中 addslashes() 函數(shù)影锈,或者當 magic_quotes_gpc 開啟時芹务,會在特殊字符前增加一個轉(zhuǎn)義字符 “\”鸭廷。因此,當攻擊者輸入:
0xbf27 or 1=1
辆床,經(jīng)轉(zhuǎn)義后會變成0xbf5c27
(\ 的ASCII碼為0x57),但0xbf57
又是另一個字符讼载。因此原本會存在的轉(zhuǎn)義符號“\”,在數(shù)據(jù)庫中就被吃掉了咨堤。 - SQL Column Truncation:MySQL中有一個sql-mode,當其被設(shè)置為 default 時一喘,即沒有開啟 STRICt_ALL_TABLES 選項時,MySQL對于用戶插入的超長值只會提示warning津滞,而不是error(如果error灼伤,則插入不成功)触徐,這可能會導(dǎo)致發(fā)生一些“截斷”問題狐赡。