システム管理者がユーザーの端末を盗聴することは可能ですか?


17

マシンにログインすると、の出力から各ユーザーの擬似端末デバイスを見つけることができますw。システム管理者として、ユーザーが気付かないうちにこの端末を盗聴することは可能ですか?つまり、この端末で行われているすべてのことを自分の端末での出力として見たいのです。

次の点に注意してください:

  • これは、ユーザーアクティビティを監視する実用的な使用例ではありません。そのためのシステム監査ツールがあることは承知しています。私はそれができるかどうか興味があります。
  • 私はこの質問を知っていますが、すべての解決策が侵襲的である(ユーザーが私がしていることを知っている)か、あまりにも多くのノイズを生成する(strace解決)。近づいて来る1つのソリューションは、の使用を提案するものgdbです。ただし、これにより、他の端末の標準出力のみが表示されます。

私が試したこと

私の端末からこれを試しました:

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

これにより、ユーザーが入力したときに、ユーザーが入力した各文字を他の疑似端末で見ることができます。問題は、数文字ごとに「スキップ」することです。1つの端末デバイスで1つの不正な文字が表示されますが、他のデバイスでは表示されません。また、ユーザーの疑似端末デバイスからのコマンドの実行も防ぎます。なぜこれが起こっているのか、それを改善する方法があるのか​​どうか、私にはよく分かりません。

見たいもの

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

1
あなたが望むttysnoopか、おそらくpeekfd
n。「代名詞」m。

回答:


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私たちの監視がそうすることを、スレーブ側への書き込みは、私たちのマスター側にそれがそのままになりxterm1を監視対象と同じものを取得します。-echo監視対象端末のアプリケーションが、端末からの応答を要求するエスケープシーケンス(カーソル位置、端末タイプ、またはウィンドウタイトルを要求するものなど)を送信すると、監視xtermxterm意志への道が開かれます返信も。局所的なエコーは必要ありません。

また、トレースすることでタイプされているものを監視することができるwrite(置き換え、同じFDにシステムコールをreadしてwrite上記)。を押すEnterと、ターミナルエミュレータはLFではなくCR文字を送信することに注意してください。また、マスター側でトレースしているため、ユーザーa<Backspace>bがを入力すると、端末デバイスが標準モードであっても3つのキーストロークがすべて表示されます。

なぜ機能しないのか:

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

端末デバイスからの読み取りはユーザー入力を読み取り、書き込みはユーザーへの表示です。

tee端末デバイスから読み取るように指示しています。だから何それは読み込み(ユーザー入力)ができなくなりread、端末内のアプリケーション(複数可)を実行して(その逆とVIS、teeそれはapplication端末入力を戦うことになります)。端末デバイスへの書き込みは、そこで表示するためのものであり、入力としてそこに戻すためではありません。するとき

echo test

echo'stdout'が端末である場合)、それはあなたがタイプしたかのようにはなりませんtest

入力として文字を戻すためのioctlTIOCSTI)がありますが、アプリケーションが既に読み取ったにそれを戻すことができるため、それでも実際には機能しません。それはあなたが何度も何度もそれを読むことを意味するでしょう。


1
+1説明および外部ツールを使用しないため。あなたの答えの多くの部分を理解するために少し読む必要がありますが、私はそれが私が望むものの線に沿っていると感じています。
ジョセフR.

5

OSがdtraceをサポートしている場合、単純なスクリプトshellsnoopを使用すると、指定されたttyで入力/印刷されたすべてを監視できます。

Linuxを実行している場合、ttysnoopは以前は同様のことをしていましたが、前提条件として侵入的な構成が必要でした。Linux、systemtap、ktap、さらにはdtraceを使用して動的トレースを提供するための多かれ少なかれ高度な試みがあります。

編集:peekfdに注意してください、そのマニュアルページの状態:

バグ:

おそらくたくさん。監視しているプロセスが停止しても驚かないでください。


3

このアプローチには、gdbとteeが少し含まれます。ああ、またsocatを使用して擬似端末をエミュレートします。それなしでも動作しますが、ユーザーは自分の出力がもはや端末ではないことに気付くでしょう(viのようなプログラムは文句を言うでしょう)。

次のことを行います。

  1. socatを使用してインターセプターを作成します。インターセプターは自身をptyとして公開します。
  2. インターセプターはteeに接続されており、$ sys端末と$ usr端末の両方でストリームを複製します。
  3. Gdbは、stdout / stderrファイル記述子を置き換えるために使用され、$ usr端末の代わりにインターセプターを指します。

bashは、入力した内容をstderrに書き込むように見えることに気付きました。他のプログラムが同じことを行うかどうかはわかりません。その場合は、stdinをインターセプトする必要はありません。

次のように呼び出しますchmod +x /path/to/script; sudo /path/to/script <usr> <sys-adm>usrおよびsys-admは、端末の名前です(例:)/dev/pts/1。したがって、サンプル呼び出しは次のようになりますsudo /path/to/script /dev/pts/1 /dev/pts/2ttyコマンドを使用して端末を見つけることができます。そして、wまたはのいずれかのユーザー端末ps

#!/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

X11のエクスプロイトを示すxkey.cと呼ばれる単純なCプログラムがあります。グーグルさせてあげます。ユーザーが気付かないうちに、これを使用してxtermでキーストロークをキャプチャできます。


実際に、端末エミュレーターに依存しないソリューションを期待していました。
ジョセフR.

xkeyは、Xディスプレイでキーストロークを提供します。これは、すべてのxtermと、キーボード入力を必要とするその他のユーティリティです。
-unxnut

正しい。私はあなたがxterm特に意味すると思った。
ジョセフR.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.