
Esta publicación es una versión de texto de mi
charla en el 35 ° Congreso de Computación del Caos a fines de 2018.
De modo que debo admitir que MS-DOS está un poco indignado, a pesar de que el malware MS-DOS siempre me ha fascinado hasta cierto punto, pero primero debemos preguntarnos: "¿Qué es DOS?"
- DOS es una versión de CP / M, otro sistema operativo muy antiguo.
- La familia DOS abarca una amplia gama de proveedores, simplemente porque sea DOS no significa que se ejecutará en una CPU 8086 o mejor
- ¡Algunos de estos proveedores de DOS tienen compatibilidad API, lo que significa que algunos de ellos usan malware!
Video de rendimiento:
La publicación fue escrita con el apoyo de EDISON Software, que desarrolla una aplicación para un operador móvil virtual y se dedica al desarrollo y mantenimiento de sitios en Python .

Pero, de hecho, la mayoría de nuestros recuerdos de la era de DOS son la estética de cómo se veían las computadoras de esa época:

Esta es la era de la "computación beige" y el teclado Modelo M, que puede ser famoso o infame dependiendo de si te gusta el teclado ruidoso o no.

¡Algunos de nosotros podemos tener recuerdos de usar DOS, y algunos aún pueden usar DOS!

Por ejemplo, se rumorea que George R. Martin, quien escribió The Game of Thrones, usó Wordstar en DOS para escribir un libro.

Tampoco podemos perdernos QBASIC, ¡para muchos este sería su primer conocimiento de la programación!

Pero a veces la vida usando DOS no era tan buena, a veces usabas DOS, y cosas así sucedieron de repente. En este ejemplo, se reproduce una pequeña melodía durante la impresión, por lo que puede ser una situación muy incómoda en un entorno de oficina.

Algunos de ellos son más "lindos", en este caso, por ejemplo, pasa una ambulancia dibujada con símbolos ascii, y luego el programa que desea abrir se inicia, en el peor de los casos, con pequeños inconvenientes.
Gracias a un grupo de archiveros de malware que se ejecutan bajo el nombre de VX Heavens, tenemos un buen archivo histórico de malware de DOS, o al menos hasta que la policía ucraniana asalte el sitio:
El viernes 23 de marzo, la policía incautó el servidor en relación con una investigación criminal (artículo 361-1 del Código Penal de Ucrania - creación de malware con el propósito de venderlo o distribuirlo) en base a las indicaciones de alguien. sobre "poner en acceso libre software malicioso diseñado para el pirateo no autorizado de computadoras, sistemas automatizados, redes de computadoras".
Afortunadamente, los sitios populares de torrents todavía tienen copias de la base de datos del sitio que nos pueden proporcionar un excelente conjunto de datos:
$ tar -tvf viruses-20070914.tar | wc -l 66714 $ ls -alh viruses-20070914.tar 6.6G viruses-20070914.tar
Sin embargo, para comenzar a estudiar estas muestras, primero debemos comprender el flujo de distribución típico de estas muestras, dado que estos programas funcionaron en la era previa a Internet:

Después de recibir un archivo infectado en su sistema y ejecutarlo, el programa malicioso buscará activamente o instalará interceptores de llamadas del sistema para los programas que ejecuta. A menudo hace esto de una manera sutil e invisible para evitar ser detectado. La importancia de la sutileza es importante porque para distribuir este programa malicioso debe transferirlo a otro sistema utilizando un medio (disquete) o descargarlo a otro punto de distribución, como BBS.

En tiempo de ejecución, el malware tiene dos opciones; puede permanecer oculto e infectar nuevos archivos o mostrar una carga útil.
¡Algunas cargas útiles son bastante bonitas! El siguiente ejemplo utiliza funciones inusuales, como 256 colores:

O este que juega con tu búfer de pantalla:


Sin embargo, en su mayor parte, el malware permanecerá en silencio e intentará encontrar archivos para la infección. La infección de la mayoría de los archivos es muy simple, por ejemplo, si ve el archivo COM como una larga cinta de código de máquina:

Entonces "todo lo que tiene que hacer" es insertar JMP al comienzo del programa y agregar datos al final del programa. Se verá más o menos así:

Algunos códigos fueron más inteligentes y encontraron "espacio vacío" en el archivo binario y se escribieron allí, lo que evitó que el archivo binario aumentara de tamaño, lo que, posiblemente, significaba que el antivirus podía usar la bandera roja.

