系统管理员是否可以窃听用户终端?


17

登录到计算机后,我可以从的输出中找出每个用户的伪终端设备w。作为系统管理员,我是否有可能在用户不知情的情况下窃听此终端?换句话说,我希望在此终端上看到的一切都作为自己终端上的输出完成。

请注意以下事项:

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

我尝试过的

我在终端上尝试了此操作:

tee /dev/pts/user_pts </dev/pts/user_pts

这使我可以看到用户在键入其他伪终端时键入的每个字符。问题是,每隔几个字符,它就会“跳过”:它将在一个终端设备上显示一个流氓字符,而在另一终端设备上却不显示。它还阻止了来自用户的伪终端设备的任何命令的执行。我不太确定为什么会这样,是否有改善的方法。

我想看什么

USER TERMINAL        |    MY TERMINAL
$ echo "Test"        |    # slick_command_here
Test                 |    echo "Test"
$                    |    Test

1
你想要ttysnoop还是可能peekfd
n。代词

Answers:


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

然后例如运行:

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'

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

stty size < /dev/pts/that-terminal

那倾倒了阅读的东西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

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

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

echo test

(将echostdout用作终端),这与您键入的内容不同test

有一个ioctlTIOCSTI)可以将字符放回输入中,但是即使这样也不能真正起作用,因为您可以在应用程序读回更多内容后再放回它,因此它将改变应用程序读取输入的顺序,无论如何,那意味着您将一遍又一遍地阅读它。


1
+1作为说明,并且不使用外部工具。我需要做一些阅读才能理解您答案的许多部分,但我认为这是我想要的。
Joseph R.

5

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

如果您正在运行Linux,则ttysnoop曾经做过类似的事情,但需要先进行侵入式配置,并且AFAIK不再受当前内核的支持,因此对您的情况无济于事。在Linux,systemtap,ktap甚至dtrace上提供了或多或少的高级动态跟踪尝试,因此您可以进行调查。

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

错误:

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


3

这种方法涉及一些gdb和tee。嗯,它还使用socat模拟伪终端。没有它也可以工作,但是用户会注意到他/她的输出不再是终端(像vi这样的程序会抱怨)。

它执行以下操作:

  1. 使用socat创建一个拦截器,该拦截器将自己显示为pty。
  2. 拦截器连接到tee,后者在$ sys终端和$ usr终端中复制流。
  3. Gdb用于替换stdout / stderr文件描述符以指向拦截器,而不是$ usr终端。

我注意到bash似乎会将您键入的内容写到stderr,我不确定其他程序是否也这样做。如果是这种情况,则不必拦截标准输入。

这样称呼:chmod +x /path/to/script; sudo /path/to/script <usr> <sys-adm>usrsys-adm是终端的名称,例如/dev/pts/1。因此,调用示例如下所示:sudo /path/to/script /dev/pts/1 /dev/pts/2。您可以使用tty命令找到您的终端。并且用户终端可以使用wps

#!/bin/sh

[ "$1" ] || exit 1
[ "$2" ] || exit 1

usr=$1
sys=$2
utty=${1#/dev/}

ps -e -o tty= -o pid= -o user= | { 
    found_it=

    while read -r tty pid_sh owner; do
        if [ "$utty" = "$tty" ]; then
            found_it=y
            break;
        fi
    done

    [ "$found_it" ] || exit 1

    tmp=$(mktemp)
    tmp_gdb=$(mktemp)

    trap 'rm "$tmp" "$tmp_gdb"' EXIT

    socat PTY,link="$tmp",echo=0,raw,openpty,user="$owner",mode=0600 SYSTEM:"tee $sys > $usr"      &

    printf 'call dup2(open("%s", 1), 1)\ncall dup2(open("%s", 1), 2)
            detach\nquit\n' "$tmp" "$tmp" > "$tmp_gdb"
    gdb -p "$pid_sh" -x "$tmp_gdb" >/dev/null 2>&1 &

    wait
}

2

有一个名为xkey.c的简单C程序来显示X11的漏洞。我让你用谷歌搜索。您可以使用此功能捕获xterm上的击键,而无需用户意识到。


我实际上希望有一个与终端仿真器无关的解决方案。
Joseph R.

xkey将在X显示屏上为您提供击键操作。这将是所有xterm以及需要键盘输入的任何其他实用程序。
unxnut

对。我以为你是xterm故意的。
Joseph R.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.