系统管理员是否有可能窃听他/她用户的终端?

Jos*_* R. 17 administration io-redirection

当登录到一台机器时,我可以从w. 作为系统管理员,我是否可以在用户不知情的情况下窃听此终端?换句话说,我希望看到在这个终端上所做的一切都作为我自己终端上的输出。

请注意以下事项:

  • 这不是用于监视用户活动的实际用例:我知道有系统审计工具可以做到这一点。我只是好奇是否可以做到。
  • 我知道这个问题,它似乎没有涵盖我要问的问题,因为所有解决方案都表明存在侵入性(用户会知道我在做什么)或产生太多噪音(strace解决方案)。接近的一种解决方案是建议使用gdb. 但这只能让我看到另一个终端的标准输出。

我试过的

我从我的终端试过这个:

tee /dev/pts/user_pts </dev/pts/user_pts
Run Code Online (Sandbox Code Playgroud)

这使我可以在用户键入时看到用户在另一个伪终端中键入的每个字符。问题是,每隔几个字符,它就会“跳过”:它会在一个终端设备上显示一个流氓字符,而不是另一个。它还可以防止从用户的伪终端设备执行任何命令。我不确定为什么会发生这种情况以及是否有办法改进它。

我想看什么

USER TERMINAL        |    MY TERMINAL
$ echo "Test"        |    # slick_command_here
Test                 |    echo "Test"
$                    |    Test
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 11

如果您想查看其上显示的内容,则它是终端仿真器中伪终端主端的 fd,您要监视它。那个fd 是模拟通往真实终端的电线。上面xterm写的是你按下的键产生的字符。它从中读取的内容就是它显示的内容。

例如,在 Linux 上:

$ lsof -ac xterm /dev/ptmx
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xterm   15173 chazelas    4u   CHR    5,2      0t0 2131 /dev/ptmx
Run Code Online (Sandbox Code Playgroud)

然后运行例如:

stty -echo -opost
strace -e read -e read=4 -p15173 2>&1 | stdbuf -o0 sh -c '
  grep "^ |" | cut -b11-60 | tr -d " " | xxd -r -p'
Run Code Online (Sandbox Code Playgroud)

当然,如果您在与您要监控的终端类型和大小相同的终端中运行它,效果会更好。您可以通过以下方式获取尺寸:

stty size < /dev/pts/that-terminal
Run Code Online (Sandbox Code Playgroud)

这会转储从终端的主端读取的内容xterm,因此显示在那里的内容,包括echo正在键入的内容的本地内容。

-e read=4上面的是strace输出一个什么样的hexdump都可以xterm在其FD 4命令的其余部分读取是将其转换成实际的字符。我试过,peekfd -n -8 15173 4但出于某种原因,只给出了正在写的内容。

我们正在使用-opost在我们的监控终端中禁用任何后处理,以便所有xxd写入从端的内容都不会改变我们的主端,以便我们的监控与xterm被监控的相同。-echo是这样,如果被监控终端中的应用程序发送一个要求终端回答的转义序列(例如那些请求光标位置或终端类型或窗口标题的),这将进入我们的监控xterm和我们的xterm意志也回复。我们不想要那种地方的回声。

您还可以通过跟踪对write同一 fd的系统调用来监视正在键入的内容(替换readwrite上述内容)。请注意,按下 后Enter,终端仿真器会发送一个 CR 字符,而不是 LF。此外,由于我们在主端进行跟踪,如果用户键入a<Backspace>b,即使终端设备处于规范模式,我们也会看到所有 3 次击键。

至于为什么你的不起作用:

tee /dev/pts/user_pts </dev/pts/user_pts
Run Code Online (Sandbox Code Playgroud)

从终端设备读取是读取用户输入,写入是将其显示给用户。

你告诉tee从终端设备读取。因此,它读取的内容(用户输入)不会read由在终端中运行的应用程序(反之亦然,teeapplication将争夺终端输入)。写入终端设备是为了在那里显示,而不是将其作为输入放回那里。当你做

echo test
Run Code Online (Sandbox Code Playgroud)

(以echo的标准输出作为终端),这与您输入test.

有一个ioctl( TIOCSTI) 将字符放回输入,但即使这样也不会真正起作用,因为您可以将它放回应用程序之后,因为已经阅读了更多内容,因此它会更改应用程序读取输入的顺序,无论如何,那意味着你会一遍又一遍地阅读它。


jll*_*gre 5

如果您的操作系统支持 dtrace,那么一个简单的脚本shellsnoop应该允许您监视在给定 tty 上键入/打印的所有内容。

如果您正在运行 Linux,ttysnoop曾经做过类似的事情,但需要一个侵入性配置作为先决条件,并且 AFAIK 无论如何都不再受当前内核的支持,因此对您的情况没有帮助。有或多或少的高级尝试使用 Linux、systemtap、ktap 甚至 dtrace 提供动态跟踪,因此您可以调查它们。

编辑:当心peekfd,其手册页指出:

错误:

可能很多。如果您正在监视的进程死亡,请不要感到惊讶。