Sin embargo, antes, también mencioné las llamadas del sistema interceptor. A pesar de que el tiempo de ejecución de MS-DOS es muy simple y prácticamente desprotegido (puede cargar Linux de manera trivial desde un archivo COM). Todavía contiene la API completa para que las aplicaciones no necesiten tener su propia implementación del sistema de archivos. Estas son algunas características de syscalls:

Funcionan causando una interrupción de software, en la que el programa le pide al procesador que se mueva a otra sección de la memoria del sistema para procesar algo:

Sin embargo, MS-DOS también ofrece la capacidad de agregar / modificar estas llamadas (usando otra llamada), lo que le permite expandir el sistema para que los nuevos controladores puedan cargarse en tiempo de ejecución. Sin embargo, también es un lugar ideal para agregar intercepciones de malware:

Fue un truco bien utilizado, porque podía interceptar la llamada "Abrir archivo" y luego usarla para detectar nuevos archivos ejecutables en el sistema ... e infectarlos.
Como un ejemplo rápido de cómo se usan, veamos un simple programa Hello World:

Como podemos ver, hay dos llamadas de tipo
int
. Usamos
21h
(h = hexadecimal) como el número de llamada del sistema principal, y podemos especificar qué acción queremos que realice MS-DOS en función del valor de
Ah

En este caso, el programa realiza una llamada para imprimir la línea y luego sale con el código de retorno 0 (indefinido).
Como se mencionó anteriormente. Cuando llame a int 21h, el procesador central buscará en la tabla IVT dónde ir, dentro de este controlador a menudo hay un segmento como un enrutador que enruta varias llamadas principales, en el caso de Int 21h dirige a varias funciones basadas en el valor ah. Tan pronto como lleguemos al lugar, el administrador de llamadas real se encargará de la tarea, luego ejecutará iret para volver al programa principal, a menudo dejando registros de los resultados de la llamada:

Entonces Si queremos ver todas las llamadas del sistema que inició el programa, podemos establecer un punto de interrupción al comienzo del controlador de interrupciones y verificar qué es ah:

Hacemos esto porque el controlador de interrupciones siempre está en un lugar fijo en MS-DOS (esto es mucho antes que la era ASLR y ASLR de Kernel), y la ubicación del programa no lo está.

Una vez que lo lancemos, podemos ver los desafíos que plantea este patrón. Si bien podemos ver en la pantalla que acaba de imprimir una notificación sobre el archivo Goat (Goat es un archivo diseñado para infectar, como una cabra sacrificada). También vemos que este programa hace más que simplemente imprimir una línea. ¡Comprueba la versión de DOS (probablemente para verificar la compatibilidad) y luego abre, lee y escribe datos!

Esto es interesante! Pero nos gustaría saber más sobre lo que el sistema llama resaltado en rojo, ya que deben tener entrada para cosas como nombres de archivos y datos para escribir en archivos / resultados en la pantalla.
Para hacer esto, necesitamos mirar otros registros durante syscall:

Usando "Cadena de impresión" como un ejemplo simple, podemos ver cómo se ve el uso:

¿Qué es DS: DX? ¿Por qué hay dos registros aquí y cómo obtenemos datos de ellos?
Para hacer esto, necesitamos entender un poco más sobre el procesador 8086.

El procesador 8086 es una CPU de 16 bits, pero con direccionamiento de memoria de 20 bits. Esto significa que el procesador solo puede almacenar valores que indican 64 KB, esto es un problema cuando la capacidad de memoria es de hasta 1 MB.
Para evitar esto, necesitamos comprender los registros de segmentación:

El procesador 8086 tiene 4 registros de segmentación que debemos cuidar:
- CS - segmento de código
- DS - segmento de datos
- SS - segmento de pila
- ES: un segmento adicional (en caso de que necesite uno más para sortear diferentes situaciones)
Hay una serie de otros registros de uso general que lo salvan del uso excesivo de memoria y le permiten pasar parámetros a otras funciones.
La segmentación registra el trabajo cambiando el bloque en la RAM:

Esto permite que la CPU de 16 bits vea los 20 bits de RAM, asegurando que para cada valor DS el bloque esté compensado por 16 bytes.

En este caso, la llamada DS se usa como un puntero dentro de la ventana de 16 bits con respecto a dónde está el comienzo de la línea. Luego, la impresora de líneas escaneará hasta encontrar el carácter $ y luego se detendrá. Esto es similar a otros sistemas que usan bytes nulos en lugar de $.

