Del traductor
Estudiante de
la Universidad de Tufts dice cómo burlarse de su compañero de cuarto. Incluso me cubrió cuando comenzó su historia con el hecho de que tienen un televisor 4K en el albergue.
Introduccion
Antes de hablar sobre cómo traje al desafortunado Logan, debo explicar el sistema de medios en nuestra habitación. Pronto entenderás por qué.
Logan, si lees esto, espero que te hayas divertido más que no.
Disposición
Tenemos una computadora con una computadora de escritorio Ubunt conectada a un televisor. Él actúa como un servidor de medios. Como todavía necesita una conexión permanente a Internet, un servidor web con un par de páginas, un servidor SSH y una serie de otros servicios todavía están girando allí.
Debido al hecho de que la televisión es 4K, y la computadora está ensamblada a partir de lo que tenía a mano, su tarjeta de video no tira. Logan decidió comprar la vieja vidyuha de NVIDIA, lanzada hace un par de generaciones (que todavía es mucho mejor que la que era) para reproducir video 4K normalmente.
El nacimiento de una idea
Poco después de la instalación, obtuvimos un par de problemas técnicos con los controladores. En ese momento, pensé que sería divertido poder mostrar manualmente los mensajes de error.
Después de algunas búsquedas en Internet, quedó claro que invocar remotamente un mensaje en un televisor es tan simple como:
- Inicie sesión a través de SSH en la computadora como el usuario que ejecuta la transmisión
DISPLAY=:0 zenity --info --text '!'
DISPLAY=:0
necesario, porque en mi sesión no hay visualización, pero quiero mostrar el mensaje en la pantalla principal.
Como tuvimos problemas con NVIDIA vidyuha, decidí pensar en algo como:
DISPLAY=:0 zenity --warning --text ' .'
Funcionó, pero cada vez que iniciar sesión en el servidor utilizando el cliente SSH para bajar Logan es un placer. Entonces decidí hacer trampa. Pensé en la tarea de la corona para enfurecerlo en un horario, pero hubo un par de problemas:
- En realidad, regularidad
- Tuvimos otras tareas en la corona, lo que aumentó el riesgo de revelar mi tarea insidiosa
Otras opciones como el script SysVInit se descartaron por los mismos motivos. Por lo tanto, decidí hacer una página web pública con el botón "Have a Logan".
Preparación del sorteo
Pensé que necesitaría un par de cosas para comenzar:
- Algo que maneja la entrada del usuario
- Algo que ejecuta comandos arbitrarios como usuario web
Entonces llegué a:
- Nginx
- Extensión FPM para NGINX
- Php
- Paquete FPM para PHP
Como resultado, hice un sitio con la página de inicio logan.html y la "página de acción"
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>
Hay una pequeña tontería en las
meta
para adaptar la página a los teléfonos móviles (¿recuerdas que hago que sea fácil de usar mientras viajas?) Para aquellos que no saben cómo representar HTML en mi cabeza, te muestro cómo se ve:

Cuando se presiona el botón, la solicitud POST vuela a otra página, que hace todo el trabajo sucio:
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 hace varias cosas:
- Selecciona un mensaje de error aleatorio.
- Selecciona el tipo de cuadro de diálogo.
- Demuestra un mensaje por un período de tiempo específico (10 segundos)
- Dibuja un botón y explica lo que está sucediendo, todo acompañado de la divertida foto de Logan en persona.
Para aquellos que aún no pueden representar HTML en sus cabezas (nuevamente, con suerte, la mayoría de las personas), la página se ve así:

Si se pregunta por qué la página web puede ejecutar código de esta manera, y por qué el propietario de la sesión del servidor web (
www-data
) puede ejecutar comandos como usuario de pantalla (el usuario de la pantalla), puede estar feliz de saber que
thedisplayuser
esto severamente a archivo
sudoers
:
Esta parte específica de la configuración permite que www-data se ejecute solo / usr / bin / zenity como el usuario de pantalla sin contraseña. Hice esto después de equivocarme con errores estúpidos en la configuración de PHP y NGINX. Luego envié la URL a un par de amigos en el campus que conocen a Logan.
Resultado del sorteo
Alabado sea el cielo, Logan reaccionó tan violentamente como pudo. Si hubiera estado un poco molesto, la idea de que mis esfuerzos se hubieran desperdiciado me habría molestado. Pero no! Perdió los estribos. No puedo contar cuántos reinicios, reinstalaciones de controladores y modificaciones de kernel hubo. Solo lamento no haber filmado un video sobre cómo se enojó después de iniciar VLC, cuando alguien arrojó un montón de ventanas con mensajes sobre errores de la tarjeta de video.
Pero me dejé llevar demasiado, y Chris, nuestro otro compañero de cuarto, decidió intervenir ...
Caza del cazador
Primera etapa
Un buen día, cuando Logan estaba durmiendo, noté un mensaje de error que decía: "Max está detrás de todo esto". Choooo? Tengo una broma! Entonces, comencé a entender y descubrí que alguien (Chris) introdujo esta frase en un conjunto de mensajes aleatorios en
zenity.php
. Lo eliminé rápidamente (hasta que Logan escuchó que lo estaban jugando) y decidí que la diversión había terminado. Ahí estaba.
Segunda etapa
Después de una semana más o menos, el mensaje apareció de nuevo. Pensé que Chris me había quemado y lo volví a agregar a la lista. No es una maldita cosa. El no estaba allí. Después de un estudio cuidadoso del archivo, noté que ahora se llama
/usr/sbin/zenity
lugar de
/usr/bin/zenity
(el sistema predeterminado), y los
sudoers
tenían una entrada permisiva correspondiente. Entonces, ¿qué es
/usr/sbin/zenity
? Script de shell:
Bueno, ese era el siguiente nivel de mierda, si alguna vez me encontraba con algo así. El 99% del tiempo todo funcionó como debería, y en el uno por ciento restante apareció el mensaje "Max se queda atrás". Eliminé el archivo (lo sé, no valió la pena) y escribir a
sudoers
devolvió
zenity.php
a su forma original. Los mensajes han dejado de aparecer. Pero luego volvieron.
Tercera etapa
zenity.php
. Nada nuevo
/usr/sbin/zenity
? Desaparecido Estoy desanimado Entonces decidí mirar dentro
/usr/bin/zenity
:
Pequeño bastardo astuto. Él arregló el binario zenity, convirtiéndolo en un script bash que funciona una vez y 70. ¿Qué demonios? ¿Y qué tipo de
rpmdb-client
? Entonces, me defendí cambiándolo:
¿Captó la diferencia? De lo contrario, se llama
/usr/sbin/rpmdb-client
lugar de
/usr/bin/rpmdb-client
, que lanza un script bash que no hace nada. Con suficiente suerte, no notará un personaje extra y su mensaje nunca aparecerá.
TODO: Comprenda la diferencia entre los ejecutables ELF
/usr/sbin/zenity
y el
/usr/bin/rpmdb-client
que Chris creó. Hay alguna diferencia extraña en los binarios que aún no he entendido.
Cuarta etapa
Decidí fortalecer la defensa, hasta que Chris notó la diferencia en una carta descrita anteriormente. Cancelé todos mis cambios y decidí parchear
zenity
en
zenity
lugar. Profunda gratitud a Tom Hebb (como en todas mis publicaciones técnicas) por ayudarme con esto. Esto es lo que hice:
apt
configurado para descargar las fuentes (en este caso, agregar deb-src
a /etc/apt/sources.list
)apt-get source zenity
- Hizo un parche con
quilt
:
quilt new myPatch.diff
- Un parche para
src/msg.c
que determina la presencia de la palabra "Max" en el cuerpo del mensaje:
quilt add src/msg.c
quilt pop
dpkg-source --commit
dpkg-buildpackage -us -uc
- Me di cuenta de que crear e instalar un nuevo paquete es más pálido que reemplazar un binario
- Reemplazó silenciosamente el
rpmdb-client
(su zenity
) con mi versión - Palmeó su espalda
Este parche cambia el comportamiento de
zenity
de tal manera que, tan pronto como aparece la palabra "Max" en el texto del mensaje, la aplicación no hace nada en silencio.
Conclusión
Hasta finales de marzo, Chris nunca descubrió que había corregido el binario. Como resultado, Logan no vio un solo mensaje con mi nombre. Así que decidí continuar el rally hasta que le dije todo después del final del curso. Pero cuando las clases terminaron, nos separamos. Aunque Logan y yo volveremos a vivir juntos el próximo año, lo más probable es que no pasemos tanto tiempo en la sala para que la concentración tenga sentido. Así que decidí publicar esta publicación antes de comenzar nuevos trucos.