HCTF 2018:WarmUp(源代码详解)
前言
之前刷BUUCTF時遇到過這題,這次刷XCTF時也遇到了,那就寫個詳細點的WP吧尋找利用點
打開題目,是一個滑稽圖
沒發現什么,查看下網頁源代碼,發現了source.php
訪問source.php,發現以下source.php中的代碼,經測試,這是index.php的源代碼
hint.php是什么?看一下,原來flag在/ffffllllaaaagggg中
代碼分析
代碼整體框架,其核心利用代碼如下:
if (! empty($_REQUEST['file'])&& is_string($_REQUEST['file'])&& emmm::checkFile($_REQUEST['file'])) {include $_REQUEST['file'];exit;} else {echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";}整體利用的漏洞就是代碼最后的include函數,利用文件包含漏洞
因此,最后的if條件語句是關鍵,即需要滿足if(true && true && true),才會執行include函數,否則輸出滑稽圖。
! empty($_REQUEST['file']滿足true簡單
is_string($_REQUEST['file']滿足true簡單
emmm::checkFile($_REQUEST['file']滿足true,需要執行emmm類中的checkFile函數,使得該函數最終返回true才可以
整體細節詳解(checkFile函數的目標就是返回true):
class emmm{public static function checkFile(&$page){$whitelist = ["source"=>"source.php","hint"=>"hint.php"];if (! isset($page) || !is_string($page)) {echo "you can't see it";return false;}if (in_array($page, $whitelist)) {return true;}$_page = mb_substr($page,0,mb_strpos($page . '?', '?'));if (in_array($_page, $whitelist)) {return true;}$_page = urldecode($page);$_page = mb_substr($_page,0,mb_strpos($_page . '?', '?'));if (in_array($_page, $whitelist)) {return true;}echo "you can't see it";return false;}}if (! empty($_REQUEST['file'])&& is_string($_REQUEST['file'])&& emmm::checkFile($_REQUEST['file'])) {include $_REQUEST['file'];exit;} else {echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";} 1、定義了一個類emm2、在類emm中定義了一個checkFile()函數3、不執行函數,先判斷下面的if語句:if (true && true && true)才能執行include函數,所 以需要滿足如下要求: (1)$_REQUEST['file']不為空,!empty($_REQUEST['file']才會返回true; (2)$_REQUEST['file']是字符串,is_string($_REQUEST['file']才會返回true; (3)checkFile($_REQUEST['file']返回true,emmm::checkFile($_REQUEST['file']才 會返回true; 因此,滿足這三個條件,最后才能執行include函數4、接下來看看checkFile()函數中的內容 (1)第一個if不能return flase,因為這里不能執行{}中的語句,因為不管return true或者return false,都會 終止當前函數的執行,所以需要滿足if (false || false)才能繼續執行下面的代碼,即,$page存在并且是字符串; (2)第2個語句可以執行,返回true 那么,就需要$whitelist中存在$page 注:in_array函數是檢查數組中是否存在某個值(找到true;找不false),特別注意這是在數組的鍵值中找,不包括鍵5、這樣的話我們就可以構造payload (1)測試payload1: http://111.198.29.45:56708/index.php?file=source.php 執行了source.php,輸出了里面的內容(2)測試payload2: http://111.198.29.45:56708/index.php?file=source.php../../../../../ffffllllaaaagggg 我想得到ffffllllaaaagggg時就出問題了,因為ffffllllaaaagggg不在$whitelist數組的鍵值中,并且 繼續執行代碼后,下面$_page=source.php../../../../../../../ffffllllaaaagggg,第3個if語句false, urldecode后$_page=source.php../../../../../../../ffffllllaaaagggg,mb_substr后還是這個,第4 個if語句還是false,最后輸出you can't see it,還return false,這還玩啥該如何解決?我需要include ffffllllaaaagggg文件,而且需要使用../,怎樣繞過? 注意到mb_strpos($page . '?', '?')沒,我們構造一個?即可(3)測試payload3: http://111.198.29.45:56708/index.php?file=source.php?../../../../../../ffffllllaaaagggg 構造?的話,第2個if語句就不能返回true了,第3個if語句一樣,也不能執行return語句,第4個if語句需要滿足if (true),因為需要執行{}中的內容,最后使得checkFile()函數返回的布爾類型為true(4)payload3執行流程:此時file=source.php?../../../../../../ffffllllaaaagggg 第1個if返回false 第2個if返回false $_page=source.php 第3個if返回true,退出checkFile函數,此時核心代碼中已滿足if(true&&true&&true),即執行include函數 最后include(source.php?../../../../../../ffffllllaaaagggg)疑惑:為什么urldecode沒有用到?有些wp用到了,但這也是多此一舉了,最后目標其實是一樣的,checkFile漢納樹返回true嘛
例如用到urldecode的payload:
執行流程:
第1個if返回false 第2個if返回false $_page=source.php%3f../../../../../ffffllllaaaagggg 第3個if返回false urldecode執行后,$_page=source.php?../../../../../ffffllllaaaagggg 執行mb_substr后$_page=source.php return true 下面核心代碼執行同理 最后include(source.php%253f../../../../../ffffllllaaaagggg)注意
(1)只要函數中return執行了,就會立即結束函數的執行,繼續執行函數外的代碼
(2)||表示任意||兩邊只要有一邊是true,整體就返回true
(3)in_array函數是檢查數組中是否存在某個值(找到true;找不false),特別注意這是在數組的鍵值中找,不包括鍵
(4)mb_strpos查找目標首次出現的位置,從0開始
(5)mb_substr返回字符串,特別注意的是:mb_strpos獲取的數字,在mb_substr不是從0開始,而是代表返回的長度
總結
以上是生活随笔為你收集整理的HCTF 2018:WarmUp(源代码详解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易大神怎么生成个人图鉴(网易游戏官网)
- 下一篇: 冰字网名76个