¿Por qué se requiere execstack para ejecutar código en el montón?

3 minutos de lectura

Escribí el siguiente código para probar el shellcode (para desvincular /tmp/passwd) para una asignación en una clase de seguridad.

Cuando compilo con gcc -o test -g test.cobtengo un error de segmento en el salto al shellcode.

Cuando postproceso el binario con execstack -s testya no obtengo una falla de segmento y el shellcode se ejecuta correctamente, eliminando /tmp/passwd.

Estoy corriendo gcc 4.7.2. Parece que es una mala idea exigir que la pila sea ejecutable para que el montón sea ejecutable, ya que hay muchos más casos de uso legítimos de este último que del primero.

¿Es este el comportamiento esperado? Si es así, ¿cuál es la razón?

#include <stdio.h>                                     
#include <stdlib.h>                                    


char* shellcode;                                       


int main(){                                            
    shellcode = malloc(67);                            
    FILE* code = fopen("shellcode.bin", "rb");      
    fread(shellcode, 1, 67, code);                     

    int (*fp)(void) = (int (*) (void)) shellcode;      
    fp();                                              
}    

Aquí está la salida de xxd shellcode.bin:

0000000: eb28 5e89 760c 31c0 8846 0bfe c0fe c0fe  .(^.v.1..F......           
0000010: c0fe c0fe c0fe c0fe c0fe c0fe c0fe c089  ................           
0000020: f3cd 8031 db89 d840 cd80 e8d3 ffff ff2f  ...1...@......./           
0000030: 746d 702f 7061 7373 7764                 tmp/passwd                 

  • en.wikipedia.org/wiki/No-execute_bit

    -Hans Passant

    24 de abril de 2014 a las 18:08

  • @HansPassant, NX parece ser útil en la granularidad de una entrada de tabla de página. La tecnología es algo ortogonal a mi pregunta, que trata sobre la lógica de combinar las protecciones de pila y montón en una sola.

    – merlín2011

    24/04/2014 a las 18:11

El verdadero comportamiento “inesperado” es que establecer la bandera hace que el montón ejecutable, así como la pila. El indicador está diseñado para usarse con ejecutables que generan procesadores basados ​​en pilas (como gcc cuando toma la dirección de una función anidada) y no debería afectar realmente al montón. Pero Linux implementa esto al hacer ejecutables globalmente TODAS las páginas legibles.

Si desea un control más detallado, puede utilizar en su lugar el mprotect llamada al sistema para controlar los permisos ejecutables por página — Agregue código como:

uintptr_t pagesize = sysconf(_SC_PAGE_SIZE);
#define PAGE_START(P) ((uintptr_t)(P) & ~(pagesize-1))
#define PAGE_END(P)   (((uintptr_t)(P) + pagesize - 1) & ~(pagesize-1))
mprotect((void *)PAGE_START(shellcode), PAGE_END(shellcode+67) - PAGE_START(shellcode),
         PROT_READ|PROT_WRITE|PROT_EXEC);

  • Permiso exec inesperado de mmap cuando los archivos ensamblados incluidos en el proyecto tienen más detalles sobre la función del kernel “leer implica exec” que -zexecstack usos.

    – Peter Cordes

    17 mayo 2020 a las 14:43


  • Actualización: con núcleos modernos, -zexecstack ahora realmente solo hace lo que dice el nombre, ya no establece READ_IMPLIES_EXEC: comportamiento predeterminado de Linux contra la sección `.data`

    – Peter Cordes

    15 de febrero de 2021 a las 1:20

¿Es este el comportamiento esperado?

Mirando el código del kernel de Linux, creo que el nombre interno del kernel para este indicador es “leer implica exec”. Así que sí, creo que es lo esperado.

Parece que es una mala idea exigir que la pila sea ejecutable para que el montón sea ejecutable, ya que hay muchos más casos de uso legítimos de este último que del primero.

¿Por qué necesitaría que el montón completo sea ejecutable? Si realmente necesita generar dinámicamente código máquina y ejecutarlo, puede asignar explícitamente memoria ejecutable usando el mmap llamada al sistema.

cual es la razon

Creo que la idea es que este indicador se pueda usar para programas heredados que esperan que todo lo que sea legible también sea ejecutable. Esos programas pueden intentar ejecutar cosas en la pila y pueden intentar ejecutar cosas en el montón, por lo que todo está permitido.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad