1. 程式人生 > 其它 >Buuctf-Web-[HCTF 2018]WarmUp

Buuctf-Web-[HCTF 2018]WarmUp

前言

刷題地址:https://buuoj.cn/challenges


首先開啟是一個笑臉,檢視原始碼,如下圖發現了,一個檔案

一.程式碼分析

發現是一堆程式碼,需要PHP程式碼審計,全部程式碼如下。

1 <?php
2    highlight_file(__FILE__);
3    class emmm
4    {
5        public static function checkFile(&$page)
6        {
7            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
8            if (! isset($page) || !is_string($page)) {
9                echo "you can't see it";
10                return false;
11           }
12
13            if (in_array($page, $whitelist)) {
14                return true;
15            }
16
17            $_page = mb_substr(
18                $page,
19                0,
20                mb_strpos($page . '?', '?')
21            );
22            if (in_array($_page, $whitelist)) {
23                return true;
24            }
25
26            $_page = urldecode($page);
27            $_page = mb_substr(
28                $_page,
29                0,
30                mb_strpos($_page . '?', '?')
31            );
32            if (in_array($_page, $whitelist)) {
33                return true;
34            }
35            echo "you can't see it";
36            return false;
37        }
38    }
39
40    if (! empty($_REQUEST['file'])
41        && is_string($_REQUEST['file'])
42        && emmm::checkFile($_REQUEST['file'])
43    ) {
44        include $_REQUEST['file'];
45        exit;
46    } else {
47        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
48    }  
49  ?> 

檢視到了關鍵字眼hint.php

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];

我們訪問這個檔案檢視,如下圖,發現flag在ffffllllaaaagggg裡面

首先先看40-48行的內容! empty($_REQUEST['file']的意思是傳參file不能為空

is_string($_REQUEST['file']的意思是傳參必須要字串

emmm::checkFile($_REQUEST['file']這句話的意思是要經過checkFile函式的檢查

如果都為真那麼就執行include $_REQUEST['file'];

包含檔案

如果為否那麼就輸出滑稽圖片

由此可以總結

1.file傳參不能為空

2.file傳參必須要字串

3.需要經過checkFile函式的檢測

40    if (! empty($_REQUEST['file'])
41        && is_string($_REQUEST['file'])
42        && emmm::checkFile($_REQUEST['file'])
43    ) {
44        include $_REQUEST['file'];
45        exit;
46    } else {
47        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
48    }  

接下來來看看,函式程式碼為5-38行,首先來看第一個if語句issset()函式判斷是否設定了$page,或者如果$page不是字串就輸出you can't see it然後返回為假。

第二個if語句判斷的是$page是否在$whitelist裡面,如果在那麼就返回true。

然後17行-21行是擷取$page?前面的東西mb_substr()函式是擷取,mb_strpos()涵數是判斷字串首次出現的位置就是,擷取$page0-?首次出現的位置的地方也就是擷取?前面的東西

22-24行又判斷$page是否在$whitelist裡面如果有那麼就返回true

26行對傳參進行了一次url編碼解碼

27-31又進行了一次擷取

32-34又進行了一次判斷是否在$whitelist裡面,如果有那麼就返回true

總結來說

1.第一個if判斷是$是否設定了值或者是$page是否為字串,如果不是返回false

2.第二個if判斷的是$page是否在$whitelist列表裡面如果在就返回true

3.第三個語句是擷取$page問號前面的東西

4.第四個語句會對$page進行一次url編碼的解碼,加上瀏覽器就是兩次解碼

5.第五個語句還是擷取$page問好前面的東西

6.最後一個語句判斷$page是否在$whitelist裡面

如果上面四個if語句都沒返回那麼就返回false

class emmm
4    {
5        public static function checkFile(&$page)
6        {
7            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
8            if (! isset($page) || !is_string($page)) {
9                echo "you can't see it";
10                return false;
11           }
12
13            if (in_array($page, $whitelist)) {
14                return true;
15            }
16
17            $_page = mb_substr(
18                $page,
19                0,
20                mb_strpos($page . '?', '?')
21            );
22            if (in_array($_page, $whitelist)) {
23                return true;
24            }
25
26            $_page = urldecode($page);
27            $_page = mb_substr(
28                $_page,
29                0,
30                mb_strpos($_page . '?', '?')
31            );
32            if (in_array($_page, $whitelist)) {
33                return true;
34            }
35            echo "you can't see it";
36            return false;
37        }
38    }

所以經過上面的判斷,payload應該是如下,測試其實不需要兩次編碼都可以,因為?的解碼還是?所以也可以直接/source.php?file=source.php?../../../../../../../../../../ffffllllaaaagggg

/source.php?file=source.php%253f../../../../../../../../../../ffffllllaaaagggg