Quando conectado a uma máquina, posso descobrir o (s) dispositivo (s) pseudo-terminal de cada usuário na saída de w
. Sendo um administrador de sistema, é possível escutar este terminal sem que o usuário esteja ciente? Em outras palavras, gostaria de ver tudo o que está sendo feito neste terminal como saída no meu próprio terminal.
Por favor observe o seguinte:
- Este não é um caso de uso prático para monitorar as atividades do usuário: eu sei que existem ferramentas de auditoria do sistema para isso. Só estou curioso se isso pode ser feito.
- Estou ciente dessa pergunta e parece não cobrir o que estou perguntando, pois todas as soluções sugeridas são invasivas (o usuário está ciente do que estou fazendo) ou produzem muito ruído (o
strace
solução). A única solução que se aproxima é a que sugere o usogdb
. Mas isso só me permite ver stdout do outro terminal.
O que eu tentei
Eu tentei isso no meu terminal:
tee /dev/pts/user_pts </dev/pts/user_pts
Isso me permite ver cada caractere que o usuário digita no outro pseudo-terminal à medida que o digita. O problema é que, a cada poucos caracteres, ele "pulava": mostrava um caractere não autorizado em um dispositivo terminal, mas não no outro. Também impede a execução de qualquer comando do dispositivo pseudo-terminal do usuário. Não sei ao certo por que isso está acontecendo e se há uma maneira de melhorá-lo.
O que eu gostaria de ver
USER TERMINAL | MY TERMINAL
$ echo "Test" | # slick_command_here
Test | echo "Test"
$ | Test
fonte
ttysnoop
ou provavelmentepeekfd
.Respostas:
É o fd no lado principal do pseudo-terminal no emulador de terminal que você deseja monitorar se deseja ver o que é exibido nele. Esse mestre fd é o que simula o fio que vai para um terminal real. O que
xterm
escreve nele são os caracteres gerados a partir da tecla que você pressiona. O que ele lê é o que ele exibe.Por exemplo, no Linux:
E execute, por exemplo:
Obviamente, funciona melhor se você o executar em um terminal do mesmo tipo e tamanho que o que você está tentando monitorar. Você pode obter o tamanho com:
Isso despeja o que é lido pelo
xterm
lado mestre do terminal, então o que é exibido lá, incluindo o localecho
do que está sendo digitado.O exemplo
-e read=4
acima é parastrace
gerar um hexdump do que éxterm
lido em seu fd 4. O restante do comando é converter isso nos caracteres reais. Eu tentei,peekfd -n -8 15173 4
mas por algum motivo, apenas deu o que estava sendo escrito.Estamos usando
-opost
para desativar qualquer pós-processamento em nosso terminal de monitoramento, para que tudo o que éxxd
gravado no lado escravo o mantenha inalterado em nosso lado mestre, para que nosso monitoramentoxterm
fique com a mesma coisa que o monitorado.-echo
é para que, se o aplicativo no terminal monitorado enviar uma sequência de escape que solicite uma resposta do terminal (como aquelas que solicitam a posição do cursor ou o tipo de terminal ou o título da janela), isso vá para o nosso monitoramentoxterm
e nossaxterm
vontade responda também. Não queremos um eco local disso.Você também pode monitorar o que está sendo digitado, rastreando as
write
chamadas do sistema para o mesmo fd (substituaread
porwrite
acima). Observe que, ao pressionar Enter, o emulador de terminal envia um caractere CR, não LF. Além disso, como estamos rastreando no lado mestre, se o usuário digitara<Backspace>b
, veremos as três teclas pressionadas, mesmo que o dispositivo terminal esteja no modo canônico.Por que o seu não funciona:
A leitura do dispositivo do terminal está lendo a entrada do usuário e a gravação é exibida para o usuário.
Você está dizendo
tee
para ler no dispositivo terminal. Portanto, o que ele lê (a entrada do usuário) não seráread
pelo (s) aplicativo (s) em execução no terminal (e vice-versa,tee
e issoapplication
lutará pela entrada do terminal). Escrever no dispositivo do terminal é para exibição lá, não é para colocá-lo lá de volta como entrada. Quando você faz(com
echo
stdout sendo o terminal), não é a mesma coisa que se você tivesse digitadotest
.Há um
ioctl
(TIOCSTI
) para colocar caracteres de volta como entrada, mas mesmo isso não funcionaria realmente porque você poderia colocá-lo novamente após o aplicativo já ter lido mais um pouco, portanto isso mudaria a ordem em que o aplicativo está lendo a entrada e, de qualquer maneira, isso significaria que você a leria repetidas vezes.fonte
Se o seu sistema operacional estiver suportando o dtrace, um script simples, shellsnoop , deve permitir que você monitore tudo o que é digitado / impresso em um determinado tty.
Se você estiver executando o Linux, o ttysnoop costumava fazer uma coisa semelhante, mas precisava de uma configuração intrusiva como pré-requisito e o AFAIK não é mais suportado pelos kernels atuais, então não ajudará no seu caso. Existem tentativas mais ou menos avançadas para fornecer rastreamento dinâmico com Linux, systemtap, ktap e até dtrace, para que você possa investigá-los.
Edit: Cuidado com o peekfd , sua página do manual declara:
Insetos:
Provavelmente muitos. Não se surpreenda se o processo que você está monitorando morre.
fonte
Essa abordagem envolve um pouco de gdb e tee. Ah, e também usa o socat para emular um pseudo-terminal. Pode funcionar sem ele, mas o usuário notará que sua saída não é mais um terminal (programas como o vi reclamarão).
Faz o seguinte:
Notei que o bash parece escrever o que você digita no stderr, não tenho certeza se outros programas fazem o mesmo. Se for esse o caso, o stdin não precisa ser interceptado.
Chamá-lo assim:
chmod +x /path/to/script; sudo /path/to/script <usr> <sys-adm>
.usr
esys-adm
são os nomes dos terminais, por exemplo/dev/pts/1
,. Assim, uma chamada de exemplo ficaria assim:sudo /path/to/script /dev/pts/1 /dev/pts/2
. Você pode descobrir o seu terminal com otty
comando E o terminal do usuário comw
oups
.fonte
Existe um programa C simples chamado xkey.c para mostrar as explorações do X11. Vou deixar você pesquisar no Google. Você pode capturar as teclas digitadas em um xterm usando isso sem que o usuário esteja ciente disso.
fonte
xterm
especificamente.