Bir sistem yöneticisinin kullanıcı terminallerine kulak misafiri olması mümkün müdür?


17

Bir makineye giriş yaptığınızda, her kullanıcının sahte terminal cihazlarını çıkışından öğrenebilirim w. Bir sistem yöneticisi olarak, kullanıcının farkında olmadan bu terminalde gizlice dinlemem mümkün mü? Başka bir deyişle, bu terminalde her şeyin kendi terminalimde çıktı olarak yapıldığını görmek istiyorum.

Lütfen aşağıdakilere dikkat edin:

  • Bu, kullanıcı faaliyetlerini izlemek için pratik bir kullanım durumu değildir: Bunun için sistem denetim araçları olduğunun farkındayım. Sadece yapılıp yapılamayacağını merak ediyorum.
  • Bu sorunun farkındayım ve sorduğum şeyleri kapsadığı gibi görünmüyor, çünkü önerilen tüm çözümler ya invaziv (kullanıcı ne yaptığımın farkında olacak) ya da çok fazla gürültü ( straceçözüm). Yaklaşan tek çözüm, kullanmayı öneren çözümdür gdb. Ama bu sadece diğer terminalin stdout'unu görmeme izin veriyor.

Ne denedim

Bunu terminalimden denedim:

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

Bu, kullanıcının yazdığı diğer sahte terminalde yazdığı her karakteri görmemi sağlar. Sorun şu, her birkaç karakterde bir "atlayacak": bir terminal aygıtında bir hileli karakter gösterecekti, diğerinde göstermeyecekti. Ayrıca, kullanıcının sözde terminal aygıtından herhangi bir komutun yürütülmesini de engeller. Bunun neden olduğundan ve onu iyileştirmenin bir yolu olup olmadığından emin değilim.

Ne görmek istiyorum

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

1
İstersiniz ttysnoopya da muhtemelen peekfd.
n. 'zamirler' m.

Yanıtlar:


11

Üzerinde gösterilenleri görmek isteyip istemediğinizi izlemek istediğiniz terminal emülatöründeki sözde terminalin ana tarafına fd'dir. Bu ana fd, gerçek bir terminale giden kabloyu simüle eden şeydir. Ne xtermüzerine yazıyor bu tuşa üretilen karakterdir. Ondan ne okuduğu onu gösterir.

Örneğin, Linux'ta:

$ 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

Ve sonra örneğin çalıştırın:

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'

Elbette, izlemeye çalıştığınız tipte ve boyutta bir terminalde çalıştırırsanız daha iyi çalışır. İle boyutu alabilirsiniz:

stty size < /dev/pts/that-terminal

Ne Yani çöplük okumak tarafından xtermterminalin ana yanından, ne yani yerel olmak üzere orada görüntülenir echoolarak yazılmış ne.

-e read=4Yukarıda içindir straceşeyin HexDump çıkışına xtermonun fd 4. komuta geri kalanı üzerinde okur gerçek karakterlere o dönüştürülmesidir. Denedim peekfd -n -8 15173 4ama nedense sadece yazılanları verdi.

-opostİzleme terminalimizdeki herhangi bir son işlemeyi devre dışı bırakmak için kullanıyoruz , böylece her şey xxdköle tarafına yazıyor, ana tarafımızda değişmeden kalıyor, böylece izlememiz xtermizlenenle aynı şeyi alıyor. -echoböylece izlenen terminaldeki uygulama terminalden cevap isteyen bir kaçış dizisi gönderirse (imleç pozisyonunu veya terminal tipini veya pencere başlığını talep edenler gibi), izlememize xtermve xtermirademize yol açar yanı sıra. Bunun yerel bir yankısını istemiyoruz.

Ayrıca takip ederek yazdığınız ediliyor ne monitör olabilir write(replace aynı fd sistem çağrıları readile writeyukarıda). Basıldığında Enter, terminal emülatörünün LF değil bir CR karakteri gönderdiğini unutmayın. Ayrıca, ana tarafta izlediğimizden, kullanıcı yazıyorsa a<Backspace>b, terminal cihazı kanonik modda olsa bile 3 tuş vuruşunun hepsini göreceğiz.

