
1. 项目概述为什么CVE-2019-15107至今仍值得警惕几年前一个编号为CVE-2019-15107的漏洞在Webmin社区掀起了轩然大波。Webmin这个老牌且广泛使用的Linux/Unix系统Web管理面板因其直观的图形化界面被无数系统管理员、运维工程师甚至开发者用来管理服务器。你可以通过它配置网络、管理用户、安装软件包、设置防火墙规则几乎涵盖了服务器管理的方方面面。正因为它权限高、功能全一旦出现安全漏洞后果往往是灾难性的。CVE-2019-15107正是一个这样的“灾难级”漏洞。它不是一个简单的功能缺陷而是一个存在于密码更改功能中的远程代码执行漏洞。攻击者无需任何身份验证只需要向存在漏洞的Webmin服务器发送一个精心构造的HTTP请求就能以Webmin进程通常是root权限的身份在目标服务器上执行任意命令。这意味着什么意味着攻击者可以瞬间获得服务器的最高控制权植入后门、窃取数据、加密文件进行勒索或者将你的服务器变成僵尸网络的一员。尽管这个漏洞的公开披露和修复已经是几年前的事情但我在日常的安全巡检和应急响应中依然能频繁地发现未修复的案例。原因有很多一些老旧系统长期无人维护一些管理员认为内网环境就绝对安全还有一些则是单纯地忘记了更新。更关键的是这个漏洞的利用方式相对简单利用代码在互联网上唾手可得使得它成为自动化攻击脚本和僵尸网络扫描的“常客”。因此无论你是正在使用Webmin还是负责维护可能遗留有Webmin的系统掌握这个漏洞的检测与修复都是一项必备的安全技能。这篇指南我将结合多次实战处理经验带你彻底搞懂它的来龙去脉并提供一套从检测、验证到彻底修复的完整方案。2. 漏洞核心原理深度拆解从“密码重置”到“命令执行”要有效防御必须先理解漏洞是如何产生的。CVE-2019-15107的根源在于Webmin的password_change.cgi文件对用户输入的处理存在严重缺陷。这个文件负责处理用户通过Web界面修改密码的请求。我们一步步来看。2.1 漏洞触发点old参数的命令注入在正常的密码修改流程中用户需要提交旧密码old、新密码new1和new2等参数。password_change.cgi会调用系统的passwd命令来验证旧密码并设置新密码。问题出在它验证旧密码的方式上。在受影响版本的代码中大致逻辑程序可能会尝试使用类似echo “$old” | passwd …这样的方式或通过Perl的open函数调用外部命令来验证旧密码。关键在于$old这个变量即用户输入的旧密码在拼接进系统命令字符串之前没有经过严格的过滤或转义。攻击者正是利用了这一点。他不需要知道真正的旧密码而是在old参数中注入系统命令。例如他可能提交这样的请求oldmyoldpassword; id; #当这个值被拼接到命令中时可能形成echo “myoldpassword; id; #” | passwd …在Unix/Linux的Shell中分号;用于分隔命令井号#用于注释后续内容。因此实际执行的命令就变成了echo “myoldpassword这部分被忽略或出错但无关紧要id执行了id命令返回当前用户信息#” | passwd …后面全部被注释掉不再执行于是攻击者注入的id命令就被成功执行了。他可以将id替换成任何其他命令如wget下载木马、curl反弹Shell、cat /etc/shadow读取密码哈希等等。注意以上是一个高度简化的原理性示例。实际漏洞利用链涉及Webmin对old参数的处理直接传递给了Perl的open()函数并且该函数在特定模式下如|-会以Shell方式执行命令从而导致了注入。其核心本质就是“未过滤的用户输入进入了命令执行上下文”。2.2 影响版本范围与利用条件这个漏洞并非影响所有Webmin版本准确的范围是Webmin 1.900 至 1.920版本。并且需要安装并启用了“Password Change”模块默认安装。这里有一个关键点利用无需认证。漏洞存在于密码更改功能页面的未授权访问接口上。攻击者直接访问/password_change.cgi这个URL即可发起攻击完全不需要登录账号。这使得漏洞的危险等级极高。2.3 与近期热词的关联思考在分析这个老漏洞时我也注意到近期安全社区的热点比如各种“漏洞复现”、“文件上传漏洞绕过”、“未授权访问漏洞”等。CVE-2019-15107可以说是这些漏洞类型的一个经典融合体它本质上是一个“命令注入漏洞”是输入验证不严的典型后果。它具备“未授权访问”特性大大降低了利用门槛。它的利用过程可以被“复现”用于安全研究或检测。防御思路也与修复其他漏洞相通及时更新、最小化攻击面、加强输入校验。理解了这个漏洞你就能举一反三更好地理解其他类似原理的安全问题。3. 漏洞检测与验证实战指南知道原理后我们需要一套方法来确认自己的系统是否暴露在风险之下。检测分为两步第一步是初步识别和自查第二步是安全地验证此步骤需在授权和隔离环境进行。3.1 自查识别潜在风险系统首先你需要盘点资产。在你的网络环境中哪些服务器可能安装了Webmin检查Webmin服务是否运行在服务器上执行ps aux | grep webmin或netstat -tlnp | grep 10000Webmin默认端口是10000。如果发现相关进程或端口监听说明Webmin正在运行。确定Webmin版本登录Webmin面板如果已知凭证在首页或“Webmin”配置模块中查看版本号。更直接的方式是访问https://your-server-ip:10000/查看登录页面的底部或标题有时会显示版本信息。使用资产扫描工具对于大型网络可以使用Nessus、OpenVAS、Nexpose等专业漏洞扫描器或使用Nmap脚本进行批量检测。一个简单的Nmap命令可以探测Webminnmap -sV -p 10000 --script http-title,http-headers target-ip从返回的HTTP头或页面标题中有时可以推断出软件和版本。如果你的Webmin版本在1.900到1.920之间那么它理论上存在漏洞。但理论存在不等于实际可利用还需要验证漏洞接口是否暴露。3.2 验证安全环境下的漏洞复现仅供授权测试郑重警告以下验证方法仅允许在你拥有完全所有权和测试权限的隔离环境如虚拟机、测试服务器中进行。严禁对任何非授权目标进行测试这是违法行为。验证的目的是确认漏洞是否真实可利用。我们使用最直接的HTTP请求进行检测。方法一使用cURL命令探测一个常见的检测请求是尝试执行一个无害的命令如sleep通过观察响应时间来判断。curl -k -X POST https://目标IP:10000/password_change.cgi \ -d “userrootpamexpired2oldid|sleep 5new1testnew2test”-k: 忽略SSL证书验证因为测试环境常使用自签名证书。-X POST: 指定POST方法。-d: 提交表单数据。注意old参数的值是id|sleep 5。这里使用了管道符|是另一种命令注入方式意思是先执行id然后执行sleep 5。如果服务器响应明显延迟了5秒以上则强烈表明漏洞存在且可被利用。方法二使用Metasploit框架验证Metasploit提供了专业的验证模块能更准确地判断。msf6 use exploit/linux/http/webmin_password_change_cgi_bof msf6 exploit(webmin_password_change_cgi_bof) set RHOSTS 目标IP msf6 exploit(webmin_password_change_cgi_bof) set SSL true msf6 exploit(webmin_password_change_cgi_bof) set RPORT 10000 msf6 exploit(webmin_password_change_cgi_bof) check执行check命令Metasploit会发送一个安全的检测载荷通常是一个不造成实际影响的命令并返回The target is vulnerable.或The target is not vulnerable.的结果。这是相对安全可靠的验证方式。方法三查看源代码终极确认如果你有服务器文件系统的访问权限最确凿的方式是直接检查password_change.cgi文件。找到Webmin的安装目录通常是/usr/share/webmin或/etc/webmin查看/password_change.cgi这个文件的修改日期和内容。与官方发布的补丁进行对比可以明确知道是否已修复。实操心得在实际应急响应中我通常采用“Nmap资产发现 - 版本比对 - cURL无害探测”的组合拳。对于大量服务器编写一个简单的Python脚本使用requests库批量、安全地发送sleep 2探测请求能快速定位全网的风险点。切记探测脚本一定要设置超时时间并且使用sleep这种无害命令避免对业务造成影响。4. 漏洞修复方案全解析从紧急止血到彻底根除检测到漏洞后必须立即采取行动。修复不是简单的一步而是一个从临时缓解到永久解决的过程。4.1 方案一立即升级首选且最根本的方案这是修复任何已知漏洞最推荐、最彻底的方法。Webmin官方早已发布了修复版本。确定升级路径如果你当前版本是1.900-1.920需要升级到1.930 或更高版本。官方在1.930版本中彻底修复了此漏洞。建议直接升级到最新稳定版以同时修复其他可能存在的安全问题。升级操作步骤通过Webmin界面升级如果面板仍可安全访问 登录Webmin - 访问 “Webmin” - “Webmin Configuration” - “Upgrade Webmin”。选择“From uploaded file”或“From ftp or http URL”上传或指定新版安装包进行升级。通过命令行升级更通用 Webmin通常提供自动升级脚本。以root身份执行# 下载最新安装包请从官网获取最新链接 wget https://prdownloads.sourceforge.net/webadmin/webmin-2.xxx.tar.gz # 解压 tar -xzf webmin-2.xxx.tar.gz # 进入目录并执行安装脚本 cd webmin-2.xxx ./setup.sh /usr/share/webmin安装脚本会提示你确认一些配置通常保持默认即可。它会自动处理升级过程。升级后必须做的检查重启Webmin服务systemctl restart webmin或/etc/webmin/restart。再次登录面板确认版本号已更新。强烈建议使用上一节的检测方法在测试环境对升级后的服务进行验证确认漏洞已不可利用。4.2 方案二手动打补丁适用于无法立即升级的特殊情况在某些极端情况下服务器可能因为依赖问题暂时无法升级整个Webmin。这时可以考虑手动应用补丁。这只是一个临时缓解措施最终仍需安排升级。补丁的核心是修复password_change.cgi文件中对old参数的处理逻辑对其进行严格的过滤或转义。你需要找到这个文件如/usr/share/webmin/password_change.cgi并修改其代码。由于涉及Perl代码修改且不同小版本间代码可能有差异手动打补丁存在风险可能引入错误或导致功能失效。更安全的方法是直接从官方修复版本1.930中提取干净的password_change.cgi文件替换掉有漏洞的文件。操作步骤高风险请备份原文件# 1. 备份原文件 cp /usr/share/webmin/password_change.cgi /usr/share/webmin/password_change.cgi.bak # 2. 从官方包中提取或下载已修复的文件确保版本对应 # 例如下载1.930版本的该文件 wget -O /tmp/password_change.cgi.fixed https://raw.githubusercontent.com/webmin/webmin/v1.930/password_change.cgi # 3. 替换文件 cp /tmp/password_change.cgi.fixed /usr/share/webmin/password_change.cgi # 4. 修改文件权限保持与原文件一致 chmod 755 /usr/share/webmin/password_change.cgi chown root:root /usr/share/webmin/password_change.cgi # 5. 重启Webmin服务 systemctl restart webmin注意事项手动替换文件后务必进行全面的功能测试特别是密码修改功能确保其正常工作。同时要意识到这只能修复CVE-2019-15107这一处漏洞Webmin的其他模块可能还存在其他未修复的问题。因此这只能是权宜之计。4.3 方案三网络层访问控制临时隔离与加固在准备升级或打补丁的窗口期必须立即实施网络层隔离防止被攻击。修改默认端口将Webmin的默认10000端口改为一个非标准的高位端口。编辑Webmin配置文件通常是/etc/webmin/miniserv.conf修改port和listen项然后重启服务。这能阻挡一部分广撒网式的自动化扫描。配置防火墙严格限制源IP这是最有效的临时防护措施。只允许特定的、可信的管理IP地址访问Webmin端口。使用iptablesCentOS/RHEL 7等:iptables -A INPUT -p tcp --dport 10000 -s 你的管理IP1 -j ACCEPT iptables -A INPUT -p tcp --dport 10000 -s 你的管理IP2 -j ACCEPT iptables -A INPUT -p tcp --dport 10000 -j DROP使用firewalldCentOS/RHEL 8等:firewall-cmd --permanent --add-rich-rule“rule family“ipv4” source address“你的管理IP1” port protocol“tcp” port“10000” accept” firewall-cmd --permanent --add-rich-rule“rule family“ipv4” source address“你的管理IP2” port protocol“tcp” port“10000” accept” firewall-cmd --reload云服务器安全组如果你使用的是阿里云、腾讯云等云服务器务必在安全组规则中设置仅放行特定IP到10000端口。启用并强制使用HTTPS确保Webmin配置中SSL已启用并禁用HTTP访问。这可以防止流量被窃听虽然不能阻止漏洞利用本身但这是良好的安全实践。4.4 修复后的安全加固建议修复漏洞后工作并未结束。你需要借此机会对整个Webmin的使用进行安全加固。禁用不必要的模块Webmin功能繁多但你可能只用其中一小部分。进入“Webmin Configuration” - “Module Config”禁用所有你不需要的模块如“Password Change”如果你不需要用户自助改密。最小化功能等于最小化攻击面。使用强密码与双因素认证为Webmin的root账户或管理账户设置复杂、唯一的密码。强烈建议启用Webmin的双因素认证2FA插件即使密码泄露攻击者也无法登录。定期审计与更新将Webmin纳入你的漏洞管理和补丁更新流程。订阅Webmin的安全公告定期检查并更新到最新版本。考虑替代方案评估是否必须使用Webmin。对于熟练的管理员直接使用SSH和命令行管理可能是更安全的选择。或者可以考虑使用其他更活跃、安全性可能更好的管理面板如Cockpit更适合现代Linux发行版。5. 应急响应与事件排查流程如果怀疑或确认服务器已经因该漏洞被入侵你需要启动应急响应流程。这不仅仅是修复漏洞更是“抓坏人”和“打扫战场”。5.1 入侵迹象排查系统被攻破后攻击者通常会留下痕迹。你需要检查以下位置异常进程使用ps auxf或top命令查看是否有不认识的、消耗资源异常的进程。特别关注以root身份运行的陌生进程。异常网络连接使用netstat -antp或ss -antp查看是否有到可疑外网IP的未知连接。反弹Shell通常会保持一个长期的连接。可疑用户和授权检查/etc/passwd和/etc/shadow看是否有新增的陌生用户或UID为0root权限的非root用户。检查/root/.ssh/authorized_keys是否被添加了攻击者的公钥。计划任务检查/etc/crontab、/etc/cron.d/目录以及各用户的cron任务crontab -l -u root等看是否有添加恶意任务以实现持久化。最近修改的文件使用find命令查找近期被修改的系统关键文件如/bin、/sbin、/usr/bin下的二进制文件。find / -type f -name “*.sh” -o -name “*.py” -o -name “*.pl” -mtime -3 2/dev/null | head -20 find /etc -type f -mtime -2 2/dev/nullWebmin日志检查Webmin的访问日志和错误日志通常位于/var/webmin或/etc/webmin目录下。寻找在漏洞利用时间点附近对/password_change.cgi的异常POST请求特别是请求参数中带有管道符|、分号;、反引号等特殊字符的记录。5.2 事件处置步骤立即隔离如果可能将受影响的服务器从网络中断开拔网线或禁用网络接口防止攻击者继续控制或横向移动。取证备份在采取任何清理操作前先对系统内存使用LiME等工具、磁盘镜像以及关键的日志文件进行备份以备后续法律调查或深度分析。清除后门根据排查结果删除恶意用户、恶意计划任务、SSH后门密钥、以及植入的恶意程序文件。注意直接删除攻击者留下的文件可能触发其设置的“报警”机制。更安全的做法是先重命名或移动文件待系统恢复后再彻底删除。彻底重装最推荐对于生产环境一旦确认被root权限入侵最彻底、最安全的方法是备份数据后重装操作系统。因为你无法确定攻击者是否在系统内核、库文件或其他隐蔽位置植入了难以察觉的Rootkit。修复漏洞只是堵上了门而重装是换了一个干净的新房子。恢复与监控从干净的备份中恢复业务数据。将服务器重新上线后实施严格的网络监控和主机入侵检测HIDS如部署OSSEC、Wazuh等工具持续监控文件完整性、异常进程和网络行为。5.3 常见问题排查速查表问题现象可能原因排查与解决思路升级Webmin后服务无法启动1. 升级过程中配置文件冲突。2. Perl模块依赖不满足新版本。1. 检查/var/webmin/miniserv.error日志文件查看具体错误信息。2. 尝试回退配置文件使用备份的/etc/webmin目录覆盖或运行./setup.sh /usr/share/webmin重新配置。3. 使用perldoc -l检查关键Perl模块如Net::SSLeay是否安装。手动打补丁后密码修改功能失效替换的password_change.cgi文件版本不兼容或权限错误。1. 恢复备份的原文件确认功能是否正常。2. 确保替换文件的权限755和属主root:root正确。3. 从完全匹配的Webmin版本中重新提取文件进行替换。防火墙限制后自己也无法访问安全组或防火墙规则未正确添加自己的公网IP。1. 通过云控制台VNC或本地控制台登录服务器。2. 检查iptables/firewalld规则列表确认ACCEPT规则已生效且顺序在DROP之前。3. 临时添加一个允许所有IP的规则进行测试再逐步收紧。漏洞修复后扫描器仍报告风险1. 扫描器基于版本号判断缓存未更新。2. 漏洞修复不彻底或存在其他相似路径。1. 手动使用本文的cURL或Metasploitcheck方法进行真实验证。2. 确保重启了Webmin服务。3. 检查Webmin目录下是否还有其他老版本的CGI文件副本。处理完一次安全事件尤其是像CVE-2019-15107这种高危害漏洞最好的总结就是完善你的安全运维清单资产清点是否包含了所有管理后台补丁更新流程是否覆盖了这类非OS自带的第三方应用网络边界策略是否遵循了最小权限原则每一次应急响应都应该是推动整体安全水位提升的一次机会。