我正在运行一个安装了 6 个多月的 Ubuntu 14.04。大约一周前,我开始收到一条错误消息:
Could not grab keyboard. A malicious client may be eavesdropping on your session.
我只在离开一段时间(通常是一夜)后返回电脑时才看到它。有几次它阻止屏幕在设置的超时后锁定(我已经在离开前开始主动锁定它)。
我使用的是直接连接到主板 USB 端口的 USB 键盘(Kinesis Advantage)。我使用的是无线埃利康老鼠。
我准备在离开前尝试断开鼠标适配器。否则我如何才能确定是否有恶意客户端跟踪我的击键或这是否是连接问题?
答案1
以下是解决谜题的方法。本回答的主要目的是教用户“如何利用标准的 Ubuntu 实用程序挖掘系统上任何可执行文件或正在运行的进程的详细信息”。我将仅使用这个特定案例来介绍广泛适用于许多类似案例的一般调试/调查技术。
步骤#1(主要出于好奇):确定哪个程序给出此错误:
# -- You may need to search under more directories, YMMV
# List files (incl. binaries) which contain the warning string
$ sudo grep -ral 'malicious client may be eavesdropping' /usr /bin /lib
/usr/lib/openssh/gnome-ssh-askpass
因此,根据 的回复grep
,唯一在二进制文件中包含此警告字符串的程序是gnome-ssh-askpass
。
您可以搜索此特定程序中是否存在错误,甚至可以下载其源代码apt-get source ssh-askpass-gnome
(请注意,软件包名称与程序名称不同)以进行进一步检查。
但是,我怀疑根本原因不是 的问题gnome-ssh-askpass
。由于gnome-ssh-askpass
要求输入密码,其开发人员只是选择在无法获取键盘时谨慎行事。他们设想了最坏的情况,即恶意程序,并让他们的消息听起来非常偏执。为什么?意外地将您的密码或密码输入到错误的位置(例如某个随机网站对话框)可能不是一个好主意。从这个意义上说,开发人员gnome-ssh-askpass
打印出此警告是正确的。
您的桌面正在运行大量程序/进程。当您在键盘上输入内容时,只有一这些进程中的一个进程获得输入。该程序是具有当前“焦点”的程序(通常是鼠标指针所在位置或最后单击的位置)。
最近,网站开始实行强制付费墙、注册和模式用户界面。它们会显示一个弹出窗口,淡化弹出对话框之外的所有其他内容,并积极“夺取焦点”,以便您的下一个键盘输入都转到它们。这很可能是gnome-ssh-askpass
“夺取键盘”失败的根本原因。如果您的浏览器在这样的网站上打开,关闭浏览器或离开积极“夺取注意力”的网站可能会有所帮助。如果这是原因,您可能会对桌面设置感兴趣,以防止单个进程夺取完整(全桌面)焦点。例如,在 KDE 中,可以在 (系统设置 -> 窗口行为 -> 焦点 -> 防止焦点窃取)。如果你真的感到偏执,我建议将其设置为High
或者Extreme
。注意:这也可能阻止gnome-ssh-askpass
其自身抓取键盘,或者更准确地说:抓取X
焦点。
步骤2:识别可疑进程:
知道在 Unix 中,设备在 下显示为文件/dev
,下一个问题是哪个设备在文件系统层次结构中代表“键盘”。我们可以使用lsof
(列出打开的文件) 实用程序来执行此操作。
# look for processes holding devices open, filter out some common ones:
$ sudo lsof | grep /dev | grep -vE '/(null|urandom|zero)'
请注意,在典型的桌面环境中,大多数保持设备打开的进程都保持/dev/pts/<N>
(伪终端) 打开。这些是感兴趣的“设备”。
关于这里发生的事情的一些背景信息:
在典型的 Linux 图形桌面中,进程不直接与键盘对话。相反,X
程序 (Xorg) 通过设备控制所有键盘事件/dev/input/event<N>
。X
使用事件处理程序 (evdev),其中包括处理键盘事件。您也可以通过查看日志来验证这一点X
:/var/log/Xorg.0.log
其中keyboard
提到了。
键盘事件X
通过 上打开的进程标准输入随时从事件处理程序转发到拥有鼠标指针焦点的进程/dev/pts/<N>
。严格来说:进程实际上并没有“抓住键盘”,键盘被 持有X
,进程只具有(或抓住)“焦点”或 的注意力,X
因此X
可以通过 上打开的 stdin 文件描述符将键盘事件转发给它/dev/pts/<N>
。
步骤#3:Xorg
在特定时间哪个流程具有焦点?
如何确定在特定时间哪个进程具有焦点?这里有一个 askubuntu 问题可以回答这个问题:
答案的总结是在使用鼠标导航的同时在终端中运行如下脚本:
#!/bin/bash
# Print the process tree of the window currently in focus.
# prereqs:
# sudo apt-get install xdotool psmisc
while true; do
pstree -spaul $(xdotool getwindowpid "$(xdotool getwindowfocus)")
sleep 2
done
步骤#4:深入挖掘流程活动
一旦确定了可疑进程,最后一步就是调查该进程。为此,您可以求助于 Linux/proc
文件系统 ( man 5 proc
)。
几乎任何您想了解的进程信息都可以在 下找到/proc
。事实上,诸如 (列出打开的文件)之类的程序、检查进程状态的调试器以及诸如或 之lsof
类的进程列表实用程序都依赖于由内核填充的 来获取数据。ps
top
/proc
使用proc
你可以找到进程可执行程序在磁盘上的位置(例如,标准系统目录之外的任何程序,特别是如果它试图隐藏在“别理我”这类名称,可能是可疑的),并且使用调试器或系统调用跟踪器,您可以检查它们在系统调用级别到底在做什么(即使您没有它们的源代码)。
PID
步骤 #2 和 #3 应该会为您提供所有可能正在读取键盘的进程 ID 。对于每个 PID(我们将每个 PID 表示为$pid
),您可以:
将 $pid 映射到其完整的命令行:
cat /proc/$pid/cmdline
将 $pid 映射到其磁盘上的可执行文件:
ls -l /proc/$pid/exe
将 $pid 映射到其当前工作目录:
ls -l /proc/$pid/cwd
将 $pid 映射到其原始环境
cat /proc/$pid/environ | tr '\000' '\012'
实时跟踪 $pid (及其子进程) 系统调用活动:
strace -f -p $pid
(还有更多:参见man 5 proc
)
如果您看到一个不熟悉的进程,该进程对每个按键做出反应,将其存储到文件中(通过write
)或通过网络发送到通过sendto
,那么您可能找到了键盘嗅探器。
您还可以检查哪些进程打开了(tcp+udp)网络端点:
# See 'man netstat' for details on all options used below
$ sudo netstat -tunapee
底线:
导致错误的最可能原因不是恶意软件,而是多个进程同时尝试获取键盘控制权。两者之一就是gnome-ssh-askpass
(打印错误的进程)。另一个可能是网站上打开的浏览器带有激进的焦点获取对话框。
即使您确实安装了恶意软件,好消息是,由于您使用的是 Linux,因此所有进程都是透明的,您可以研究和检查。恶意软件很难真正躲避您,或阻止您使用上述技术轻松找到它、终止其进程并删除其所有文件。
答案2
我的问题是由于两个并发gnome-ssh-askpass
窗口造成的。我通过 SSH 向同一台服务器执行了两个 rsync 作业,并且都尝试询问 SSH 证书的密码。将它们分组(和链接)在一起就解决了这个问题!
答案3
正如 arielf 在其出色的回答中提到的那样,无害进程之间可能会发生一些焦点竞争。我的情况就是这样,我通常通过按Alt+F2并运行r
以重新启动窗口管理器来解决此问题。