SSH渗透测试实战:从密钥利用到隧道穿透的完整攻防解析

发布时间:2026/7/4 16:38:09

SSH渗透测试实战:从密钥利用到隧道穿透的完整攻防解析 1. 项目概述从靶机到实战SSH服务为何是渗透测试的“必争之地”在网络安全竞赛和实战渗透测试中SSH服务几乎是一个绕不开的“老朋友”。无论是DC系列靶机、VulnHub上的经典环境还是企业内网的真实资产22号端口背后运行的SSH守护进程常常是攻击者获取初始立足点、建立持久化通道的关键跳板。我见过太多新手在CTF里对着SSH登录框一筹莫展也处理过不少因为SSH配置不当导致整个内网沦陷的真实案例。这个协议设计之初是为了安全但配置的复杂性和历史的“惯性”让它成了安全与风险并存的矛盾体。简单来说一次针对SSH服务的渗透测试远不止是“爆破密码”那么简单。它是一场从信息搜集、漏洞利用、权限提升到横向移动的完整战役。你需要理解SSH的认证机制密码、密钥、甚至多因素熟悉服务端和客户端的各种配置参数掌握在受限环境下利用SSH进行隧道穿透的技巧。本次分享我将以一个虚拟的、但高度贴近实战的CTF靶场环境为背景拆解SSH渗透测试的全流程。无论你是正在刷题准备比赛还是希望夯实内网渗透的基础这篇从踩坑中总结出的经验都能帮你构建一套清晰、可复现的攻击思路。我们会从最基础的端口扫描和横幅信息抓取开始一步步深入到密钥利用、配置错误滥用和隧道技术最后分享几个让我记忆深刻的“翻车”案例和排查技巧。2. SSH服务渗透测试的核心思路与攻击面分析进行SSH渗透首先得知道从哪里下手。盲目爆破是最低效的方法。一个成熟的测试者会像侦探一样先勾勒出目标的“肖像”。2.1 信息搜集不止于22端口很多人一提到SSH就是nmap -p 22这远远不够。首先SSH服务可能运行在非标准端口上。在高强度对抗的CTF或真实环境中管理员修改默认端口是基本操作。因此全面的端口扫描是第一步。我习惯使用nmap的-p-参数进行全端口扫描或者针对性地扫描高位端口如2222, 22222, 2022等。# 全面扫描识别所有开放端口 nmap -sS -p- -T4 --min-rate1000 target_ip # 针对扫描到的开放端口进行服务和版本探测 nmap -sV -sC -p discovered_ports target_ip其次获取SSH服务的横幅Banner信息至关重要。这条信息会暴露SSH服务器的软件类型和版本号。例如SSH-2.0-OpenSSH_7.9p1。这个版本号是后续漏洞利用的基石。老版本的OpenSSH可能存在已知的漏洞比如CVE-2018-15483用户名枚举、CVE-2020-14145信息泄露等。即使版本较新特定的发行版如Ubuntu、CentOS打的补丁不同也可能存在配置差异。注意有些CTF靶机会故意在横幅中隐藏或修改版本信息或者植入“彩蛋”。不要完全依赖自动化工具的输出手动用nc或telnet连接一下22端口亲眼看看返回的原始信息有时会有意外发现。echo “” | nc -nv target_ip 222.2 四大核心攻击面剖析基于信息搜集的结果我们可以将SSH服务的攻击面归纳为四大类这构成了我们后续测试的路线图。1. 弱口令与暴力破解这是最直接但也最“笨”的方法。成功率取决于字典质量和目标策略。关键在于“智能”而非“蛮力”。首先尝试常见默认凭证如root:root,admin:admin,user:user以及目标业务相关的用户名如靶机名、公司名缩写。如果靶机是基于某个CMS或框架如WordPress可以尝试从Web界面收集可能的用户名。工具方面hydra、medusa和patator是主流选择。但必须注意速率限制和账户锁定策略在CTF中可能宽松在真实测试中必须获得授权并谨慎操作。2. SSH密钥相关漏洞这是本次分享的重点也是高手与新手的分水岭。主要涉及私钥泄露在靶机Web目录、备份文件如.bak,.old、版本控制.git目录甚至其他已沦陷的主机上可能找到SSH私钥文件通常是id_rsa。拿到后需注意权限chmod 600 id_rsa并尝试用ssh -i登录。如果私钥被加密则需要破解其密码。授权密钥文件authorized_keys滥用如果发现你可以写入目标用户的~/.ssh/authorized_keys文件例如通过Web文件上传漏洞、配置错误的NFS共享等就可以直接植入你自己的公钥实现免密登录。主机密钥Host Key欺骗在中间人攻击MITM场景下可能用到但在CTF中较少见。3. 服务端配置错误OpenSSH服务器的配置文件/etc/ssh/sshd_config是宝藏也是雷区。管理员配置不当会打开致命缺口允许root登录PermitRootLogin yes。这给了攻击者直接夺取最高权限的机会。密码认证过于宽松PasswordAuthentication yes且没有强密码策略。启用不安全的认证方式如RSAAuthentication yes已过时的SSHv1 RSA认证或RhostsRSAAuthentication。匹配块Match Block配置错误可能意外地为某些用户或组开启了额外的权限。AllowUsers/DenyUsers列表错误可能意外允许了未授权的用户。4. 客户端配置利用与隧道攻击当我们通过某种方式如Web漏洞在目标服务器上获得了命令执行权限RCE但非交互式shell时可以利用SSH客户端配置建立反向连接或隧道。SSH反向代理与端口转发这是内网穿透的核心技术。通过将内网端口转发到攻击机实现访问内网服务。利用ssh -o参数执行命令在某些严格受限、但允许执行ssh命令的环境中可以通过ssh -o ProxyCommand等参数来执行任意命令有时能绕过限制。SSH Config (~/.ssh/config) 利用如果可控用户目录下的SSH配置文件可以注入恶意配置例如在连接特定主机时执行命令。3. 实战演练一步步拆解SSH渗透链条理论说完我们进入实战环节。假设我们面对一个名为dc-lab的CTF靶机IP为192.168.1.100。我们的目标是获取root权限并找到所有flag。3.1 第一阶段侦察与初步接触首先进行端口扫描。我们发现除了80HTTP2222端口也开放着SSH服务。nmap -sV -sC -p 22,2222,80 192.168.1.100输出显示2222端口运行着SSH-2.0-OpenSSH_7.6p1而22端口关闭。同时80端口是一个简单的企业网站。通过目录扫描如gobuster网站我们发现了一个/backup/目录里面有一个压缩包website_backup.tar.gz。下载解压后在文件堆里找到了一个名为id_rsa_backup的文件——正是一个SSH私钥3.2 第二阶段私钥处理与登录尝试拿到私钥第一步不是直接登录而是先检查。# 1. 检查私钥格式和是否加密 file id_rsa_backup # 如果显示“PEM RSA private key”则是未加密或使用旧格式。如果显示“OpenSSH private key”可能是新格式。 # 2. 尝试直接使用注意修改权限 chmod 600 id_rsa_backup ssh -i id_rsa_backup -p 2222 user192.168.1.100如果提示需要密码“Enter passphrase for key ‘id_rsa_backup’:“说明私钥被加密了。我们需要破解这个密码。使用ssh2john将私钥转换为John the Ripper可识别的格式然后进行破解。# 使用ssh2john通常随John the Ripper安装 python3 /usr/share/john/ssh2john.py id_rsa_backup id_rsa.hash # 使用john破解rockyou.txt是常用字典 john --wordlist/usr/share/wordlists/rockyou.txt id_rsa.hash假设破解出密码是summer2021。现在我们可以登录了。但登录用户是谁私钥通常对应一个系统用户。我们需要枚举。常见的有www-data,apache,nginx,ubuntu,debian,user,admin,ctf以及从网站内容中可能推断出的用户名。我们可以写个简单脚本用sshpass配合私钥尝试或者更优雅地利用SSH的LogLevel VERBOSE来看错误信息但很多服务器会关闭详细日志。一个更直接的方法是先不管用户用-i指定密钥尝试连接服务器会返回认证失败信息有时会包含有效的用户名提示。或者使用hydra进行基于密钥的用户名枚举虽然效率较低。经过尝试我们发现用户名为developer。ssh -i id_rsa_backup -p 2222 developer192.168.1.100 # 输入破解出的密码summer2021成功我们获得了第一个立足点拿到了developer用户的shell。3.3 第三阶段权限提升与横向移动登录后立即开始信息收集。# 查看当前用户权限 id sudo -l # 查看可以以root身份运行哪些命令 # 查看敏感文件 cat /etc/passwd | grep -v “nologin” # 查看可登录用户 ls -la /home/ # 查看其他用户目录 find / -perm -4000 -type f 2/dev/null # 查找SUID文件假设sudo -l显示developer用户可以以root身份无密码运行/usr/bin/vim。那么权限提升就很简单了sudo vim -c ‘:! /bin/bash’ # 或者在vim内 :shell现在我们已经是root了。但CTF通常要求找到多个flag。可能在/root/目录下有一个在/home/下的其他用户目录也有。检查/home/发现还有用户backup和admin。检查backup用户的家目录发现一个有趣的脚本/home/backup/backup.sh内容是将/var/www/html备份到/home/backup/backups/并且这个脚本由backup用户定期执行cron job。更重要的是这个脚本对/home/backup/backups/目录有写权限且该目录设置了粘滞位不关键是我们作为root可以修改这个脚本。但我们也可以换个思路利用SSH密钥横向移动。作为root我们可以读取任何用户的私钥或向他们的authorized_keys写入公钥。# 1. 检查其他用户的.ssh目录 ls -la /home/backup/.ssh/ ls -la /home/admin/.ssh/ # 2. 如果存在authorized_keys我们可以直接追加我们的公钥 echo “ssh-rsa AAAAB3NzaC1yc2E... mykey” /home/backup/.ssh/authorized_keys # 3. 如果没有.ssh目录可以创建需注意目录权限必须是700文件是600 su - backup -c “mkdir -p ~/.ssh chmod 700 ~/.ssh” su - backup -c “echo ‘ssh-rsa AAAAB3NzaC1yc2E... mykey’ ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys”现在我们就可以从攻击机直接SSH到backup用户了。同理可以获取admin用户的权限。在每个用户的家目录下仔细搜索通常就能找到隐藏的flag文件如.flag.txt,flag.txt,user.txt,root.txt。3.4 第四阶段隧道技术穿透内网假设在admin用户的家目录下我们发现了一个笔记文件提到内部有一个管理面板运行在172.16.0.10:8080一个我们攻击机无法直接访问的内网地址。这时就需要用到SSH隧道。由于我们已经控制了developer用户或root可以建立动态SOCKS代理或本地/远程端口转发。方法一动态端口转发SOCKS代理在攻击机上执行ssh -i id_rsa_backup -p 2222 -D 1080 developer192.168.1.100这条命令在攻击机的1080端口建立了一个SOCKS5代理。随后我们可以配置浏览器或使用proxychains工具让流量通过这个代理访问内网。proxychains curl http://172.16.0.10:8080方法二本地端口转发如果只想访问特定的内网服务本地转发更直接。ssh -i id_rsa_backup -p 2222 -L 8080:172.16.0.10:8080 developer192.168.1.100这条命令将靶机192.168.1.100能访问到的内网172.16.0.10:8080服务映射到了攻击机本地的8080端口。现在在攻击机浏览器访问http://127.0.0.1:8080就等于在访问内网的管理面板。4. 高频问题排查与深度技巧实录在实际操作中绝不会一帆风顺。下面是我在无数次“连接失败”和“权限不足”中总结出的排查清单和进阶技巧。4.1 连接与认证失败排查表问题现象可能原因排查命令与解决思路Connection refused端口不对、服务未运行、防火墙阻断nc -zv IP PORT确认端口状态检查目标netstat -tlnp检查防火墙规则iptables -L/ufw status。Permission denied (publickey,password).用户名错误、密钥错误、密码错误、服务器禁用密码登录1. 确认用户名尝试常见用户或信息搜集所得。2. 检查密钥权限chmod 600。3. 检查sshd_configPasswordAuthentication no则只能密钥登录。4. 使用-v参数查看详细握手过程。Agent admitted failure to sign using the key.SSH Agent未加载密钥或密钥格式问题ssh-add ~/.ssh/id_rsa加载密钥或直接使用ssh -i指定密钥路径。Host key verification failed.已知主机记录known_hosts冲突删除~/.ssh/known_hosts中对应IP的记录或使用ssh -o StrictHostKeyCheckingno不安全仅测试用。登录后立即断开用户shell被设置为/bin/false或/sbin/nologin检查/etc/passwd中该用户的shell字段。即使登录也无法获得交互shell。需通过其他方式如ssh -T执行单条命令利用。可以连接但执行命令无回显可能处于受限shellrbash尝试逃逸技术ssh userhost ‘/bin/bash’或利用环境变量、编辑器等突破。4.2 私钥利用的“骚操作”从内存中提取私钥如果通过其他漏洞获得了root权限可以尝试从SSH进程内存中提取私钥。使用gcore或/proc/pid/mem需要高权限且复杂但更简单的是检查是否有ssh-agent在运行并用ssh-add -L列出已加载的公钥。利用ssh-keyscan进行信息搜集ssh-keyscan target_ip可以快速获取目标主机的公钥指纹用于验证主机身份或加入已知主机列表在批量测试时有用。批量化密钥测试当你有一堆密钥和一堆IP时可以用pssh或自己写循环脚本。for ip in $(cat ips.txt); do for key in $(cat keys.txt); do ssh -o ConnectTimeout5 -o BatchModeyes -i $key user$ip “whoami” echo “[] $ip with $key” success.txt done doneBatchModeyes会禁止交互式询问适合脚本。4.3 隧道搭建的稳定性与隐匿性保持长连接SSH隧道容易因为网络波动或超时而断开。使用autossh工具可以自动重连。autossh -M 0 -o “ServerAliveInterval 30” -o “ServerAliveCountMax 3” -i key -p 2222 -D 1080 userhost-M 0禁用监控端口ServerAliveInterval每30秒发送保活包。应对网络限制如果目标网络出站流量限制到22端口可以尝试将SSH服务端端口转发到443HTTPS或53DNS等常用端口以绕过基础防火墙策略。这需要在服务端有权限修改sshd_config并重启服务或通过iptables进行重定向。多层跳板在复杂内网可能需要多次转发。记住一个原则-L本地转发是“把远端的端口拿到本地来用”-R远程转发是“把本地的端口放到远端去用”。画个简单的数据流图能极大帮助理解。5. 防御视角从攻击中学习如何加固SSH服务作为渗透测试者理解攻击手段的最终目的是为了更好的防御。完成一次测试后我通常会从防御者角度给出以下加固建议这也是CTF出题人常常设置“考点”的地方。禁用密码登录强制使用密钥对在/etc/ssh/sshd_config中设置PasswordAuthentication no和ChallengeResponseAuthentication no。这是最有效的一步。使用强密码保护私钥即使使用了密钥也必须为私钥设置强密码短语passphrase防止私钥文件泄露即意味着沦陷。限制用户和IP使用AllowUsers或AllowGroups明确指定允许登录的用户。结合防火墙如iptables、ufw或TCP Wrappers/etc/hosts.allow,/etc/hosts.deny限制来源IP。修改默认端口将端口从22改为一个高位随机端口能减少大量自动化扫描和低水平攻击。使用Fail2ban部署Fail2ban监控SSH日志对多次认证失败的IP进行临时封禁。保持更新及时更新OpenSSH服务器软件修复已知漏洞。审查配置与日志定期检查sshd_config确保没有不必要的配置项如PermitRootLogin应为prohibit-password或no。监控/var/log/auth.log或/var/log/secure中的异常登录尝试。限制内部用户权限避免给普通用户不必要的sudo权限。定期审计SUID/GUID文件。渗透测试就像一场攻防博弈SSH服务是这场博弈中一个经典而持久的战场。从信息泄露的私钥到配置疏忽的sudo规则从简单的端口转发到复杂的内网穿透每一个环节都考验着测试者的细心和知识广度。我个人的体会是工具永远在变但协议原理和攻防思路是相通的。下次当你面对一个SSH服务时不妨先停下来花五分钟时间按照“信息搜集-攻击面分析-分层利用-权限维持”这个流程在脑子里过一遍你会发现很多看似困难的问题其实都有清晰的解决路径。最后一个小技巧建立一个属于你自己的“武器库”里面不仅要有nmap、hydra、john这些工具更要有一个分类清晰的笔记记录你遇到过的各种SSH配置片段、错误信息和解法。时间久了这就是你最宝贵的经验。

相关新闻