¿Qué tiene de especial "!xxx%s%s%s%s%s%s%s%s"?

¿Qué tiene de especial "!xxx%s%s%s%s%s%s%s%s"?

yo estaba vinculado aEl manual de los que odian a Unixy tropecé con (página 149):

Asunto: Error relevante de Unix

11 de octubre de 1991

Compañeros estudiantes de W4115x:

Ya que estamos en el tema de los registros de activación, la transferencia de argumentos y las convenciones de llamada, ¿sabías que escribir:

!xxx%s%s%s%s%s%s%s%s

a cualquier C-shell provocará que se bloquee inmediatamente? ¿Sabes por qué?

Preguntas para pensar:

  • ¿Qué hace el shell cuando escribes !xxx?
  • ¿Qué debe estar haciendo con su entrada cuando escribe !xxx%s%s%s%s%s%s%s%s?
  • ¿Por qué esto bloquea el shell?
  • ¿Cómo podrías (con bastante facilidad) reescribir la parte ofensiva del shell para no tener este problema?

Por pura curiosidad, ¿alguien puede explicar cuál fue el problema? Como era de esperar, buscar la cadena en Google no ayuda. La búsqueda de otras citas del mensaje solo me dio otras copias del mensaje, pero ninguna explicación.

Respuesta1

No tengo ganas de buscar fuentes de proyectiles de hace 25 años, pero

Podría ser unvulnerabilidad de cadena de formato.

Si el shell contiene código como

printf(str);

donde strse toma una cadena de la entrada del usuario, el contenido de la cadena será la cadena de formato que printfutiliza. Los %s's indican printfque se imprima una cadena apuntada por un argumento. Si no se proporcionan los argumentos (como arriba, solo está la cadena de formato), la función leerá algunos otros datos de la pila y los seguirá como punteros. Probablemente accediendo a memoria no asignada y bloqueando el proceso.

En cierto modo, creo que la redacción del mensaje también sugiere una solución como ésta. Si escribe !xxx, lo que hace visiblemente el shell es imprimir un mensaje de error como !xxx: event not found. A partir de ahí, no hay un gran salto para intentar imprimir también !xxx%s%s%s%s%s%s%s%s: event not found, con la implicación de una vulnerabilidad de cadena de formato.


No debería haberlo hecho, pero eché un vistazo a la fuente.aquí( 4.3BSD-Tahoe/usr/src/bin/csh, las fechas son de 1988).

findev(cp, anyarg)ensh.lex.cParece que podría ser la función para encontrar un evento histórico coincidente: recorre una lista vinculada de struct Histllamadas Histlist. Si no encuentra nada, seterr2(cp, ": Event not found");llama noev(). cpAquí parece estar la cadena que se busca en el historial.

seterr2()establece la variable errcomo concatenación de los argumentos y errse usa como if (err) error(err);en un par de lugares en process(), ensh.c. Finalmente, error()(ensh.err.c) contiene una vulnerabilidad de cadena de formato clásico:if (s) printf(s, arg), printf(".\n");

En algunos otros lugares, error()se llama con un argumento, como error("Unknown user: %s", gpath + 1);, por lo que claramente la idea es que el primer argumento error()pueda ser una cadena de formato.

No sería honesto si dijera que entendí completamente las funciones de sustitución del historial. Es un manejo manual de cadenas prácticamente sin comentarios en C. %Tiene un significado especial en la sustitución del historial, pero solo puedo ver que se maneja especialmente cuando se llama al primer carácter (como en !%) o después .findev()

información relacionada