文档网络安全教程【免费下载链接】Learn-Web-HackingStudy Notes For Web Hacking / Web安全学习笔记项目地址https://gitcode.com/gh_mirrors/le/Learn-Web-Hacking点击查看免费下载导读PHP 流Streams自 PHP 4.3 引入是对文件、网络、压缩等一切流式数据的统一抽象也是 Web 安全攻防中伪协议Wrapper利用的底层支撑。本篇以仓库 source/language/php/stream.rst 为骨架系统讲解封装协议清单、php://各类输入输出流与内存/临时流、php://filter元封装器及其过滤器体系并结合本仓库的 文件包含、XXE、Phar 反序列化、安全配置 等笔记梳理 LFI 读源码、XXE 编码绕过、资源耗尽 DoS、rot13 过 WAF 等实战利用链。读完本文你将掌握 PHP 流的完整能力图谱并能把这些伪协议知识直接用于文件读取、代码审计与 WAF 绕过场景。一、PHP 流Streams是什么流Streams的概念是在 PHP 4.3 引入的本质是对流式数据的抽象用于统一数据操作——无论是文件数据、网络数据还是压缩数据都可以通过同一套流式接口来读写。这一抽象层的价值在于上层代码不需要关心数据到底来自磁盘、内存、网络还是过滤器加工后的产物只需要面向统一的流接口编程。在 PHP 中流通常通过以下文件系统函数来操作fopen/fclose/fwrite/fread/fgetsfile/file_get_contents/file_put_contentscopy/file_exists/filesize/readfile这些函数内部统一走main/streams/streams.c所实现的流包装层。也正因为如此Phar 反序列化 笔记中指出PHP 在文件流处理过程中会调用_php_stream_stat_path位于php-src/main/streams/streams.c而后间接调用phar_wrapper_stat所以file_get_contents、fopen、file_exists等大量文件操作函数都能触发 phar 元数据的反序列化——流的统一抽象正是这类以流为入口的漏洞面被放大的根本原因。从安全视角看流的另一层意义在于不同封装协议wrapper赋予同一个file_get_contents()完全不同的能力——读本地文件、请求远程 URL、读写内存、对数据流做编码转换甚至触发对象反序列化。这就是伪协议成为 Web 安全核心议题的原因。二、封装协议Wrapper全景PHP 带有很多内置 URL 风格的封装协议可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数。当前环境支持的全部协议可以通过stream_get_wrappers()查看。协议用途file://访问本地文件系统http://访问 HTTP(s) 网址ftp://访问 FTP(s) URLsphp://访问各个输入/输出流I/O streamszlib://压缩流data://数据流RFC 2397glob://查找匹配的文件路径模式phar://PHP 归档Phar Archivessh2://Secure Shell 2rar://RAR 压缩归档ogg://音频流expect://处理交互式的流其中几个协议在安全利用中尤其高频data://可以直接在 URI 中内嵌数据内容如data://text/plain;base64,SSBsb3ZlIFBIUAo配合allow_url_includeOn可实现远程代码执行式的文件包含见 文件包含漏洞 的伪协议绕过一节。glob://支持使用 Shell 通配符?、*等匹配文件路径在 Sink 函数笔记 中被列为绕过open_basedir的原生类利用方式之一即DirectoryIterator结合glob://列举受限目录之外的文件。phar://以流的形式打开 phar 归档时会自动反序列化 manifest 中序列化存储的 meta-data从而触发反序列化攻击链详见 Phar 与反序列化。此外仓库 文件包含漏洞 的协议绕过一节指出allow_url_fopen和allow_url_include主要针对http、ftp两种协议生效因此攻击者可以使用 SMB、WebDav 等协议绕过这两项限制——这意味着协议是否可用不能只看上述两项配置stream_get_wrappers()的输出才是完整的事实清单。三、PHP 支持的流php:// I/O 流PHP 提供了一些输入/输出I/O流允许访问 PHP 进程的输入输出流、标准输入输出和错误描述符、内存中/磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。关键安全前提这些php://流不受allow_url_fopen限制但php://input、php://stdin、php://memory和php://temp受限于allow_url_include。也就是说只要allow_url_includeOn即使allow_url_fopenOffphp://input等流依然可以在include场景下被使用与 安全相关配置 笔记中allow_url_include默认关闭、allow_url_fopen默认开启的描述结合理解php://input的可用性直接取决于allow_url_include的开关状态。3.1 输入输出流php://stdin、php://stdout、php://stderrphp://stdin、php://stdout和php://stderr允许直接访问 PHP 进程相应的输入或者输出流。需要注意数据流的引用机制这些流引用的是复制的文件描述符所以如果在打开php://stdin并在之后关闭它仅关闭了复制品真正被引用的 STDIN 并不受影响。访问权限上php://stdin是只读的php://stdout和php://stderr是只写的。3.2 php://fd访问指定文件描述符php://fd允许直接访问指定的文件描述符。例如php://fd/3引用了文件描述符 3。这在 CLI 场景下可用于读取进程已打开的其他文件句柄在 Web 场景下较少直接利用但它是理解PHP 可以绕过文件路径直接操作 fd的入口点。3.3 php://memory 与 php://temp内存流与临时文件流php://memory和php://temp是一个类似文件包装器的数据流允许读写临时数据。两者的唯一区别是php://memory总是把数据储存在内存中php://temp会在内存量达到预定义的限制后默认是2MB把数据存入临时文件临时文件位置的决定方式与sys_get_temp_dir()一致。php://temp的内存限制可通过添加/maxmemory:NN来控制其中 NN 是以字节为单位、保留在内存的最大数据量超过该值则改用临时文件。例如// 最多保留 5MB 在内存中超过则落入临时文件 $fp fopen(php://temp/maxmemory:5242880, w);结合 PHP 其他特性笔记 中/tmp 临时文件竞争一节可以理解上传的临时文件与php://temp生成的临时文件都位于系统临时目录当phpinfo()可访问时可以看到上传临时文件的路径从而配合 LFI 实现利用——这类临时文件路径泄露 文件包含的组合是php://temp相关攻击思路的延伸。3.4 php://input读取请求原始数据php://input是个可以访问请求的原始数据的只读流。在 POST 请求的情况下最好使用php://input来代替$HTTP_RAW_POST_DATA因为它不依赖于特定的 php.ini 指令。而且在这样的情况下$HTTP_RAW_POST_DATA默认没有填充比激活always_populate_raw_post_data潜在需要更少的内存。两个实战要点当enctypemultipart/form-data时php://input是无效的——即 multipart 表单上传场景下无法通过该流读取原始请求体在 文件包含漏洞 的伪协议绕过一节中php://input是经典 payload?filephp://input把 PHP 代码放在 POST 参数中作为被包含的文件内容前提是allow_url_includeOn。四、php://filter元封装器与过滤器体系php://filter是一种元封装器meta-wrapper设计用于数据流打开时的筛选过滤应用。所谓元是指它本身不产生数据而是包装在另一个数据流resource之上在数据读入/写出时套用一系列过滤器。PHP 默认提供了一些流过滤器除此之外还可以使用各种自定义过滤器。4.1 filter 的三个参数php://filter有resource、read、write三个参数resource必需指定你要筛选过滤的数据流read可选设定在读取数据流时套用的一个或多个过滤器名称write可选设定在写入数据流时套用的一个或多个过滤器名称。多个过滤器名称以管道符|分隔。典型语法php://filter/readconvert.base64-encode/resourceindex.php php://filter/readstring.rot13|string.toupper/resourceindex.php php://filter/writeconvert.base64-decode/resourceshell.php最后一个示例在文件包含场景中常被用来写马先上传 Base64 编码后的 PHP 代码再用php://filter/writeconvert.base64-decode作为写入过滤器让目标把写入内容当作 Base64 解码后落盘从而得到可执行的 PHP 文件——这也是 文件包含 中伪协议绕过思路在写入方向的延伸。4.2 过滤器列表可以通过stream_get_filters()获取已经注册的过滤器列表。其中 PHP 内置的过滤器如下字符串过滤器string.rot13string.toupperstring.tolowerstring.strip_tags转换过滤器convert.base64-encodeconvert.base64-decodeconvert.quoted-printable-encodeconvert.quoted-printable-decodeconvert.iconv.*压缩过滤器zlib.deflatezlib.inflatebzip2.compressbzip2.decompress加密过滤器mcrypt.ciphernamemdecrypt.ciphername注意convert.iconv.*是一个可参数化的过滤器族通配符部分指定字符集配合string.rot13可以构造出极其多样化的字符变换组合而mcrypt.*/mdecrypt.*仅在对应扩展mcrypt可用时才会出现在stream_get_filters()的结果中。安全检查时建议先调用stream_get_filters()确认目标环境实际注册了哪些过滤器。4.3 过滤器利用 Tricks原笔记整理的过滤器攻击技巧是本节的核心逐条展开如下。LFI本地文件包含读源码php://filter/convert.base64-encode/resourceindex.php当include($_GET[file])可控时该 payload 会先对index.php的源码做 Base64 编码再输出从而绕过PHP 源码在解析后不可见的限制直接拿到明文源码。这是审计和漏洞利用中最经典的php://filter用法与 文件包含漏洞 中Base64: 使用 Base64 伪协议读取文件一节完全对应。XXE 读取文件时的编码救赎在 XXE 场景下如果直接在外部实体中引用目标文件如file:///etc/passwd因为 XML 解析器会把特殊字符、、引号等当作语法标记解析读取带特殊字符的文件会导致解析报错详见 XXE 笔记 的文件读取一节。此时可以用 Base64 编码包装将文件内容转化为纯字母数字字符规避解析器对特殊字符的拦截——原笔记称之为XXE 读取文件时会因而解析报错可用 base64 编码。Base64 过滤器的丢字符特性用于绕过文件格式Base64 编码会丢弃未在码表内的字符非A-Za-z0-9/的字符在解码时会被忽略。利用这一点可以让经过convert.base64-decode的数据洗掉掉不想要的字节从而绕过一些对文件格式的校验——例如在内容中混入干扰字符后通过 base64 解码最终得到的仍然是合法格式的文件内容。convert 过滤器的高资源消耗 → DoS部分convert过滤器尤其是convert.iconv.*这类字符集转换在处理特定输入时会消耗大量 CPU/内存资源。构造特定的 payload 反复触发这类过滤器可把服务端资源耗尽形成拒绝服务攻击。这属于基于资源的绕过/攻击的范畴与 WAF 笔记 中使用消耗大的载荷耗尽 WAF 的计算资源的思路同源——同样的手法既可以打 WAF也可以打业务进程本身。rot13 / convert 转换过 WAF利用string.rot13、string.toupper、convert.iconv.*等过滤器对读取内容做字符变换可以让流量中的载荷形态与 WAF 的规则库预期不一致例如用string.rot13先对目标文件内容做 ROT13 位移返回内容经过旋转后不再是原始明文若 WAF 基于内容关键字如?php、eval、system做黑名单正则匹配rot13 变换后的字符序列即可绕过关键字检测convert.base64-encode同理将明文转为 Base64 形态规避对明文关键字的匹配。这与 WAF 笔记 中基于规则的绕过——等价替换字符编码Base64、Unicode 解析等一节相互印证也呼应了 WebShell 笔记 中把str_rot13列入字符串变形函数的做法——过滤器的变换能力本质上与 WebShell 的混淆思路同构。五、PHP 流的纵深利用与防御对照把前面的协议与过滤器知识串起来可以得到一张针对本仓库其他笔记的利用对照表场景Payload / 手法仓库对应笔记LFI 读源码php://filter/convert.base64-encode/resourceindex.php文件包含LFI 执行代码php://inputPOST 携带代码需allow_url_includeOn文件包含LFI 内嵌数据data://text/plain;base64,SSBsb3ZlIFBIUAo需allow_url_includeOn文件包含远程包含http/https/ftp协议需allow_url_fopenOn且allow_url_includeOn文件包含绕过两项开关SMB、WebDav 等非http/ftp协议文件包含XXE 读文件外部实体 Base64 编码规避特殊字符解析报错XXEopen_basedir 绕过DirectoryIteratorglob://Sink、Open Basedir反序列化触发phar://配合file_get_contents等文件流函数PharSSRF 文件读取file:///etc/passwd、gopher://、dict://等协议SSRF几点防御侧的结论同样可以从本仓库相关笔记推导配置层面allow_url_include默认关闭、allow_url_fopen默认开启见 安全相关配置但这只约束http/ftp以及php://input、php://memory、php://temp、php://stdin等少数流file://、php://filter、phar://、glob://等协议并不受这两项开关管控因此不能把这两项配置当作伪协议利用的完整防线。目录层面open_basedir的检查实现在php-src/main/fopen-wrappers.cphp_check_open_basedir_ex它按路径前缀逐一比对来判断是否放行见 Open Basedir 笔记对路径类利用有效但对php://input、data://这类不指向真实文件路径的流无能为力。函数层面流的统一抽象意味着file_get_contents、fopen、readfile、copy、file_exists等文件系函数都可能成为伪协议入口Sink 笔记 中列出的 SSRF 危险函数file_get_contents()、fsockopen()、curl_exec()、fopen()、readfile()与 phar 触发点清单都应纳入代码审计的入口函数黑名单。六、小结PHP 流是理解一个file_get_contents()为什么能读源码、打内网、触反序列化的关键抽象封装协议决定了数据来源与访问能力本地文件、远程 URL、压缩包、内存、归档……可用stream_get_wrappers()盘点php://输入输出流stdin/stdout/stderr、fd、memory/temp、input提供了进程级数据通道其中php://input是 LFI 执行代码的核心入口php://filter元封装器通过resourceread/write过滤器链实现了对流的 Base64、ROT13、iconv 等任意变换支撑起 LFI 读源码、XXE 编码绕过、格式洗白、资源耗尽 DoS 与 WAF 绕过等一整套利用手法。掌握这张流图谱后建议继续结合本仓库的 PHP 目录索引 阅读 文件包含、SSRF、Phar、安全相关配置 与 WAF 等章节将流的理论知识落到实际的漏洞挖掘与 WAF 对抗场景中。赞分享文档网络安全教程【免费下载链接】Learn-Web-HackingStudy Notes For Web Hacking / Web安全学习笔记项目地址https://gitcode.com/gh_mirrors/le/Learn-Web-Hacking点击查看免费下载相关推荐Learn-Web-Hacking语言安全PHP、Java、Python代码审计实战Learn Web Hacking语言安全PHP、Java、Python代码审计实战 想要快速掌握Web安全审计技能吗Learn Web Hacking项目文档网络安全教程AI图像修复突破深度学习革新水印去除技术AI图像修复突破深度学习革新水印去除技术 在数字内容创作与传播中水印作为版权保护的重要手段却常常成为内容再利用的阻碍。无论是历史照片修复、学术资料整理还是文档网络安全教程PHP 版本安全改动全解析从 5.4 到 8.0 的漏洞面演变Learn-Web-Hacking 学习笔记PHP 版本安全改动全解析从 5.4 到 8.0 的漏洞面演变Learn Web Hacking 学习笔记 本篇技术指南聚焦 Learn Web Hack文档网络安全教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考