Do tradutor
O estudante da
Universidade Tufts conta como provocar o colega de quarto. Ele até me prendeu quando começou sua história com o fato de que eles tinham uma TV 4K no albergue.
1. Introdução
Antes de falar sobre como trouxe o infeliz Logan, devo explicar o sistema de mídia em nossa sala. Em breve você entenderá o porquê.
Logan, se você leu isso, espero que tenha se divertido mais do que não.
Disposição
Temos um computador com um Ubunt de mesa conectado a um aparelho de TV. Ele atua como um servidor de mídia. Como ele ainda precisa de uma conexão permanente com a Internet, um servidor da Web com algumas páginas, um servidor SSH e vários outros serviços ainda estão funcionando lá.
Devido ao fato de que a televisão é 4K e o computador é montado a partir do que estava à mão, sua placa de vídeo não é puxada. Logan decidiu comprar o velho NVIDIA vidyuha, lançado há algumas gerações (o que ainda é muito melhor do que era) para reproduzir vídeo 4K normalmente.
O nascimento de uma ideia
Logo após a instalação, descobrimos algumas falhas nos drivers. Naquele momento, pensei que seria divertido poder exibir manualmente mensagens de erro.
Após algumas pesquisas na Internet, ficou claro que chamar remotamente uma mensagem na televisão é tão simples quanto:
- Efetue login via SSH no computador como o usuário executando a transmissão
DISPLAY=:0 zenity --info --text '!'
DISPLAY=:0
necessário, porque na minha sessão não há exibição, mas quero mostrar a mensagem na tela principal.
Como tivemos problemas com o NVIDIA vidyuha, decidi me concentrar em algo como:
DISPLAY=:0 zenity --warning --text ' .'
Funcionou, mas cada vez que efetuar login no servidor usando o cliente SSH para baixar o Logan é um prazer. Então eu decidi trapacear. Pensei na tarefa da coroa de enfurecê-lo dentro do cronograma, mas havia alguns problemas:
- Na verdade, regularidade
- Tivemos outras tarefas na coroa, o que aumentou o risco de divulgar minha tarefa insidiosa
Outras opções como o script SysVInit foram descartadas pelos mesmos motivos. Por isso, decidi criar uma página pública com o botão "Have a Logan".
Preparação do sorteio
Imaginei que precisaria de algumas coisas para começar:
- Algo que manipula a entrada do usuário
- Algo executando comandos arbitrários como um usuário da web
Então eu vim para:
- Nginx
- Extensão FPM para NGINX
- Php
- Pacote FPM para PHP
Como resultado, criei um site com a página de
logan.html
logan.html e a "página de ação"
zenity.php
:
logan.html <html> <head> <style type="text/css"> form button { font-size: 20px; } div.explanation { width: 400px; } </style> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="HandheldFriendly" content="true"> </head> <body> <form method="POST" action="/zenity.php"> <button> </button> </form> </body> </html>
Há um pouco de absurdo nas
meta
para adaptar a página para celulares (lembre-se de que eu facilito o uso em qualquer lugar?) Para aqueles que não sabem como renderizar HTML na minha cabeça, mostro como fica:

Quando o botão é pressionado, a solicitação POST voa para outra página, que faz todo o trabalho sujo:
zenity.php <?php $messages = Array( " .", " .", " .", " .", " .", " .", " .", " .", " .", " .", " and has recovered.", " .", " .", " .", " .", " .", " .", " NVIDIA .", "NVIDIA - . ( 43)", " wlx10bef54d395c." ); $statuses = Array("error", "warning"); $msg = $messages[array_rand($messages)]; $status = $statuses[array_rand($statuses)]; $timeout = "--timeout 10"; exec("sudo -u thedisplayuser /usr/sbin/zenity --$status --display=:0 --text ': $msg' $timeout > /dev/null &"); include 'logan.html'; ?> <div class="explanation"> , . , // .. </div> <br /> <img src='/logan.jpg' />
Esta página faz várias coisas:
- Seleciona uma mensagem de erro aleatória
- Seleciona o tipo de caixa de diálogo.
- Demonstra uma mensagem por um período especificado (10 segundos)
- Ele aperta um botão e explica o que está acontecendo - tudo acompanhado pessoalmente pela imagem engraçada de Logan
Para aqueles que ainda não conseguem renderizar HTML em suas cabeças (novamente, esperamos que a maioria das pessoas), a página fica assim:

