È possibile per un amministratore di sistema intercettare sui terminali dei suoi utenti?


17

Quando accedo a una macchina, posso scoprire i dispositivi pseudo-terminali di ciascun utente dall'output di w. Essendo un amministratore di sistema, è possibile per me intercettare su questo terminale senza che l'utente ne sia consapevole? In altre parole, vorrei vedere tutto ciò che veniva fatto su questo terminale come output sul mio terminale.

Si prega di notare quanto segue:

  • Questo non è per un caso pratico di monitoraggio delle attività degli utenti: sono consapevole che esistono strumenti di controllo del sistema per questo. Sono solo curioso di sapere se si può fare.
  • Sono consapevole di questa domanda e non sembra coprire ciò che sto chiedendo in quanto tutte le soluzioni suggeriscono che ci sono o invasive (l'utente sarebbe consapevole di ciò che sto facendo) o producono troppo rumore (il stracesoluzione). L'unica soluzione che si avvicina è quella che suggerisce l'utilizzo gdb. Ma questo mi fa vedere solo stdout dell'altro terminale.

Quello che ho provato

Ho provato questo dal mio terminale:

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

Questo mi permette di vedere ogni carattere digitato dall'utente nell'altro pseudo-terminale mentre lo digita. Il problema è che, ogni pochi caratteri, "salterebbe": mostrerebbe un personaggio canaglia su un dispositivo terminale ma non sull'altro. Impedisce inoltre l'esecuzione di qualsiasi comando dal pseudo terminale dell'utente. Non sono davvero sicuro del perché questo accada e se esista un modo per migliorarlo.

Quello che mi piacerebbe vedere

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

1
Tu vuoi ttysnoopo probabilmente peekfd.
n. 'pronomi' m.

Risposte:


11

È il fd sul lato master dello pseudo-terminale nell'emulatore di terminale che si desidera monitorare se si desidera vedere cosa viene visualizzato su di esso. Quel master fd è ciò che simula il filo che va a un terminale reale. Ciò che xtermscrive su di esso sono i caratteri generati dal tasto premuto. Ciò che legge da esso è ciò che visualizza.

Ad esempio, su 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

E quindi eseguire ad esempio:

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'

Certo, funziona meglio se lo esegui in un terminale dello stesso tipo e dimensione di quello che stai cercando di monitorare. Puoi ottenere le dimensioni con:

stty size < /dev/pts/that-terminal

Che scarica ciò che viene letto dal xtermdal lato master del terminale, in modo da ciò che viene visualizzato lì, compreso il locale echodi ciò che viene digitato.

Quanto -e read=4sopra serve per stracegenerare un hexdump di ciò che xtermlegge sul suo fd 4. Il resto del comando è di convertirlo in caratteri effettivi. Ci ho provato, peekfd -n -8 15173 4ma per qualche ragione questo ha dato solo ciò che veniva scritto.

Stiamo utilizzando -opostper disabilitare qualsiasi post-elaborazione nel nostro terminale di monitoraggio, in modo che tutto ciò che xxdscrive sul lato slave rimanga invariato sul nostro lato master, in modo che il nostro monitoraggio xtermottenga la stessa cosa di quello monitorato. -echoè così che se l'applicazione nel terminale monitorato invia una sequenza di escape che richiede una risposta dal terminale (come quelli che richiedono la posizione del cursore o il tipo di terminale o il titolo della finestra), si farà strada verso il nostro monitoraggio xterme la nostra xtermvolontà rispondi pure. Non vogliamo un'eco locale di questo.

Puoi anche monitorare ciò che viene digitato tracciando le writechiamate di sistema sullo stesso fd (sostituisci readcon writesopra). Si noti che quando si preme Enter, l'emulatore di terminale invia un carattere CR, non LF. Inoltre, poiché stiamo eseguendo la traccia sul lato principale, se l'utente digita a<Backspace>b, vedremo tutte e 3 le sequenze di tasti anche se il dispositivo terminale è in modalità canonica.

Per quanto riguarda il motivo per cui il tuo non funziona:

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

La lettura dal dispositivo terminale sta leggendo l'input dell'utente e la scrittura su di esso è per visualizzarlo all'utente.

Stai dicendo teedi leggere dal dispositivo terminale. Quindi ciò che legge (l'input dell'utente) non lo sarà readper le applicazioni in esecuzione nel terminale (e viceversa, teee questo applicationcombatterà per l'input del terminale). Scrivere sul dispositivo terminale, è per la visualizzazione lì, non è per rimetterlo lì come input. Quando lo fai

echo test

(con lo echostdout il terminale), non è la stessa cosa che se avessi digitato test.

C'è un ioctl( TIOCSTI) per rimettere i caratteri come input, ma anche quello non funzionerebbe davvero perché potresti rimetterlo dopo l'applicazione come già letto un po 'di più, quindi cambierebbe l'ordine in cui l'applicazione sta leggendo l'input e, in ogni caso, ciò significherebbe che l'avresti letto più e più volte.


1
+1 Per la spiegazione e per non utilizzare strumenti esterni. Avrò bisogno di leggere un po 'per capire molte parti della tua risposta, ma sento che è sulla falsariga di ciò che voglio.
Joseph R.

5

Se il tuo sistema operativo supporta dtrace, un semplice script, shellsnoop , dovrebbe permetterti di monitorare tutto ciò che è stato digitato / stampato su un dato tty.

Se stai usando Linux, ttysnoop faceva una cosa simile ma aveva bisogno di una configurazione invadente come prerequiste e AFAIK non è più supportato con i kernel attuali, quindi non ti aiuterà nel tuo caso. Esistono tentativi più o meno avanzati di fornire traccia dinamica con Linux, systemtap, ktap e persino dtrace in modo da poterli investigare.

Modifica: attenzione a peekfd , la sua pagina di manuale afferma:

bugs:

Probabilmente un sacco. Non essere sorpreso se il processo che stai monitorando muore.


3

Questo approccio prevede un po 'di gdb e tee. Ah, e usa anche socat per emulare uno pseudo-terminale. Potrebbe funzionare senza di essa, ma l'utente noterà che il suo output non è più un terminale (programmi come vi si lamenteranno).

Fa quanto segue:

  1. Crea un intercettore, usando socat, che si espone come un pty.
  2. L'interceptor è collegato a tee, che duplica flussi sia nel terminale $ sys che nel terminale $ usr.
  3. Gdb è usato per sostituire i descrittori di file stdout / stderr in modo che puntino all'intercettore anziché al terminale $ usr.

Ho notato che bash sembra scrivere ciò che si digita su stderr, non sono sicuro che altri programmi facciano lo stesso. In tal caso, non è necessario intercettare lo stdin.

Chiamatela come questo: chmod +x /path/to/script; sudo /path/to/script <usr> <sys-adm>. usre sys-admsono i nomi dei terminali, ad esempio /dev/pts/1. Quindi, una chiamata di esempio sarebbe simile a questa: sudo /path/to/script /dev/pts/1 /dev/pts/2. Puoi scoprire il tuo terminale con il ttycomando. E il terminale utente con wo 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

Esiste un semplice programma C chiamato xkey.c per mostrare gli exploit di X11. Ti lascio google. Puoi catturare i tasti premuti su un xterm usando questo senza che l'utente ne sia consapevole.


Speravo davvero in una soluzione agnostica-emulatore terminale.
Joseph R.,

xkey ti darà i tasti su un display X. Saranno tutti gli xterm e qualsiasi altra utility che necessita dell'input da tastiera.
Unxnut

Giusto. Pensavo intendessi xtermspecificamente.
Joseph R.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.