Con la edad de ISA x86, poco ha cambiado, en lugar del hecho de que el tamaño de bits del procesador ha aumentado, los mismos registros se han ampliado.
Entonces, con este conocimiento, podemos crear una lista de "tareas" para rastrear estos programas:

Con esta configuración, ¡podemos lanzar varias computadoras grandes al problema durante varias horas y obtener los resultados!

Y tenemos ...

Nada de eso.
Esto es decepcionante.
¡Quemamos al menos un valor de poder de hámsters y casi no obtuvimos activaciones geniales!
(Xs cómo traducir esto)
Si miramos algunas muestras, veremos una pistola humeante aquí. Una muestra decente verifica la fecha o la hora.
Si miramos la documentación de estas llamadas, veremos que la llamada del sistema devuelve valores en forma de registros para el programa:

¡Entonces podemos forzarlos con fuerza bruta! Todo lo que necesitamos hacer es algo como esto:

Pero hay un problema con este método.

El paso de probar el ejemplo lleva unos 15 segundos, ya que utiliza el proceso completo de emulación qemu, y puede llevar hasta 15 segundos ejecutar completamente el programa en la máquina virtual. Dado que DOS no tiene características de ahorro de energía, esto significa que cuando DOS está en modo de espera, está en un
ciclo ocupadoPor lo tanto, podríamos ver este problema de manera diferente al ver qué código se ejecutará después de la solicitud de fecha / hora.
Como nuestro rastreador está en el controlador de interrupciones, no sabemos desde el cuadro dónde se encuentra el programa:

Para hacer esto, debemos mirar la pila donde nos esperan los registros CS e IP.

Tan pronto como tomemos estos dos registros de la pila, podemos usarlos para obtener el código de retorno para que nuestra lista de verificación se vea así:

Una vez que hayamos hecho esto y hayamos probado repetidamente el conjunto de datos, ¡veremos cómo se ve la parte del código de retorno!

Aquí hay una muestra de uno. Aquí vemos que se hace una comparación para DL y 0x1e.

Si miramos nuestra documentación, veremos que DL es el día del mes, es decir, podemos analizar los tres códigos de operación principales de la siguiente manera:

Podríamos revisar todo esto manualmente, pero hay muchas de estas muestras que verifican la hora, alrededor de 4700:

Entonces, en cambio, necesitamos hacer otra cosa. Necesitamos escribir algo ... Necesitamos escribir ...

El peor emulador x86 del mundo, llamado BenX86, es un emulador diseñado específicamente para nuestras necesidades, y nada más:

Pero tiene algunas ventajas en su velocidad.


Agregamos 10,000 pruebas de ejecución diferentes basadas en las rutas que encontramos usando la fuerza bruta con BenX86. Por lo tanto, terminaré con algunos de mis descubrimientos favoritos que se activan con el tiempo:

Este patrón se activa el día de Año Nuevo y cuelga su sistema después de que se muestra un saludo. Puede ser bueno si está atrapado en la oficina para el año nuevo, o puede ser malo si realmente necesita hacer algo el día de Año Nuevo.

Este ejemplo me sorprendió mucho. Se activa a principios de 1995 e informa al usuario sobre todos los archivos infectados que infectó, y luego elimina el virus (eliminando la transición al principio) y luego no hace nada más. Aunque por alguna razón dice que debe comprar McAfee, este mensaje obviamente no está desactualizado.

Esto, francamente, realmente me confunde, el 8 de noviembre de cualquier año, convertirá todos los ceros del sistema en pequeños glifos de "odio". Realmente me molesta si sabes por qué lo necesitas, házmelo saber ...

Esta es probablemente mi pesadilla cuando, después de iniciar cualquier programa, muestra un mensaje de que no pudo comer su disco principal. Sería increíblemente perturbador ver de la nada.

En conclusión, tenemos cuál es la versión Navy Seal Copypasta del malware DOS. No estoy seguro de que a este autor no le guste Aladdin, pero hagas lo que hagas, eres una persona.
Si está interesado en el código que se ejecutó en este artículo,
lancé mi kit de herramientas en github , sin ninguna garantía. Si desea crear este código usted mismo, deberá trabajar para asegurarse de que funciona con su instalación de MS-DOS (arreglar un punto de interrupción del controlador)
Sin embargo, si solo mira para ver lo que vi mientras miraba este proyecto, he archivado la interfaz web aquí:
dosv.benjojo.co.ukHasta pronto!