【BUUCTF】BabySQli

Mr_Soap發表於2024-08-06

【BUUCTF】BabySQli

題目來源

收錄於:BUUCTF  GXYCTF2019

題目描述

純粹的SQL隱碼攻擊題

img

隨意傳入

name=abc&pw=a

返回 wrong user

img

嘗試傳入

name=1%27&pw=a

發現閉合方式為',同時給出了一個可疑字串

img

把這段字串丟進ChatGPT,告訴我們可能是Base32編碼的,對其進行Base32解碼得到字串

c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==

這顯然是Base64編碼的,再對其解碼,得到明文

select * from user where username = '$name'

顯然這道題的注入點就是name

題解

在嘗試的過程中發現以下字串被過濾

or  =   (   )  

但是由於對大小寫不敏感,or可以使用大小寫方式進行繞過

傳參:

name=1' Or 1#&pw=a

返回 wrong pass

img

說明name已經注入成功了,但是卻要校驗pw引數。

由於當name的值為1'時,會返回錯誤的語句,正常的思路是使用報錯注入,得到資料庫的資訊,但是過濾了(),因此也無法進行資料庫的查詢。

題目給了原始碼,點入search.php的原始碼,關鍵程式碼如下:

img

其登入邏輯是,根據name到資料庫中查詢,將查詢到的使用者名稱對應的md5加密的密碼與傳入的pw的md5值進行比較(即儲存在資料庫中的是密碼的md5值),若相等,則登入成功。這與CTF比賽中常見的直接對使用者名稱引數進行注入不同。

當我們傳入name=1' Or 1#&pw=a時,查詢的結果是使用者admin的使用者名稱和密碼,即$arr[1]的值是admin$arr[2]的值是admin使用者的密碼。當pw的md5值與$arr[2]的值相等時,就返回flag。而admin使用者的密碼是我們無法得到的。

因此我們需要控制$arr[2]的值,將其賦值為pw引數的md5值。當傳參如下時:

name=1' union select 1,"admin",3#&pw=a

返回也是 wrong pass,說明使用者名稱儲存在表中的第二列,猜測密碼儲存在第三列,傳參:

name=1' union select 1,"admin","0cc175b9c0f1b6a831c399e269772661"#&pw=a

其中0cc175b9c0f1b6a831c399e269772661a的md5值,這樣傳參,$arr[1]的值為admin$arr[2]的值為0cc175b9c0f1b6a831c399e269772661

總結

本題的登入邏輯與一般的題目不同,原始碼中的查詢語句並非是

select * from user where username = '$name' && password = '$pw'

而是

select * from user where username = '$name'

先選擇與使用者名稱匹配的記錄,記錄中儲存的是使用者名稱和密碼的md5值,再將查詢到的密碼的md5值與傳入引數的md5值進行比較。