SSH劫持
SSH 是一个可以用于远程访问网络设备的网络协议,广泛运用于 Linux 主机,并且如今 SSH 在 Windows 主机上的使用也越来越广泛。对于我们网络安全人士,直观地概括就是 SSH 会话能给予我们完全交互式的 Shell。SSH 还可以与 FTP 服务集成,以加强文件安全性。因为 SSH 能访问主机的特性,也被一些集中式管理工具集成,以对受管理的主机进行命令执行、分发 IT 任务等,
SSH 不仅支持密码登陆,还支持密钥登陆。如果使用密钥认证的话,需要用户通过 ssh-keygen 命令先生成一对私钥与公钥。从 IT 管理员的角度来看,应当尽可能禁用密码认证,只允许密钥认证。尽管基于密钥的认证更加安全,但如果密钥相关的重要文件被窃取或者攥改了,也会导致主机被入侵。对于攻击者,这可以帮助我们实现横向移动。因为如今 Windows 也支持 SSH 服务,针对 SSH 的成功攻击不仅可以让我们入侵更多的 Linux 主机,也可以让我们拿下 Windows 主机以及实现对特权用户的模仿。
SSH 重要文件
id_rsa
id _rsa 是用户的 SSH 私钥,私钥文件应该被保护好,只有所有者用户才允许拥有读写权限。因为对于攻击者而言,这是最有吸引力的了,SSH 私钥可以授予我们访问任何信任该密钥的主机 (私钥配套的公钥在目标主机的 authorized_keys 中),在横向移动方面尤其有效。我们不仅可以在入侵了一台配置有 SSH 服务的主机后生成或搜集各个用户的 SSH 私钥以实现持久化访问,如果我们发现了可能是用于连接其他主机的私钥,那么我们便可以连接到其他主机。这在开发与生产环境是比较常见的,因为员工可能需要通过 SSH 连接到多台主机上作业,因此索性在用户目录下保存了多个主机的 SSH 私钥,这样的图省事带来的是多个主机一并被入侵。
默认情况下,私钥文件存储为 ~/.ssh/id_rsa 目录中,需要通过 ssh-keygen 命令生成或者覆盖现有的,用户还可以指定 Passphrase 来保护密钥,但对于贪图方便的用户,可能就一路回车跳过了这个环节。
而对于设置了 Passphrase 的私钥,在使用私钥进行认证的时候,我们需要输入私钥的 Passphrase 方可认证。我们可以对其进行离线字典破解恢复出 Passphrase。
使用 ssh2john 将私钥的 Passphrase 提取出来成哈希格式
再使用 john 来字典破解该哈希,得到 Passphrase 为 dev01。
id_rsa.pub 与 authorized_keys
id_rsa.pub 为 id_rsa 所对应的公钥,位置为 ~/.ssh/id_rsa.pub,可以自由分发。当用户尝试连接到远程系统时,系统使用此公钥加密质询消息,如果能成功使用私钥解密该消息,即证明用户拥有相应的私钥,那么将获得访问权限。
公钥认证,即将用户的公钥添加到目标主机的 authorized_keys 中。例如,用户 Alice 持有一 VPS,为了能实现免密码 SSH 登陆,Alice 将自己在个人用主机上的 SSH 公钥添加到 VPS 上一用户的 authorized_keys 中。如图所示,主机 ts 为我的个人 VPS,在该文件中有 3 个公钥,前 2 个为我其他个人主机。我将这些设备上的 SSH 公钥添加在这个文件中,就可以在这 2 个设备上以 root 身份访问 ts 了。
私钥认证,在 id_rsa 部分说过了,私钥以凭证的方式被用于向 SSH 服务器认证,带来的问题就是如果私钥被攻击者窃取了,那么私钥可以访问到的主机都会沦陷。如下图所示,我们看到在 dev01 上,dev01 用户的公钥也存在于 authorized_keys 中,这样的话,持有 dev01 私钥的用户,当然也包括了窃取了私钥的攻击者,可以通过私钥向 dev01 的 SSH 服务器认证。
回顾该图的上一张图,第 3 个公钥是 dev01 的,什么意思呢?我在 ts 上的 authorized_keys 中添加了 dev01 的公钥,那么持有 dev01 私钥的用户可以以 root 身份访问 ts 这台主机了。因此,私钥的窃取可能导致多台主机的沦陷,这取决于有多少台主机信任该密钥。
known_hosts
该文件通常位于客户端计算机上用户的 ~/.ssh/ 目录中,为客户端曾经连接过的所有远程主机保留主机密钥列表。 这用于验证您是否正在连接到您认为的服务器。 如果您尝试连接到服务器并且服务器的密钥与存储在您的 known_hosts 文件中的密钥不匹配,SSH 将警告您服务器的身份已更改,这可能表明存在中间人攻击。
对于设置了 passphrase 的 SSH 私钥,我们会在文件中发现 Proc-Type: 4,ENCRYPTED 的字样。我们可以使用 ssh2john 提取 passphrase:ssh2john id_rsa > passphrase.txt。然后使用 john 来破解:john --wordlist=rockyou.txt passphrase.txt。
我们来总结一下针对 SSH 密钥的枚举步骤:
1:搜索名为 id_rsa 的文件,当然,私钥可能会被改名,例如 alice.key。
2:检查私钥是否有 passphrase,如果有,尝试破解出 passphrase。
3:查看 authorized_keys,判断哪些用户/主机可以连接到该主机(后文提及利用手法)。从后利用角度,我们也可以将自己的 SSH 公钥添加到该文件末尾,实现持久化访问。
4:查看 known_hosts,配合命令记录判断该用户连接过哪些主机。known_hosts 中的内容可能被哈希过。
5:尝试连接其他主机
SSH 有一个特性叫 Control Master,可以通过单个网络连接共享多个会话。这意味着只要用户建立起第一个 SSH 会话,那么后续的 SSH 连接不再需要密码,从而实现尾随在第一个会话身后。一个常见的情景就是,主机 web02 上的用户正在通过 SSH 访问 web03,而我们已经入侵了 web03,我们可以尾随用户从而无须密码便能移动到 web03。
利用方式如下:
1:假设该主机已经开启 ControlMaster了,在 .ssh 文件夹中会存在 config文件,内容如下
Host *
ControlPath ~/.ssh/controlmaster/%r@%h:%p
ControlMaster auto
ControlPersist yes
List
2:进入 .ssh 文件夹下的 contromaster 子文件夹,我们会发现 socket 文件,文件名格式为 user@host:22。
3:这时候,我们通过命令 ssh user@host 无密码移动到当前用户所在的主机上。
即便当前用户尚未开启 ControlMaster,我们可以替他开启,这样在用户下次访问其他主机的时候,我们就能实现劫持。总结一下,我们在 A 主机上发现用户正在通过 SSH 访问 B 主机,我们可以劫持该会话,尾随在用户后面,无密码移动到主机 B。
除此之外,我们还可以通过 SSH 代理以及 SSH 代理转发实现横向移动。SSH 代理追踪了用户的密钥和 passphrase,因此在输入一次 passphrase 后,用户不再需要重复输入 passphrase,是一种 SSO 的实现。
情景以及利用手法如下:
受害用户从主机A 正在访问主机 B,而我们已经入侵了主机 B,试图移动到主机C。
1:主机 A 已经配置了 SSH代理,在主机 B 上也已经在 sshd_config 中配置了SSH 代理转发:AllowAgentForwarding yes。
2:受害用户的私钥被主机 C 所接受,但受害用户尚未连接主机 C
3:攻击者在主机 B 上访问主机 C,无须输入 passphrase。
SSH Control Master
Control Master 是 SSH 中的一项设置,允许用户在创建新的 SSH 会话时重新使用与服务器的现有连接。 这可以显着加快后续 SSH 连接的建立,因为它绕过了每次创建新连接的开销。 如果用户经常通过 SSH 连接到同一台机器,这将特别有用。
ControlMaster 设置提供三个选项:
no (默认):每个 SSH 会话都有自己的连接。
yes:第一个 SSH 会话将作为后续连接的主服务器。 此会话必须保持打开状态,其他会话才能使用其连接。
auto:与“yes”类似,但如果找不到要使用的现有主会话,SSH 将退回到创建新会话。
除了 ControlMaster 设置,用户通常还使用 ControlPath 设置来指定用于连接的 Unix 域套接字的位置。
root
低特权
SSH 代理转发
代理转发是 SSH 的一个特性,可以通过多个服务器建立连接链,并且可以在链的末端使用在本地计算机上运行的 SSH 代理。 简单来说,它允许用户从远程服务器使用本地 SSH 密钥。当用户需要从一台服务器通过 SSH 连接到另一台服务器而不将 SSH 密钥传输到本地计算机以外的任何其他服务器时,这会非常方便。 它提高了安全性,因为我们的 SSH 私钥永远不会暴露给任何远程服务器。但是,对代理转发要谨慎,因为这可能是一个安全问题:如果链中的其中一台服务器被入侵,密钥可能会被滥用来建立新连接。