mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
63 lines
5.9 KiB
Markdown
63 lines
5.9 KiB
Markdown
# House of Force
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Información Básica
|
|
|
|
### Código
|
|
|
|
- Esta técnica fue parcheada ([**aquí**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)) y produce este error: `malloc(): corrupted top size`
|
|
- Puedes probar el [**código de aquí**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html) para testearlo si lo deseas.
|
|
|
|
### Objetivo
|
|
|
|
- El objetivo de este ataque es poder asignar un chunk en una dirección específica.
|
|
|
|
### Requisitos
|
|
|
|
- Un desbordamiento que permita sobrescribir el tamaño del encabezado del chunk superior (por ejemplo, -1).
|
|
- Poder controlar el tamaño de la asignación de heap.
|
|
|
|
### Ataque
|
|
|
|
Si un atacante quiere asignar un chunk en la dirección P para sobrescribir un valor aquí. Comienza sobrescribiendo el tamaño del chunk superior con `-1` (quizás con un desbordamiento). Esto asegura que malloc no usará mmap para ninguna asignación ya que el chunk superior siempre tendrá suficiente espacio.
|
|
|
|
Luego, calcula la distancia entre la dirección del chunk superior y el espacio objetivo para asignar. Esto se debe a que se realizará un malloc con ese tamaño para mover el chunk superior a esa posición. Así es como se puede calcular fácilmente la diferencia/tamaño:
|
|
```c
|
|
// From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5
|
|
/*
|
|
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
|
|
* new_top = old_top + nb
|
|
* nb = new_top - old_top
|
|
* req + 2sizeof(long) = new_top - old_top
|
|
* req = new_top - old_top - 2sizeof(long)
|
|
* req = target - 2sizeof(long) - old_top - 2sizeof(long)
|
|
* req = target - old_top - 4*sizeof(long)
|
|
*/
|
|
```
|
|
Por lo tanto, asignar un tamaño de `target - old_top - 4*sizeof(long)` (los 4 longs son por los metadatos del chunk superior y del nuevo chunk cuando se asigna) moverá el chunk superior a la dirección que queremos sobrescribir.\
|
|
Luego, haz otro malloc para obtener un chunk en la dirección objetivo.
|
|
|
|
### Referencias y Otros Ejemplos
|
|
|
|
- [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file)
|
|
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/)
|
|
- [https://heap-exploitation.dhavalkapil.com/attacks/house_of_force](https://heap-exploitation.dhavalkapil.com/attacks/house_of_force)
|
|
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c)
|
|
- [https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html)
|
|
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11)
|
|
- El objetivo de este escenario es un ret2win donde necesitamos modificar la dirección de una función que va a ser llamada por la dirección de la función ret2win.
|
|
- El binario tiene un desbordamiento que puede ser abusado para modificar el tamaño del chunk superior, que se modifica a -1 o p64(0xffffffffffffffff).
|
|
- Luego, se calcula la dirección al lugar donde existe el puntero a sobrescribir, y la diferencia desde la posición actual del chunk superior hasta allí se asigna con `malloc`.
|
|
- Finalmente, se asigna un nuevo chunk que contendrá este objetivo deseado dentro del cual se sobrescribe con la función ret2win.
|
|
- [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x_tr_sl=es&\_x_tr_tl=en&\_x_tr_hl=en&\_x_tr_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)
|
|
- En el `Input your name:` hay una vulnerabilidad inicial que permite filtrar una dirección de la heap.
|
|
- Luego, en la funcionalidad `Org:` y `Host:` es posible llenar los 64B del puntero `s` cuando se solicita el **nombre de la organización**, que en la pila es seguido por la dirección de v2, que luego es seguida por el **nombre del host** indicado. Como luego, strcpy va a copiar el contenido de s a un chunk de tamaño 64B, es posible **sobrescribir el tamaño del chunk superior** con los datos puestos dentro del **nombre del host**.
|
|
- Ahora que la escritura arbitraria es posible, el GOT de `atoi` fue sobrescrito con la dirección de printf. Luego fue posible filtrar la dirección de `IO_2_1_stderr` _con_ `%24$p`. Y con este leak de libc fue posible sobrescribir nuevamente el GOT de `atoi` con la dirección de `system` y llamarlo pasando como parámetro `/bin/sh`.
|
|
- Un método alternativo [propuesto en este otro informe](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud) es sobrescribir `free` con `puts`, y luego agregar la dirección de `atoi@got`, en el puntero que será liberado más tarde para que se filtre y con este leak sobrescribir nuevamente `atoi@got` con `system` y llamarlo con `/bin/sh`.
|
|
- [https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html)
|
|
- Hay un UAF que permite reutilizar un chunk que fue liberado sin limpiar el puntero. Debido a que hay algunos métodos de lectura, es posible filtrar una dirección de libc escribiendo un puntero a la función free en el GOT aquí y luego llamando a la función de lectura.
|
|
- Luego, se utilizó House of force (abusando del UAF) para sobrescribir el tamaño del espacio restante con un -1, asignar un chunk lo suficientemente grande para llegar al free hook, y luego asignar otro chunk que contendrá el free hook. Luego, escribir en el hook la dirección de `system`, escribir en un chunk `"/bin/sh"` y finalmente liberar el chunk con ese contenido de cadena.
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|