Sizinki neden çalışmıyor?

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

Terminal cihazdan okuma, kullanıcı girişini okuyor ve ona yazma, onu kullanıcıya göstermektir.

teeTerminal cihazından okumayı söylüyorsunuz . Yani okur Ne (kullanıcı girişi) olmayacak read, terminal çalışan uygulama (lar) tarafından (vis tersi ve, teeve bu applicationuç girişi için mücadele edeceğiz). Terminal cihazına yazmak, orada göstermek içindir, oraya giriş olarak koymak için değildir. Ne zaman yaparsın

echo test

( echoterminalin stdout'u ile), yazmış gibi değil test.

Karakterleri giriş olarak geri koymak için bir ioctl( TIOCSTI) vardır , ancak uygulamadan sonra biraz daha okuduktan sonra geri koyabileceğiniz için bu gerçekten işe yaramaz , bu nedenle uygulamanın giriş okuma sırasını değiştirir ve herhangi bir şekilde, bu onu tekrar tekrar okuyacağınız anlamına gelir.


1
+1 Açıklama ve harici araçlar kullanmadığınız için. Cevabınızın birçok bölümünü anlamak için biraz okumaya ihtiyacım olacak, ama istediğim şeyin çizgisinde olduğunu hissediyorum.
Joseph R.

5

İşletim sisteminiz dtrace'yi destekliyorsa, basit bir komut dosyası olan shellsnoop, belirli bir tty'ye yazılan / yazdırılan her şeyi izlemenize izin vermelidir.

Linux kullanıyorsanız, ttysnoop benzer bir şey yapardı, ancak ön koşul olarak müdahaleci bir yapılandırmaya ihtiyaç duyuyordu ve AFAIK artık mevcut çekirdeklerle desteklenmiyor, bu yüzden davanızda yardımcı olmayacak. Linux, systemtap, ktap ve hatta dtrace ile dinamik izleme sağlamak için az çok gelişmiş girişimler vardır, böylece bunları araştırabilirsiniz.

Düzenleme: peekfd sakının , manuel sayfa devletler:

Hatalar:

Muhtemelen çok. İzlediğiniz işlem ölürse şaşırmayın.


3

Bu yaklaşım biraz gdb ve tee içerir. Ah, ve ayrıca yalancı bir terminal taklit etmek için socat kullanır. Onsuz çalışabilir, ancak kullanıcı çıktısının artık bir terminal olmadığını fark edecektir (vi gibi programlar şikayet edecek).

Aşağıdakileri yapar:

  1. Socat kullanarak kendini pty olarak gösteren bir önleme oluştur.
  2. Durdurucu hem $ sys terminalinde hem de $ usr terminalinde akışları çoğaltan tee'ye bağlanır.
  3. Gdb, stdout / stderr dosya tanımlayıcılarını $ usr terminali yerine yakalayıcıyı işaret edecek şekilde değiştirmek için kullanılır.

Ben bash stderr yazdığınızı yazmak gibi görünüyor fark ettim, diğer programlar aynı şeyi yapmak emin değilim. Bu durumda, stdin'in ele geçirilmesi gerekmez.

Böyle diyelim: chmod +x /path/to/script; sudo /path/to/script <usr> <sys-adm>. usrve sys-admterminallerin adlarıdır, örneğin /dev/pts/1. Yani örnek bir çağrı şu şekilde görünecektir: sudo /path/to/script /dev/pts/1 /dev/pts/2. Terminalinizi ttykomutla öğrenebilirsiniz . Ve kullanıcı terminali ile ya wveya 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'in istismarını göstermek için xkey.c adlı basit bir C programı var. Google'a izin vereceğim. Kullanıcının farkında olmadan bunu kullanarak xterm'deki tuş vuruşlarını yakalayabilirsiniz.


Aslında bir terminal-emülatör-agnostik çözüm umuyordum.
Joseph R.

xkey, bir X ekranında tuş vuruşlarını verecektir. Bu tüm xterms ve klavye girişi gerektiren diğer herhangi bir yardımcı program olacaktır.
unxnut

Sağ. xtermÖzellikle demek istediğini sanıyordum .
Joseph R.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.