Writeup — GhostAV
Todas las detecciones y resultados se comprobaron enviando los ficheros al motor real (localhost:8888). Cada versión limpia se ejecutó antes con Python para confirmar que sigue imprimiendo su TAREAN_OK.
Tarea 1 — Firma de cadena
Firma de cadena★
Cómo llega (detectado):
$ cat tareas/tarea1.py
# GHOST_MALWARE_TAG (marca de version dejada por el equipo)
print("TAREA1_OK")GhostAV busca literalmente la cadena GHOST_MALWARE_TAG. Como es un comentario que no hace nada, basta con borrarlo:
Versión limpia:
$ cat tareas/tarea1.py
print("TAREA1_OK")Flag: GO{una_cadena_literal_se_ve_a_simple_vista}
Tarea 2 — Firma por hash
Firma por hash★
Cómo llega (detectado):
$ cat tareas/tarea2.py
def diagnostico():
print("TAREA2_OK")
diagnostico()El motor tiene en lista negra el SHA-256 exacto de este fichero. Cambiar cualquier byte (aquí, añadir un comentario inofensivo) genera un hash distinto que ya no está en la lista:
Versión limpia:
$ cat tareas/tarea2.py
def diagnostico():
print("TAREA2_OK")
diagnostico() # revisado por el equipoFlag: GO{un_byte_distinto_cambia_todo_el_hash}
Tarea 3 — Combinación de APIs
subprocess + call★★
Cómo llega (detectado):
$ cat tareas/tarea3.py
import subprocess
subprocess.call(["echo", "TAREA3_OK"])La regla se dispara cuando aparecen juntas las palabras subprocess y call. Otra API equivalente ejecuta lo mismo sin usar ninguna de las dos:
Versión limpia:
$ cat tareas/tarea3.py
import os
os.system("echo TAREA3_OK")Flag: GO{hay_mas_de_una_forma_de_lanzar_un_comando}
Tarea 4 — Entropía alta
Entropía★★
Cómo llega (detectado):
$ cat tareas/tarea4.py
import base64
_b = "bXNn...(blob base64 largo)...Cg=="
exec(base64.b64decode(_b).decode())El blob en base64 dispara la entropía por encima del umbral. La ofuscación no aporta nada aquí: el mismo resultado se logra con código directo y de baja entropía:
Versión limpia:
$ cat tareas/tarea4.py
msg = "TAREA4_OK"
print(msg)Flag: GO{demasiado_ofuscado_tambien_es_sospechoso}
Tarea 5 — Función peligrosa
eval(★★
Cómo llega (detectado):
$ cat tareas/tarea5.py
resultado = eval("21 * 2")
print("TAREA5_OK:" + str(resultado))El motor marca la subcadena eval(. No hace falta esconderla: el cálculo se hace directamente sin eval. (Curiosidad: incluso ast.literal_eval( contendría eval(, otra muestra de lo simplista que es una regla por subcadena.)
Versión limpia:
$ cat tareas/tarea5.py
resultado = 21 * 2
print("TAREA5_OK:" + str(resultado))Flag: GO{evitar_la_funcion_es_mejor_que_esconderla}
Tarea 6 — Nombre de fichero
Nombre de fichero★
Cómo llega (detectado):
$ cat tareas/backdoor_tarea6.py
# fichero renombrado por el laboratorio; el contenido es benigno
print("TAREA6_OK")El contenido es inofensivo: lo que detecta GhostAV es el nombre del fichero (backdoor_...). Basta con renombrarlo a algo neutro:
Versión limpia:
$ cat tareas/tarea6.py
print("TAREA6_OK")Flag: GO{el_nombre_del_fichero_tambien_se_mira}
Tarea 7 — Comentarios reveladores
Metadatos / comentarios★
Cómo llega (detectado):
$ cat tareas/tarea7.py
# TODO: bypass antivirus antes de entregar esto
# payload malicioso de prueba (recordar quitar este comentario)
print("TAREA7_OK")Los comentarios contienen frases que el motor reconoce. Como no afectan al funcionamiento, se eliminan:
Versión limpia:
$ cat tareas/tarea7.py
print("TAREA7_OK")Flag: GO{los_comentarios_tambien_se_leen}
Tarea 8 — Todo a la vez
5 heurísticas combinadas★★★
Cómo llega (detectado):
$ cat tareas/tarea8.py
# TODO: bypass antivirus antes de entregar esto -- GHOST_MALWARE_TAG
import subprocess, base64
_extra = base64.b64decode("...")
resultado = eval("21 * 2")
subprocess.call(["echo", "TAREA8_OK:" + str(resultado)])Este fichero dispara cinco heurísticas a la vez: firma de cadena (GHOST_MALWARE_TAG), combinación subprocess+call, entropía alta (el blob base64), eval( y el comentario revelador. Hay que corregir las cinco en el mismo fichero, sin que arreglar una reactive otra (por ejemplo, no sustituir el blob por otra ofuscación que vuelva a subir la entropía):
Versión limpia:
$ cat tareas/tarea8.py
import os
resultado = 21 * 2
os.system("echo TAREA8_OK:" + str(resultado))Flag: GO{evadir_una_firma_no_basta_si_hay_siete}
Resumen
| # | Heurística | Evasión |
|---|---|---|
| 1 | Firma de cadena | Borrar la cadena marcada |
| 2 | Firma por hash | Cambiar un byte cualquiera |
| 3 | Combinación de APIs | Usar una API equivalente |
| 4 | Entropía alta | Quitar la ofuscación innecesaria |
| 5 | Función peligrosa | No usar la función, no esconderla |
| 6 | Nombre de fichero | Renombrar |
| 7 | Comentarios reveladores | Limpiar los comentarios |
| 8 | Cinco a la vez | Corregir todas sin reactivar ninguna |