Cómo llamar a execve en C sin nombrarlo y evadir el corrector de la escuela

Calling a function in C without naming it

Un estudiante y su amigo sortean el sistema de calificación automática de su escuela, que verifica las funciones permitidas mediante el AST. Aprovechan que el código se compila con ASan para filtrar el offset entre printf y mmap, obtener una página ejecutable y lanzar cualquier syscall, incluido execve, logrando ejecución de shell. Un bypass de ASLR que demuestra que la seguridad por oscuridad no funciona.

En C, la inseguridad es una característica, así que podemos usar uniones.
  1. ashdnazg

    Nuestra universidad era mucho menos cuidadosa, y simplemente ejecutaba nuestras entregas en la misma red que todo lo demás, aunque con un usuario con apenas permisos.

    Una vez, cuando las pruebas automáticas hicieron fallar mi entrega, simplemente usé `system` para volcar la entrada de prueba en mi directorio home. Sin embargo, olvidé configurar los permisos, ¡así que no pude acceder a ella! Tras un par de reenvíos más con chmods adicionales, estropeando algo distinto cada vez, logré reproducir mi bug, arreglarlo, reenviar y purgar toda (o casi toda) la evidencia.

  2. Kevin_Flynn

    Como sabemos que nuestro código se compila con ASan, optamos por filtrar el offset entre printf, una función que siempre está permitida, y mmap, una función que nos da ejecución arbitraria de código ensamblador. Así podemos saltarnos las comprobaciones de la escuela y llamar a cualquier syscall, en nuestro caso execve para obtener acceso a shell.

    No investigamos más y simplemente reportamos este posible problema a la escuela.

    No veo una forma trivial de parchear esto.

    El fallo parece estar en el sistema de entrega.

    El sistema de entrega podría compilar/reenlazar tu código con una librería trampolín donde el cuerpo de cada función a prohibir se reemplace con reporte de errores y abort. En tu ejemplo, atraparía:

    char *code =

    notmmap.fn(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,

    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    y evitaría que uses el flag PROT_EXEC durante la fase de ejecución de la validación de la entrega.

    Según la IA, en linux: "... un filtro seccomp-BPF aplicado a cada proceso antes de que empiece a ejecutar el programa. Puede inspeccionar el argumento prot de mmap y devolver EPERM cuando PROT_EXEC está activado."

    Además, en linux: "systemd ofrece MemoryDenyWriteExecute=yes para servicios. Eso es menos restrictivo que prohibir cada mapeo ejecutable: apunta a mapeos escribibles+ejecutables y formas relacionadas de hacer memoria ejecutable."

    ( SI ... leí el artículo correctamente )

    ps. Envía las soluciones propuestas al jefe de tu departamento u otra figura de autoridad que pueda lanzarte algún tipo de hueso para que tu sol […]

  3. PeterWhittaker

    Parece que la escuela necesita envolver las cosas en una lista de denegación de seccomp. Potencialmente no trivial, pero potencialmente interesante.

    Requisitos:

Más de este día

2026-10-08