tutorial solucion programacion pila example desbordamiento contramedidas camara c security buffer-overflow fortify-source memory-safety

solucion - desbordamiento de pila



El desbordamiento del búfer funciona en gdb pero no sin él (7)

Estoy en CentOS 6.4 32 bit y estoy tratando de causar un desbordamiento de búfer en un programa ... Sin embargo, cuando se ejecuta la pila de programas solo por sí mismo seg seguras.

También debe asegurarse de que FORTIFY_SOURCE no afecte sus resultados. El fallo de segmento suena como FORTIFY_SOURCE podría ser el problema porque FORTIFY_SOURCE insertará llamadas a funciones "más seguras" para proteger contra algunos tipos de desbordamientos de búfer. Si el compilador puede deducir los tamaños del búfer de destino, entonces se comprueba el tamaño y se abort() en una violación (es decir, su falla seg).

Para desactivar FORTIFY_SOURCE para la prueba, debe compilar con -U_FORTIFY_SOURCE o -D_FORTIFY_SOURCE=0 .

Estoy en CentOS 6.4 32 bit y estoy tratando de causar un desbordamiento de búfer en un programa. Dentro de GDB funciona. Aquí está el resultado:

[root@localhost bufferoverflow]# gdb stack GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/bufferoverflow/stack...done. (gdb) r Starting program: /root/bufferoverflow/stack process 6003 is executing new program: /bin/bash Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6_4.2.i686 sh-4.1#

Sin embargo, cuando ejecuto la pila de programas por sí solo, falla. ¿Por qué podría ser esto?


Aquí hay una forma sencilla de ejecutar su programa con pilas idénticas en la terminal y en gdb :

Primero, asegúrese de que su programa esté compilado sin protección de pila,

gcc -m32 -fno-stack-protector -z execstack -o shelltest shelltest.c -g

y y ASLR está desactivado:

echo 0 > /proc/sys/kernel/randomize_va_space

NOTA: el valor predeterminado en mi máquina era 2, tenga en cuenta el suyo antes de cambiar esto.

Luego ejecute su programa como tal (terminal y gdb respectivamente):

env -i PWD="/root/Documents/MSec" SHELL="/bin/bash" SHLVL=0 /root/Documents/MSec/shelltest env -i PWD="/root/Documents/MSec" SHELL="/bin/bash" SHLVL=0 gdb /root/Documents/MSec/shelltest

Dentro de gdb , asegúrese de unset LINES y COLUMNS .

Nota: Obtuve esas variables de entorno jugando con un programa de prueba .

Esas dos ejecuciones le darán punteros idénticos a la parte superior de la pila, por lo que no es necesario realizar engaños remotos de scripts si está tratando de explotar un binario alojado de forma remota.


El desarrollo de vulnerabilidades puede generar graves dolores de cabeza si no se toman en cuenta adecuadamente los factores que introducen la no determinación en el proceso de depuración. En particular, las direcciones de pila en el depurador pueden no coincidir con las direcciones durante la ejecución normal. Este artefacto se produce porque el cargador del sistema operativo coloca las variables de entorno y los argumentos del programa antes del comienzo de la pila:

Dado que su programa vulnerable no toma ningún argumento, las variables de entorno probablemente sean las culpables. Mare seguro de que son los mismos tanto en las invocaciones, en el shell y en el depurador. Para este fin, puede envolver su invocación en env :

env - /path/to/stack

Y con el depurador:

env - gdb /path/to/stack ($) show env LINES=24 COLUMNS=80

En el ejemplo anterior, hay dos variables de entorno establecidas por gdb, que puede deshabilitar aún más:

unset env LINES unset env COLUMNS

Ahora show env debe devolver una lista vacía. En este punto, puede iniciar el proceso de depuración para encontrar la dirección de pila absoluta que prevé pasar (por ejemplo, 0xbffffa8b ) y codificarla en su exploit.

Otro detalle más sutil pero importante: hay una diferencia entre llamar ./stack y /path/to/stack : ya que argv[0] mantiene el programa exactamente como lo invocó, necesita asegurar cadenas de invocación iguales. Es por eso que utilicé /path/to/stack en los ejemplos anteriores y no solo en ./stack y gdb stack .

Al aprender a explotar con las vulnerabilidades de seguridad de la memoria, recomiendo usar el programa de envoltura a continuación, que hace el trabajo pesado y garantiza la igualdad de compensaciones de la pila:

$ invoke stack # just call the executable $ invoke -d stack # run the executable in GDB

Aquí está el guión:

#!/bin/sh while getopts "dte:h?" opt ; do case "$opt" in h|/?) printf "usage: %s -e KEY=VALUE prog [args...]/n" $(basename $0) exit 0 ;; t) tty=1 gdb=1 ;; d) gdb=1 ;; e) env=$OPTARG ;; esac done shift $(expr $OPTIND - 1) prog=$(readlink -f $1) shift if [ -n "$gdb" ] ; then if [ -n "$tty" ]; then touch /tmp/gdb-debug-pty exec env - $env TERM=screen PWD=$PWD gdb -tty /tmp/gdb-debug-pty --args $prog "$@" else exec env - $env TERM=screen PWD=$PWD gdb --args $prog "$@" fi else exec env - $env TERM=screen PWD=$PWD $prog "$@" fi


El motivo por el que su desbordamiento de búfer funciona en gdb y segfaults de otra manera es que gdb deshabilita la asignación al azar del diseño de espacio de direcciones. Creo que esto fue activado por defecto en gdb versión 7.

Puede verificar esto ejecutando este comando:

show disable-randomization

Y configurarlo con

set disable-randomization on

o

set disable-randomization off


He intentado con la solución aceptada aquí y no funciona (para mí). Sabía que gdb agregaba variables de entorno y por esa razón la dirección de la pila no coincide, pero incluso eliminando esas variables no puedo explotar mi exploit sin gdb (también probé el script publicado en la solución aceptada).

Pero al buscar en la web encontré otro script que funciona para mí: https://github.com/hellman/fixenv/blob/master/r.sh

El uso es básicamente el mismo que el script en la solución aceptada:

  • r.sh gdb ./program [args] para ejecutar el programa en gdb
  • r.sh ./program [args] para ejecutar el programa sin gdb

Y este script funciona para mí.


La dirección del puntero de marco de pila cuando se ejecuta el código en gdb es diferente de ejecutarlo normalmente. Por lo tanto, puede dañar la dirección de retorno en el modo gdb, pero puede no funcionar correctamente cuando se ejecuta en modo normal. La razón principal de eso es que las variables de entorno difieren entre las dos situaciones.

Como esto es solo una demostración, puede cambiar el código de víctima e imprimir la dirección del búfer. Luego cambie su dirección de retorno para compensar + dirección del búfer.

En realidad, sin embargo, debes adivinar la dirección de retorno para agregar un trineo NOP antes de tu código malicioso. Y puede adivinar varias veces para obtener una dirección correcta, ya que su conjetura puede ser incorrecta.

Espero que esto le pueda ayudar.


Una de las principales cosas que hace gdb que no ocurre fuera de gdb es la memoria cero. Es más que probable que en algún lugar del código no esté inicializando su memoria y esté obteniendo valores de basura. Gdb borra automáticamente toda la memoria que asigna ocultando esos tipos de errores.

Por ejemplo: lo siguiente debería funcionar en gdb, pero no fuera de él:

int main(){ int **temp = (int**)malloc(2*sizeof(int*)); //temp[0] and temp[1] are NULL in gdb, but not outside if (temp[0] != NULL){ *temp[0] = 1; //segfault outside of gdb } return 0; }

Intenta ejecutar tu programa en valgrind para ver si puede detectar este problema.