【vulhub实战】OpenSSH CVE-2018-15473漏洞复现与防护策略
1. 从一次“意外”登录说起:为什么这个SSH漏洞值得警惕
那天下午,我正在测试一个内部开发环境,像往常一样用SSH连接服务器。输入密码,敲下回车,一切如常。但就在我准备切出去干点别的时,终端里突然弹出了一行我之前没太留意的日志信息。这行信息本身没什么,但它让我心里“咯噔”了一下。因为我突然意识到,在我输入错误密码的那个瞬间,服务器的反应和输入一个根本不存在的用户名时的反应,似乎有那么一点微妙的差别。这个差别极其短暂,几乎无法被人类感知,但对于一个自动化脚本来说,可能就是打开一扇门的钥匙。
这个“微妙的差别”,正是我们今天要深入聊的 OpenSSH CVE-2018-15473 漏洞的核心。它不是什么能直接拿到服务器最高权限的“核弹”,而更像是一个精密的“探测仪”。攻击者利用它,可以在不进行完整身份认证的情况下,悄悄地、一个接一个地探测出你的服务器上哪些用户名是真实存在的。别小看这一步,在安全攻防里,知道“谁在系统里”是发起精准攻击的第一步。想象一下,黑客如果知道了你系统里存在“admin”、“root”、“oracle”、“jenkins”这些高权限账户名,后续的密码爆破、社会工程学攻击是不是就更有针对性了?
我自己在甲方做安全评估和后来研究漏洞复现时,遇到过不少因为默认配置或老旧系统遗留的“幽灵账户”。这些账户可能连运维自己都忘了,但它们的存在就是风险。CVE-2018-15473这个漏洞,恰恰是把这份“用户名单”拱手送人的一种方式。所以,无论你是运维工程师、安全研究员,还是对网络安全感兴趣的开发者,理解这个漏洞的原理、亲手复现一遍、并知道如何堵上这个口子,都是一项非常实用且必要的技能。
接下来的内容,我会带你用最流行的漏洞靶场环境 Vulhub,从零开始,完整地走一遍漏洞复现的流程。我们会搭建环境、分析原理、使用两种不同的工具进行利用,最后再聊聊真正有效的防护策略。我保证,整个过程会像搭积木一样清晰,哪怕你之前没怎么接触过漏洞复现,也能跟着一步步做下来。咱们不搞那些云里雾里的理论,就讲实战中能遇到的情况和解决方案。
2. 实验环境搭建:用Vulhub快速“复刻”漏洞现场
说到漏洞学习和研究,最头疼的就是环境问题。你总不能为了测试一个漏洞,真的去搞垮一台生产服务器吧?这时候,Vulhub 就成了我们的“神器”。它就像一个漏洞主题乐园,把历史上各种著名的漏洞环境,用 Docker 容器的方式打包好了,我们只需要几条命令就能一键启动一个包含特定漏洞的、完全隔离的测试系统。这对于学习和演示来说,安全又方便。
2.1 前期准备:确保你的“工具箱”齐全
在开始之前,我们需要确保电脑上已经安装好了必要的软件。这里假设你使用的是 Linux 系统(比如 Ubuntu、Kali 等),或者 macOS。Windows 用户可以通过 WSL2 获得几乎相同的体验。
首先,是 Docker 和 Docker Compose。Vulhub 完全依赖于它们来创建和管理漏洞环境。你可以通过下面的命令来检查是否已经安装:
docker --version
docker-compose --version
如果系统提示“command not found”,那就需要先安装它们。在 Ubuntu 上,安装命令通常如下:
sudo apt update
sudo apt install docker.io docker-compose -y
安装完成后,记得将当前用户添加到 docker 组,这样以后就不用每次都加 sudo 了:
sudo usermod -aG docker $USER
重要提示:执行完上面这行命令后,你需要完全退出当前终端会话,并重新登录,这个分组变更才会生效。不然你会一直遇到权限错误,这是我刚开始用 Docker 时踩过的一个小坑。
接下来,获取 Vulhub 的漏洞环境代码。它托管在 GitHub 上,我们直接克隆下来:
git clone https://github.com/vulhub/vulhub.git
cd vulhub
这个仓库有点大,因为它包含了上百个漏洞环境,第一次克隆可能需要一点时间。下载完成后,你会看到一个结构清晰的目录,每个子目录对应一个漏洞,比如 openssh/CVE-2018-15473 就是我们今天的目标。
2.2 启动靶场:让漏洞“活”起来
环境代码准备好后,启动靶场就非常简单了。我们直接进入目标漏洞的目录:
cd openssh/CVE-2018-15473
这个目录里通常只有一个 docker-compose.yml 文件,它定义了如何构建和运行这个特定的漏洞容器。在启动之前,确保 Docker 服务正在运行:
sudo systemctl start docker # 如果Docker服务未运行
然后,使用 Docker Compose 在后台启动这个漏洞环境:
sudo docker-compose up -d
看到 Creating network...、Creating container... 和 Started 之类的提示,就说明启动成功了。这里 -d 参数代表“detached”,即让容器在后台运行,这样我们就能继续使用当前的终端窗口。
怎么确认我们的漏洞靶场真的跑起来了呢?用这个命令查看容器状态:
sudo docker ps
你应该能看到一个名为 vulhub-openssh-cve-2018-15473 或类似的容器,状态是 “Up”。同时,注意看 PORTS 那一列,它会显示类似 0.0.0.0:20022->22/tcp 的信息。这表示容器内部的 SSH 服务(端口22)已经被映射到了我们宿主机的 20022 端口。这意味着,我们接下来要连接的不是容器的IP,而是本机的 127.0.0.1:20022。
2.3 首次连接:验证环境可用性
在开始漏洞利用前,我们先正常连接一次,确保 SSH 服务是好的,也了解一下靶场的默认账户。根据 Vulhub 这个环境的配置,它通常预设了一个用户 root,密码是 vulhub。我们连接试试:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@127.0.0.1 -p 20022
这条命令有几个小技巧:
-o StrictHostKeyChecking=no:连接时跳过“是否信任此主机密钥”的提示。在测试环境频繁重建容器时非常有用,避免一直手动确认。-o UserKnownHostsFile=/dev/null:将已知主机信息写入/dev/null(一个黑洞设备),相当于不保存本次连接的主机密钥。这也是为了测试环境干净。-p 20022:指定连接端口为我们映射的 20022。
输入密码 vulhub 后,你应该能成功登录到容器内部,看到类似 root@xxxxxxxxxxxx:~# 的提示符。输入 exit 即可退出。这一步验证了环境是完好的,也为后面的漏洞利用提供了一个已知的正确用户名和密码作为参照。
3. 漏洞原理深潜:SSH协议中的“指纹”泄露
环境跑起来了,但我们不能只做个“脚本小子”,知其然更要知其所以然。这个漏洞到底是怎么发生的?为什么能从错误信息里“猜”出用户名?这需要深入到 SSH 协议认证流程的细节里去看。
OpenSSH 支持多种认证方式,最常见的是密码认证(password)和公钥认证(publickey)。在一次完整的 SSH 连接建立过程中,客户端和服务器会协商加密算法、交换密钥,然后进入“用户认证”阶段。服务器会告诉客户端它支持哪些认证方式,比如 publickey,password。
关键点来了:在 OpenSSH 7.7 版本之前,当客户端发起认证请求时,整个认证流程的“步调”存在一个差异。具体来说,如果客户端发送了一个认证请求,声称要使用某种认证方法(比如密码认证),但提供的用户名根本不存在,那么服务器会在处理认证请求的早期就直接返回失败。而如果用户名是存在的,服务器则会继续处理这个认证请求,去校验密码或其他凭证,在更晚的步骤才会因为密码错误而返回失败。
这两种失败,最终返回给客户端的错误信息可能看起来一样(都是认证失败),但服务器内部处理它们所花费的时间、产生的数据包序列,或者在某些调试日志层面,是可能存在细微差别的。CVE-2018-15473 利用的,就是这种因用户名有效性检查发生时机不同而导致的侧信道信息泄露。
你可以把它想象成一个智能门锁。错误情况A:你拿一张完全不对的卡(无效用户)去刷,门锁立刻亮红灯并“滴”一声报错“卡无效”。错误情况B:你拿一张有效的门禁卡(有效用户)但密码按错了,门锁会先“滴”一声读卡,停顿一下验证密码,然后再亮红灯报错“密码错误”。虽然结果都是没开门,但一个有经验的“试探者”通过听“滴”声后的停顿长短,就能判断出你手里的卡是不是这个楼里的有效卡。
在 OpenSSH 7.7 及之后版本中,这个流程被修改了。无论用户名是否存在,服务器都会在认证流程的同一阶段返回失败,从而消除了这个可被探测的差异,修复了这个漏洞。所以,这个漏洞的影响范围是 OpenSSH 7.7 之前的所有版本。虽然现在新系统默认都用了更高版本,但在很多企业的遗留系统、嵌入式设备或长期未升级的服务器上,这个漏洞依然可能存在。
4. 实战利用(一):使用专用EXP脚本进行用户名枚举
理解了原理,我们开始动手利用。第一种方法,是使用安全研究员为这个漏洞专门编写的利用脚本(EXP)。这类脚本通常能更精准地触发漏洞特征,实现用户名的枚举。
4.1 获取与准备EXP脚本
GitHub 上有一个比较流行的利用脚本,我们把它下载下来:
git clone https://github.com/Rhynorater/CVE-2018-15473-Exploit.git
cd CVE-2018-15473-Exploit
这个仓库里主要是一个 Python 3 脚本 sshUsernameEnumExploit.py。用文本编辑器打开它简单看一下,你会发现它的逻辑就是利用我们前面说的原理,向目标 SSH 服务器发送一系列认证请求,然后根据响应的差异(比如特定的错误代码或数据包长度)来判断用户名是否存在。
脚本自带了一个很小的用户名字典 exampleInput.txt,里面只有几个常见的测试用户名,如 root, admin, test。这显然不够。在实际渗透测试中,我们需要一个更全面的字典。一个非常直接的来源就是 Linux 系统本身的用户列表 —— /etc/passwd 文件。虽然靶场容器里的用户不多,但我们可以模拟一个从其他渠道获取的、更丰富的用户列表。
我们在攻击机(也就是我们的宿主机)上创建一个新的字典文件,并加入一些常见用户名:
# 创建一个新的字典文件
cat > my_userlist.txt << EOF
root
admin
administrator
test
guest
ubuntu
debian
ftp
mysql
oracle
jenkins
git
www-data
nobody
EOF
4.2 运行脚本并解读结果
现在,运行利用脚本,指定我们的目标端口和用户字典:
python3 sshUsernameEnumExploit.py --port 20022 --userList my_userlist.txt 127.0.0.1
运行后,脚本会开始逐个尝试字典里的用户名。你可能会看到类似下面的输出:
[+] 127.0.0.1:20022 - Valid user: root
[-] 127.0.0.1:20022 - Invalid user: admin
[-] 127.0.0.1:20022 - Invalid user: administrator
[+] 127.0.0.1:20022 - Valid user: test
...
看到 Valid user: root 了吗?这说明脚本成功地利用漏洞特征,判断出 root 是目标系统上的有效用户。而 admin 则被判定为无效。请注意:这个脚本在不同环境下可能因为网络延迟、OpenSSH 小版本差异等原因,稳定性有所不同。有时你可能会遇到误报或漏报,或者脚本直接报错退出。这正是实战中会遇到的情况——没有哪个EXP是百分百通用的。
如果脚本运行不顺利,别着急,这很正常。我们可以换用另一种更通用、更“暴力”但也更可靠的工具,它不仅能利用这个漏洞进行用户枚举,还能直接进行密码爆破。
5. 实战利用(二):使用Hydra进行组合攻击
当专用EXP因为环境兼容性问题不好用时,Hydra 这个老牌的网络登录破解工具往往能派上大用场。Hydra 支持数十种协议,SSH 是其中之一。更重要的是,在针对某些版本的 OpenSSH 进行攻击时,Hydra 的某些模式会触发与 CVE-2018-15473 类似的行为,从而在爆破密码的同时,也暴露出用户名的有效性信息。
5.1 Hydra 的基本用法与参数解析
首先,确保你的系统安装了 Hydra。在 Kali Linux 中它是预装的,Ubuntu 可以通过 sudo apt install hydra 安装。
Hydra 的命令参数看起来很多,但用于 SSH 爆破的核心参数就几个,我们来拆解一下:
hydra -l <用户名> -P <密码字典> <目标IP> ssh -s <端口> -v -t <线程数>
-l:指定单个用户名进行爆破。例如-l root。-L:指定一个用户名字典文件,进行批量用户爆破。-p:指定单个密码。-P:指定一个密码字典文件。-s:当服务运行在非默认端口时指定端口号(SSH默认是22)。-v/-V:详细模式,-V会显示每次尝试的详情。-t:指定并发线程数,提高速度,但太高可能被目标封禁或导致不稳定。
一个重要区别:如果我们使用 -l(小写L)指定一个已知有效的用户(比如我们之前确认的 root),那么 Hydra 就是在进行纯粹的密码爆破。但如果我们使用 -L(大写L)指定一个用户名字典,Hydra 在尝试每个用户的密码时,其行为模式可能会因为目标SSH版本存在漏洞,而间接地告诉我们哪些用户是存在的(通过尝试速度、错误响应的细微差别)。不过,Hydra 本身并不会像专用EXP那样明确输出“有效用户”列表,它的主要目的是破解密码。
5.2 构造密码字典与实施爆破
我们先从简单的密码爆破开始。我们已经知道有效用户是 root,现在需要准备一个密码字典。创建一个简单的文件:
echo -e "vulhub\npassword\n123456\nroot\nadmin\nletmein" > ssh_passwords.txt
然后,使用 Hydra 对 root 用户进行密码爆破:
hydra -l root -P ssh_passwords.txt -v -t 4 -s 20022 ssh://127.0.0.1
运行后,Hydra 会开始尝试。当尝试到正确的密码 vulhub 时,你会看到非常清晰的成功提示:
[20022][ssh] host: 127.0.0.1 login: root password: vulhub
[STATUS] attack finished for 127.0.0.1 (valid pair found)
这就证明了密码爆破是成功的。那么,如何结合用户名枚举呢?我们可以尝试使用 -L 参数,并准备一个更大的用户名字典。同时,为了观察差异,我们可以使用一个很小的、几乎肯定不对的密码字典(或者就用一个错误密码),然后观察 Hydra 对不同用户名的尝试速度或响应。在某些存在漏洞的版本上,对于有效用户名的尝试,可能会比无效用户名花费稍长的时间(因为服务器多走了一步密码校验流程),有经验的操作者可以通过时间差来推断。
不过,更常见的实战场景是:先通过其他信息收集手段(比如网站邮箱、文档泄露等)整理出一个可能的用户名单,然后用这个名单配合一个较大的通用密码字典,进行“用户名-密码”组合爆破。这时,CVE-2018-15473 漏洞的存在,会让这种爆破攻击在第一步——验证用户名有效性上,变得更加高效和隐蔽。
6. 漏洞修复与防护策略:不只是升级那么简单
复现漏洞是为了更好地防御。现在我们已经清楚了攻击者是如何利用这个漏洞的,那么该如何保护我们的服务器呢?很多人第一反应是“升级到最新版OpenSSH”,这当然是最根本、最有效的办法。但现实中的系统维护往往更复杂,我们还需要一些立即可行的缓解措施和深度防御思路。
6.1 根本性修复:升级OpenSSH版本
对于任何受此漏洞影响的系统,最直接的措施就是将 OpenSSH 升级到 7.7 或更高版本。你可以使用系统包管理器来操作:
- Ubuntu/Debian:
sudo apt update sudo apt upgrade openssh-server - CentOS/RHEL:
sudo yum update openssh-server
升级后,务必重启 SSH 服务以使新版本生效:sudo systemctl restart sshd。然后,可以尝试用之前的 EXP 脚本再次测试,应该会发现它无法再枚举出有效用户名了。
6.2 网络层防护:限制与监控
升级并非总是能立即进行(比如某些关键业务系统需要漫长的变更窗口)。在这种情况下,网络层的防护就是第二道重要防线。
-
限制访问源:在防火墙或 SSH 服务器的配置中,严格限制允许连接 SSH 的 IP 地址范围。只允许运维人员所在的办公网 IP 或跳板机 IP 访问服务器的 22 端口。这能极大缩小攻击面。
- 修改
/etc/hosts.allow和/etc/hosts.deny,或直接配置 iptables/firewalld。
- 修改
-
修改默认端口:将 SSH 服务从默认的 22 端口改到一个高位端口(如 23456)。这并不能防止定向攻击,但可以显著减少互联网上自动化扫描脚本的骚扰。
-
部署入侵检测系统:在网络边界或服务器上部署 IDS/IPS(如 Suricata, Snort),并配置规则来检测针对 SSH 服务的暴力破解和异常连接行为。例如,短时间内来自同一 IP 的大量 SSH 认证失败请求,就是一个非常明显的攻击信号。
6.3 服务层加固:SSH配置优化
即使升级了版本,良好的 SSH 配置习惯也能进一步提升安全性。
-
禁止密码登录,使用密钥认证:这是我最推荐、也是实践下来最有效的一招。彻底关闭密码认证,强制所有用户使用 SSH 密钥对登录。私钥的强度远高于任何密码。
- 编辑
/etc/ssh/sshd_config,设置:PasswordAuthentication no PubkeyAuthentication yes
然后重启
sshd服务。这样,即使攻击者枚举出了用户名,也无法进行密码爆破。 - 编辑
-
使用强密码策略:如果业务上必须保留密码登录,那么必须为所有账户设置高强度、无规律的密码,并定期更换。避免使用默认密码、常见单词、与用户名相关的密码。
-
禁用无关用户:定期审计系统账户,禁用或删除那些不再使用的用户账号(比如测试账号、默认安装创建的非必要账号)。减少有效用户的数量,就从源头上减少了被枚举出的风险。
-
使用Fail2ban:这是一个非常实用的工具,它能监控系统日志(如
/var/log/auth.log),当发现某个 IP 在短时间内有多次失败的 SSH 登录尝试时,自动将其 IP 加入防火墙黑名单一段时间。- 安装:
sudo apt install fail2ban - 它开箱即用,对防御 SSH 暴力破解有奇效。
- 安装:
6.4 主动防御与安全意识
最后,再分享两点更深层的体会。一是监控与告警:一定要建立对 SSH 登录日志的集中监控和异常告警。任何非正常时间、非信任IP的成功登录,都应该立即触发告警通知管理员。二是安全意识:再好的技术措施也抵不过人为疏忽。确保团队成员都理解使用弱密码的风险,保管好自己的 SSH 私钥,不把密钥留在共享目录或未经加密的存储中。
漏洞复现的练习结束后,别忘了清理现场,关闭并移除 Vulhub 启动的 Docker 容器,释放资源:
cd vulhub/openssh/CVE-2018-15473
sudo docker-compose down
这个简单的命令会停止并删除本次实验创建的所有容器和网络,非常方便。保持实验环境的整洁,是个好习惯。
更多推荐
所有评论(0)