如何绕过PHP文件包含限制?

12 人参与

如果你认为PHP文件包含限制仅仅是开发者的安全指南,那可能低估了它的实战价值。在渗透测试CTF竞赛中,绕过这些限制往往是通往关键信息或系统控制权的钥匙。限制本身是防线,而绕过的方法,则是一套精密的“锁匠”工具。

限制的本质与通用旁路

常见的限制手法,比如用stripos()检查文件名中是否包含点号(.),或者用str_replace()过滤掉../这类路径穿越符。它们的意图很明确:把你困在指定的目录里。但思路一换,海阔天空。

当点号被禁,php://filter伪协议就成了你的老朋友。它根本不需要文件扩展名。通过convert.base64-encode等过滤器,你甚至能把目标文件的内容以base64格式读出来,绕过很多基于内容直接输出的限制。如果连php://被部分关键字过滤,试试大小写变体、双写绕过,或者利用某些环境下的编码特性。

路径截断:一个被遗忘的老技巧

在PHP版本低于5.3.4,且magic_quotes_gpc关闭的情况下,路径截断(Path Truncation)曾大放异彩。核心是利用include($filename . '.php')这类拼接操作。如果你能让$filename足够长,超过系统路径处理的最大长度,后面的'.php'就会被无情地截断。怎么变长?大量./或者长目录名堆叠起来就行。虽然现代PHP环境已基本修复,但理解它有助于明白安全边界是如何被一点点侵蚀的。

逻辑缺陷的精准打击

有时候,最坚固的防线是从内部瓦解的。看看这个条件判断:if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)。它像一道复杂的组合锁。

$id==0看似简单,但GET参数传id=0可能不行,因为字符串"0"在松散比较(==)时等于整数0。关键是eregi()这个废弃的正则函数,它存在空字节截断漏洞。传入%000x00,可能会让匹配逻辑失效。更巧妙的或许是substr($b,0,1)!=4eregi("111".substr($b,0,1),"1114")的配合。如果substr($b,0,1)"4",前一个条件不满足;如果不是"4",又如何匹配"1114"?这里可能需要利用eregi()的漏洞或类型混淆,让第一个字符在比较时不是4,但在正则截取时又被忽略。这种绕过的快感,不亚于解出一道数学谜题。

环境与配置的“助攻”

服务器配置偶尔会成为“神队友”。如果allow_url_include被意外开启(默认关闭),那么包含远程文件(RFI)就成为可能,攻击面瞬间从本地扩展到整个互联网。session文件、日志文件、通过php://temp等伪协议临时生成的文件,都可能成为注入恶意代码的载体。这种绕过,考验的是对攻击面理解的广度。

说到底,绕过限制是一场开发者与安全研究者之间的思维博弈。防御方在明处设下关卡,攻击方在暗处寻找每一处缝隙、每一条逻辑歧义。理解这些方法,不是为了破坏,而是为了构建更无懈可击的防御——毕竟,你知道锁是怎么被打开的,才能造出更好的锁。

参与讨论

12 条评论
  • 林间小路

    这个路径截断现在还能用吗?

    回复
  • 草莓牛奶冰

    之前试过伪协议,确实能绕开一些检查

    回复
  • 颙鸟啼夜

    看不懂,太硬核了

    回复
  • 峨眉山径

    strlen($b)>5 这个条件感觉有点迷

    回复
  • 霸道的蝴蝶

    session文件包含这个点挺有意思

    回复
  • 馋猫

    hhhh 想起了当年打CTF被eregi支配的恐惧

    回复
  • 浮世

    有没有更简单的例子能演示一下?

    回复
  • 流水浮灯

    php://filter 在实战里确实好用

    回复
  • 影之回响

    老漏洞了,现在环境基本都修复了吧

    回复
  • 梦幻动画

    感觉像是在看天书 😂

    回复
  • 青空之翼

    那如果allow_url_include关了,还有其他招吗?

    回复
  • 古井边

    逻辑绕来绕去的,头大

    回复