連接:http://ctf5.shiyanbar.com/web/PHP/index.php
根據題目應該就是代碼審計得題,進去就是
日常工具掃一下,御劍和dirsearch.py 無果
抓包,發現返回得響應頭里面有提示
訪問則拿到源碼。。
有次聽培訓有個學長說,做代碼審計看代碼順序,先去找flag在哪兒,快速找到直接從那兒開始看。
intval() 返回變量得整數值
strrev() 這個函數讓字符串反序.
然后再來看代碼里is_palindrome_number()得功能,函數得功能
就是看看這個輸入這個字符是不是回文數,是就返回ture。(有時候如果看不懂函數得內容可以直接翻譯函數得名字,一般是對得,哈哈哈) // 回文數就是 12321 1112111 這樣的第i個和n-i個字符要相等。
ok,接下來說解題思路
四個限制條件
不得不說,CTF里得代碼審計老是出這種矛盾得題,其實就是想讓我們利用函數得漏洞繞過
第一個 is_numeric() 可以用%00繞過,可以輸入數字,所以這里第一個條件和第二個條件通過。%00可以放在開頭或結尾,%20只能放在最后。
三四個條件繞過得方法很多種
1.intval() 處理浮點數得時候直接返回整數,所以我們直接構造 number=0.00%00
這樣得話就可以滿足第三個條件滿足,因為0得反序也是0
但是代碼里那個函數處理number得時候,是從第一位和最后一位相等,倒數第二位和第二位相等一次類推,所以我們直接構造0.00,0是不是回文數我不知道,但是第二位 '.'和倒數第二位’0‘是不同得,所以檢測函數會判斷它不是回文數,所以條件4也繞過,拿到flag。
類似這個0.00%00 得原理還有 ’-0%00‘
2.number=0e00%00
這個原理和上面一樣,只是把0.00 換成科學記數法而已。
3.構造法3,這個構造法我去測試了發現不行,出處 https://blog.csdn.net/he_and/article/details/80615920
但是看了別人得wp發現以前是可以得。
能想出這個方法得人真是棒棒哦,也許題目就是想這么考得,因為32位最大就是 2147483647 ,value2得過程就是,先將2147483647反序,得到7463847412,而這個數字是大於2147483647這個數字得,所以intval()這個函數又會返回 2147483647,這樣就使得value1和value2得值都相等了,而2147483647這個數又不是回文數,所以繞過四個條件。
但是這個方法不行了,我也不知道為什么.
如果服務器是64位操作系統這個方法則不行,因為9223372036854775807這個數反序后比最大小。