El nombre del programa fantasma

22 views
Skip to first unread message

occams...@uvigo.es

unread,
Apr 9, 2011, 8:25:57 AM4/9/11
to revista-oc...@googlegroups.com
Hola a todos,

Uno de nuestros lectores, Carlos, encontró un problema con el impío
programa fantasma: Si en lugar de utilizar el comando "ps axe" que
sugerimos en el artículo, utilizamos el comando "ps" sin parámetros,
el nombre del proceso no cambia.

Un comportamiento bastante misterioso verdad?. Pero ¿qué se podía
esperar de un programa fantasma?.

Para resolver el misterio hemos tenido que echarle un vistazo al
código fuente de "ps" que se puede encontrar en el paquete "procps"
(http://procps.sourceforge.net/). Si analizamos detenidamente el
código veremos que la forma de obtener el nombre del proceso es
diferente cuando pasamos parámetros a la aplicación que cuando no.

En un caso utiliza el contenido de /proc/PID/cmdline, y en el otro
utiliza el contenido de /proc/PID/stats. Donde PID es el identificador
del proceso que queremos consultar.

Como recordaréis, el programa fantasma simplemente sobreescribe el
argumento argv[0], el cual contiene la cadena de caracteres que
pasamos a la línea de comandos cuando lo ejecutamos. Pero ese no es
realmente el nombre del proceso, es solo una cadena de caracteres que
se almacena en el área de la memoria que contiene los parámetros que
recibe el programa y a la que podemos acceder a través de
/proc/PID/cmdline. Sin embargo, /proc/PID/stat contiene el nombre real
del proceso.

Lo que nuestro lector nos sugería era utilizar la llamada al sistema
"prctl" que, una de las cosas que nos permite hacer, es cambiar el
nombre del proceso. Eso hace que tanto "ps" como "ps axe" muestren el
nombre que nosotros queramos, sin embargo, esto tiene un efecto
secundario fatal para nuestro programa fantasma. Esa función cambia el
verdadero nombre del proceso, de forma que el comando "killall" nos va
a permitir matarlo (de ahí lo de fatal), utilizando el nombre que nos
muestre el comando ps.

Pero lo que nosotros queremos es que el nombre que devuelve "ps" sea
falso, de forma que no sea posible utilizar el comando "killall" para
acabar con nuestro pequeño espectro. El comando "kill" ya queda
inutilizado con las continuas llamadas a "fork" que cambian el
identificador del proceso cada segundo.

Así que, ¿cuál es la solución a este intrigante misterio?

La solución nos viene del inframundo, de la mano de los demonios.
Cuando ejecutamos "ps" sin parámetros, el comando nos muestra la lista
de procesos asociados al terminal/sesión en la que nos encontramos.
Sabiendo esto, lo único que tenemos que hacer es liberar a nuestro
programa fantasma de su sesión y eso es algo que todos los demonios
saben hacer muy bien.

¿Cómo conseguimos este resultado?. Simplemente haciendo un "fork" al
principio del programa, matando al proceso padre y, a continuación,
ejecutando la llamada al sistema "setsid" que crea una nueva sesión y
asigna un nuevo identificador de grupo de procesos. Algo como esto:

if (fork () > 0) exit (0);
setsid ();

De esta forma el proceso deja de estar asociado al terminal, ya no
aparece con el comando "ps", y lo que "ps axe" nos mostrará será el
nombre falso que maléficamente hemos usado para ocultar el programa
fantasma. Ahora solo aquel que inicia el proceso conoce su nombre
verdadero y tienen la capacidad de fulminarlo :)

En este caso, ni siquiera root tienen el poder para averiguar esa
información sin más. La única forma (que nosotros sepamos) es
modificar el código fuente de "ps" para que, incluso cuando se ejecute
con parámetros, tome el nombre del proceso del fichero
/proc/PID/stat... alguien se anima a crear esa versión "ghostbuster"
de ps?


Saludos y muchas gracias Carlos!

P.D.: Sí, podemos añadir la llamada al sistemas setsid() en nuestro
bucle principal y ahorrarnos el primer fork(), pero en ese caso,
estaríamos ejecutándola cada segundo, y solo necesitamos ejecutarla
una vez.


--
Por que lo más sencillo es lo más probable
http://webs.uvigo.es/occams-razor

Reply all
Reply to author
Forward
0 new messages