ssh技巧

避免SSH垂直越权!agent forwarding 和 proxy command 命令的安全风险

如何使用 agent forwarding
SSH agent forwarding 可以让我们透过跳板机连上另一台服务器时,省去把私钥复制上 server 或是需要输入密码的功夫。
通常可以使用 ssh -A 来做转发
将要 forwarding 的 key 加到列表之中
ssh-add
或是写在 .ssh/config 之中

Host web-server
  HostName 33.33.33.10
  ForwardAgent yes


常见应用:跳板机
举例来说,当我们本地机器透过 SSH 连线至跳板机时,接着再从跳板机 到 web-server 这段,会直接使用本地的 SSH Key
Local —(SSH)—> 跳版机 —(SSH) web-server
透过 agent forwarding,我们在跳板机到 web-server 这段, web-server 会将 challenge 发送到跳版机,然后跳版机 会在发回到发起请求的本地端,随后本地端的 ssh-agent 会将解密后的私钥用来验证,并完成验证。
简单来说,这个连接不管有多长,只要中间都是打开 agent forwarding 就都可以不用输入密码,可以一直转发 local 的 ssh。
然而常见的应用除了上述提到的跳板机架构以外,还有部属时为了拉 code 也会用到
Git Deployment
举例来说,web-server要能够从 github 上pull code 下来,那最直觉的作法是在 web-server 上放一份能够和 github 认证的 ssh key pair。
但是,通常为了不增加安全风险,所以不把私钥留在机器上,否则就会变成谁能进来机器,就可以有拉 code 的权限。
所以我们也可以在这段做 agent-forwarding,并且基本上能够部属的人,也会有 pull code 的权限,所以直接从部署者的 ssh key 进行转发,让 code 能够顺利从 github 拉到 server 上完成部署。
方便带来的安全疑虑
我们在 command line 输入 man ssh 可以看到
-A Enables forwarding of the authentication agent connection.
This can also bespecified on a per-host basis in a configuration file.
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host (for the agent’s UNIX-domain socket) can access the local agent through the forwarded connection.An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent.

agent forwarding显然非常方便好用,但需谨慎使用,尤其当大家都对机器有 root 权限时,就更不应该使用,因为这样可能有垂直越权的风险。
如何垂直越权
可以先找一台 server 用 agent forwarding 方式登入
ssh -A deploy@your_server
输入 ls -l /tmp | grep “ssh-” 会发现 agent 的 socket 被放到 /tmp 下方
deploy@localhost:~$ ls -l /tmp | grep “ssh-“
drwx—— 2 deploy deploy 4096 Aug 2 01:11 ssh-evnX3i6YmO

所以只要有 root 权限,就可以通过 SSH_AUTH_SOCK 来冒充这个利用 forwarding 的人
export SSH_AUTH_SOCK=/tmp/ssh-evnX3i6YmO/agent.1918

git clone git@github.com:niclin/project.git
成功拉下项目
这样一来,也就是说如果有比我们权限更高的用户 forwarding,我们就可以通过这样的机制越权拿到更高权限的东西
类似:
1、利用别人身份访问自己没有权限看到的代码
2、冒充他人身份发送 commit
3、登入本来没有权限的服务器,然后进去在 ~/.ssh/authorized_keys 加上我们的 public key,就可以乱登了(通常应该没人会特别去检查这只档案吧 XD?)

这样子就是透过 forwarding 垂直越权了
ProxyCommand
我们一样可以通过 ssh 内的 proxy command 做到代理转发的需求
不过这边不同的是,你需要先在这些机器上面做 public key authorized(不做也可以,就是一直输入密码XD)

Host jump-server
    User nic
    Hostname 117.10.10.1
 
 Host web-server
    User deploy
    Hostname 192.168.1.1
    Port 2222
    ProxyCommand ssh -q -W %h:%p jump-server


要连到 web-server 会先经过 jump-server,而 proxy command 的作用就是在连到 web-server 之前,先和 jump-server 建立 ssh 连线,并在中间打开一条 TCP/socket 隧道,进行内容转送
实际过程大致如下
1、Local 和 jump-server 建立 ssh 连接
2、在jump-server建立port去转送 command 信息
3、jump-server 和 web-server 建立 ssh 连接
4、在 web-server 上建立 port 去转送 command 消息
5、在 web-server 上发起和 jump-server 的 tcp/socket 连线
6、将 web-server 的标准输入转送给 jump-server 让 jump-server 和 local ssh 能够使用

不过看了 hacknews 上面的讨论,用 proxy command 会比 agent forwarding 较安全的原因是不容易被伪造,也不像 agent forwarding 会留下踪迹可以冒充身份
那么,假设跳版机已经被入侵了,那么用 proxy command 只是做 tcp 转发,第二段连接到 web server 那段的数据都是在 local 端上进行加解密,所以基本上从跳板机那台是看不到解密的数据。

本文来源:https://blog.niclin.tw/2019/08/03/ssh-agent-forwarding-and-proxy-command/