Se você estiver surpreso por que uma página da Web pode executar código dessa maneira e por que o proprietário de uma sessão do servidor da Web (
www-data
) pode executar comandos como um usuário de exibição (
thedisplayuser
), você ficará feliz em saber que eu
thedisplayuser
severamente arquivo
sudoers
:
Essa parte específica da configuração permite que www-data execute apenas / usr / bin / zenity como o usuário da tela sem uma senha. Eu fiz isso depois de mexer com erros estúpidos nas configurações PHP e NGINX. Então enviei o URL para alguns amigos no campus que conhecem Logan.
Resultado do sorteio
Louvado seja o céu, Logan reagiu o mais violentamente possível. Se ele estivesse um pouco irritado, o pensamento de que meus esforços haviam sido desperdiçados teria me irritado. Mas não! Ele perdeu a paciência. Não consigo contar quantas reinicializações, reinstalações de drivers e modificações no kernel houve. Só lamento não ter gravado um vídeo sobre como ele ficou louco depois de iniciar o VLC, quando alguém abriu um monte de janelas com mensagens sobre erros na placa de vídeo.
Mas fiquei muito empolgado e Chris, nosso outro colega de quarto, decidiu intervir ...
Caça ao caçador
Primeira etapa
Um belo dia, quando Logan estava dormindo, notei uma mensagem de erro que dizia: "Max está por trás de tudo isso". Choooo? Eu tenho uma brincadeira! Então, comecei a entender e descobri que alguém (Chris) introduziu essa frase em um conjunto de mensagens aleatórias no
zenity.php
. Eu o apaguei rapidamente (até Logan saber que eles estavam tocando) e decidi que a diversão havia terminado. Lá estava.
Segunda etapa
Depois de uma semana ou mais, a mensagem apareceu novamente. Eu pensei que Chris me tivesse queimado e re-adicionado à lista. Nada. Ele não estava lá. Após um estudo cuidadoso do arquivo, notei que agora ele é chamado
/usr/sbin/zenity
vez de
/usr/bin/zenity
(o padrão do sistema), e os
sudoers
tinham uma entrada permissiva correspondente. Então, o que é
/usr/sbin/zenity
? Script de shell:
Bem, esse foi o próximo nível de merda, se eu já conheci algo assim. 99% das vezes tudo funcionava como deveria e, no restante, um por cento da mensagem "Max está por trás" apareceu. Excluí o arquivo (eu sei, não valia a pena) e escrever para
sudoers
trouxe o
zenity.php
à sua forma original. As mensagens pararam de aparecer. Mas então eles voltaram.
Terceira etapa
Eu verifiquei o
zenity.php
. Nada de novo.
/usr/sbin/zenity
? Desapareceu. Estou desanimado. Então eu decidi olhar dentro de
/usr/bin/zenity
:
Bastardo astuto. Ele consertou o binário do zenity, tornando-o um script bash que funciona uma vez e 70. Que diabos? E que tipo de
rpmdb-client
? Então, lutei de volta mudando:
Você percebeu a diferença? Caso contrário,
/usr/sbin/rpmdb-client
é chamado em vez de
/usr/bin/rpmdb-client
, que inicia um script bash que não faz nada. Com sorte suficiente, ele não notará um caractere extra e sua mensagem nunca aparecerá.
TODO: Entenda a diferença entre os executáveis do ELF
/usr/sbin/zenity
e o
/usr/bin/rpmdb-client
que Chris criou. Há alguma diferença estranha nos binários que eu ainda não entendi.
Quarta etapa
Eu decidi fortalecer a defesa, até Chris perceber a diferença em uma letra descrita acima. Cancelei todas as minhas alterações e decidi corrigir o
zenity
. Profunda gratidão a Tom Hebb (como em todos os meus posts técnicos) por me ajudar com isso. Aqui está o que eu fiz:
- Configurado o
apt
para baixar os fontes (neste caso, adicionando deb-src
ao /etc/apt/sources.list
) apt-get source zenity
- Feito um patch com
quilt
:
quilt new myPatch.diff
- Um patch para
src/msg.c
que determina a presença da palavra "Max" no corpo da mensagem:
quilt add src/msg.c
quilt pop
dpkg-source --commit
dpkg-buildpackage -us -uc
- Percebi que criar e instalar um novo pacote é mais pálido do que substituir um binário
- Substituiu silenciosamente o
rpmdb-client
(sua zenity
) pela minha versão - Deu um tapinha nas costas
Esse patch altera o comportamento do
zenity
forma que, assim que a palavra "Max" aparece no texto da mensagem, o aplicativo silenciosamente não faz nada.
Conclusão
Até o final de março, Chris nunca descobriu que eu corrigi o binário. Como resultado, Logan não viu uma única mensagem com meu nome. Então decidi continuar o rali até contar tudo a ele depois do final do curso. Mas quando as aulas terminaram, nos separamos. Embora Logan e eu moremos juntos novamente no próximo ano, provavelmente não passaremos tanto tempo na sala para que o rali faça sentido. Decidi publicar este post antes de iniciar novos truques.