ctf.show 萌新模塊的web1關, 這一關考察的是intval()函式轉換字串時的特性以及SQL的拼接繞過

這一關直接就給了原始碼, 并提示我們 id = 1000 時, 就是flag
先分析一下原始碼, 首先是 intval()函式將引數id轉換為數值型, id > 999直接die()結束程式, 也就是說我們傳遞的id不能大于 999, 明知道1000就是flag, 但不能直接傳1000, 否則程式會直接die()結束, 傳遞的id 即不能大于999, 又需要查詢 1000的值 , 這里我們可以通過 or( 邏輯或)來同時傳遞兩個id, 一個id用于繞過intval($id) > 999 的驗證, 另一個id 用來回傳1000的查詢結果, 也就是flag
?id=2 or id=1000
奪旗成功

這里需要解釋一下intval()函式的一些特性
intval()函式用來獲取變數的整數值, 使用的時候常見的有兩種情況
1. 轉換整數時,回傳整數本身
2. 轉換字串時, 會從字串的開始進行轉換,直到遇到一個非數字的字符,如果字串的第一個字符不是整數,則回傳0
當我們傳遞 id = 2 or id = 1000 時, 后臺的執行結果會是下面這樣

傳遞的引數 id = 2 or id = 1000 被當做一個字串 ' 2 or id = 1000' , intval()函式會從字串的開始進行轉換, 直到遇到非數字的字符, 轉換到or的時候, 由于or不是數字型別的字符, 從而停止轉換, 轉換的結果就只有 2 

傳遞的引數 id = 2 or id = 1000 被intval()函式轉換成2以后, 參與if條件判斷自然不會大于999, 從而繞過了intval()的校驗
繞過intval()函式的校驗以后自然就會執行后邊的SQL陳述句, 我們先來查看id的具體回傳結果

id = 1 的時候, 回傳了id為1的資訊

而當id = 2 的時候, 資訊是空顯示 , 也就是說資料庫里沒有id為2的資訊
當我們輸入的引數 id = 2 or id = 1000 參與SQL的執行時, 會變成下面這樣
select * from article where id = 2 or id = 1000 order by id limit 1
SQL會同時查詢2 和 1000 這兩個id的資訊, 剛才我們試過, id為2時, 沒有資訊, 那這條SQL查詢的結果就只有 id = 1000 的資訊, 從而回傳flag
除此之外, 還有一些其他的答案, 在此關卡的靶場中可以正常獲取flag, 但這些繞過只適用于PHP7.0以前的部分版本, 新版本中已經修復了這些漏洞, 以下是部分答案
字串繞過 '1000'
二進制 0b1111101000
十六進制 0x38e
兩次取反 ~~1000
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298600.html
標籤:其他
