Soluciones del Hack it! Euskal Party 12 - 2004 ----------------------------------------------------------------------------- Autores: samsa, eSn-mIn, Ripe ----------------------------------------------------------------------------- Nivel 1: Hemos puesto un alert aqui var alpha = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); alert(""+alpha[1]+alpha[0]+alpha[18]+alpha[8]+alpha[2]+alpha[14]); ----------------------------------------------------------------------------- Nivel 2: Este era un flash que se descompilaba. onClipEvent () { if (_root.pass.text == "340975343434") { _root.gotoAndStop(5); } else { _root.pass.text = ""; } // end if } ----------------------------------------------------------------------------- Nivel 3: Descrifrar el html ( rot+4 ) Analizar html o usar otro alert ----------------------------------------------------------------------------- Nivel 4: John the ripper y sacabas la contraseña de los filipinos: Password: $1$AnB0rai7$9SaSpCqmq33GSvWd1uxM6. Password: malcuida (john) ----------------------------------------------------------------------------- Nivel 5: Habia que bajarse pass.txt gracias a que se descompilaba un applet con dj java decompiler: tpassword.cab -> tpassword.class -> // [ tpassword.jad ] if(s != null) readFile(s + "pass.txt"); else readFile("./pass.txt"); s = getParameter("auto"); if(s != null && s.equalsIgnoreCase("YES")) login(); } // [ pass.txt ] BERTHOU § A § Raymond BERTHOU ADMIN § NE0HAX0R § UB3RG33K § ../level6-ne0flautas.html ----------------------------------------------------------------------------- Nivel 6: http://hackit.ekparty.org//level6-ne0flautas.html Bajamos zip, usamos azpr, crackeamos zip. -> splash Obtenemos el mensaje : -----BEGIN PGP MESSAGE----- Version: GnuPG v1.2.1 (MingW32) - WinPT 0.7.96rc1 jA0EAwMCzRnoCTJLGJ1gyT3xB+3tQ6vLRidEYymmqLa3nN1QEr+nBKfTNJYIDC7e ww/LEX9RAZTijuU4ICnyyas5hZg9cikPG/ke2FyU =qHlb -----END PGP MESSAGE----- Pgp -> descifrar -> splash ----------------------------------------------------------------------------- Nivel 7: Con html decoder y un alert por ahi, encontramos: En un comentario encontramos : ----------------------------------------------------------------------------- Nivel 8: int main() { char *str="tkjynkvugqm{ksfpoi{ks:/hrnmtbvlots"; int i; for( i=0; i 23012 var f = e.substring(1,2) + e.substring(4,5)+ e.substring (6,7) + e.substring (0,1) + e.substring(5,6)+ e.substring(2,3) + e.substring(3,4); _0.____ if (a == "ai" && b1 == "vehav" && c == "the" && d == "fux0ring" && f == "0.p.w4" ) { a = "i"; alert("ACCESS GRANTED"); window.location="./level10-"+a+b+c+d+e+".html"; done=1; } if (done==0) { alert("ACCESS DENIED"); } } ----------------------------------------------------------------------------- Nivel 10: Vigenere: "VIGO" (cryptool daba "VIGD") :P Parece que el criptoanalisis se te da bien. Continua con el juego en level11-vigeriatrik.html ----------------------------------------------------------------------- Nivel 11: #include #include main(int argc, char *argv[]) { int crap[3]; int check; char buf[20]; if(argc>1) strcpy(buf,argv[1]); if (check==0x1fabada1) { printf("level12-XXXXXXXX.html\n\n"); } } LOAD:08048394 push ebp LOAD:08048395 mov ebp, esp LOAD:08048397 sub esp, 58h LOAD:0804839A mov [ebp+var_28], 'E' LOAD:080483A1 mov [ebp+var_24], 'L' LOAD:080483A8 mov [ebp+var_20], 'W' LOAD:080483AF mov [ebp+var_1C], 'e' LOAD:080483B6 mov [ebp+var_18], 'A' LOAD:080483BD mov [ebp+var_14], 'N' LOAD:080483C4 mov [ebp+var_10], 'p' LOAD:080483CB mov [ebp+var_C], 'y' LOAD:080483D2 cmp [ebp+arg_0], 1FABADA1h LOAD:080483D9 jnz short locret_804843F LOAD:080483DB mov [esp+58h+Magic], offset aLevel12 ; "level12-" LOAD:080483E2 call printf LOAD:080483E7 movsx eax, byte ptr [ebp+var_C] LOAD:080483EB mov [esp+58h+h], eax LOAD:080483EF movsx eax, byte ptr [ebp+var_10] LOAD:080483F3 mov [esp+58h+g], eax LOAD:080483F7 movsx eax, byte ptr [ebp+var_14] LOAD:080483FB mov [esp+58h+f], eax LOAD:080483FF movsx eax, byte ptr [ebp+var_18] LOAD:08048403 mov [esp+58h+e], eax LOAD:08048407 movsx eax, byte ptr [ebp+var_1C] LOAD:0804840B mov [esp+58h+d], eax LOAD:0804840F movsx eax, byte ptr [ebp+var_20] LOAD:08048413 mov [esp+58h+c], eax LOAD:08048417 movsx eax, byte ptr [ebp+var_24] LOAD:0804841B mov [esp+58h+b], eax LOAD:0804841F movsx eax, byte ptr [ebp+var_28] LOAD:08048423 mov [esp+58h+a], eax LOAD:08048427 mov [esp+58h+Magic], offset aCCCCCCCC ; "%c%c%c%c%c%c%c%c" LOAD:0804842E call printf LOAD:08048433 mov [esp+58h+Magic], offset a_html ; ".html\n\n" LOAD:0804843A call printf El codigo de ejemplo muestra una vulnerabilidad por buffer overflow que permite sobreescribir "check", sin embargo no hace falta explotar nada, pues mirando un poco el codigo... http://hackit.ekparty.org/level12-ELWeANpy.html ----------------------------------------------------------------------- Nivel 12: Ejecutamos el programa en un linux y no produce ninguna salida apreciable Le pasamos el strace : read(3, "\3642\0\216\27,\304\33\2458D6c\312\272\35>V5\375\277\303"..., 32) = 32 close(3) = 0 open("level12", O_RDWR|O_CREAT, 0644) = 3 write(3, "level13-v3l0c1r4pt0r", 20) = 20 close(3) = 0 unlink("level12") = 0 exit_group(0) http://hackit.ekparty.org/level13-v3l0c1r4pt0r.html ----------------------------------------------------------------------- Nivel 13: El texto esta cifrado con el algoritmo playfair ( la "no pista" del enunciado puede inducirnos a ello ): Este texto contiene el enlace para el siguiente nivel, como siempre, pero he creido que haciendolo un poco mas largo sera mas sencillo el criptoanalisis ;-) En fin, al grano, el siguiente nivel continua en level14-cypherphun.html, todo en minusculas claro, que lo disfrutesssw!! ----------------------------------------------------------------------- Nivel 14: El algoritmo lo que hace es desencriptar una zona de memoria restando 0x60 a cada byte. .data:080490DC Cypher db 0Ah,0CCh,0C5h,0D6h,0C5h,0CCh, 91h, 95h .data:080490DC db 8Dh,0D3h,0C8h, 94h,0CBh, 93h,0D4h,0C8h .data:080490DC db 94h,0D4h,0A5h,0ACh,0A6h, 6Ah Lo debugueamos con gdb, una vez analizado el comportamiento con IDA : (gdb) set $eip=0x80480a1 // Entry Point (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) n Program not restarted. (gdb) c Continuing. level15-sh4k3th4tELF Program exited normally ----------------------------------------------------------------------- Nivel 15: Shell script que se cuenta a si mismo el numero de caracteres linea a linea (sin contar vueltas de carro) y usa el resultado para validar un password: w contiene el continido del propio shell script pass="0"; for I in $w; do pass=$(expr $pass + $(echo $I | wc -c)); done; Calcula la longitud de caracteres imprimibles y la compara con el número entrado: uri@main uri $ ls -l total 8 -rw-r--r-- 1 uri users 357 Jul 20 18:11 level15-sh4k3th4tELF.sh -rw-r--r-- 1 uri users 403 Jul 24 06:51 trash.sh uri@main uri $ sh level15-sh4k3th4tELF.sh Password: 357 Password: 356 Password: 355 ./level16-126025.html Happy cracking ;-P Pass : level16-126025.html ----------------------------------------------------------------------- Nivel 16: Se descomprime con UPX -d (de la beta), luego con HTe vemos que hace getchar y luego lo compara con una X. despues imprime la url. Quitamos el empaquetado UPX $ upx-1.92-linux_i386/upx -d DEC Ultimate Packer for eXecutables Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 UPX 1.92 beta Markus F.X.J. Oberhumer & Laszlo Molnar Jul 20th 2004 File size Ratio Format Name -------------------- ------ ----------- ----------- 211518 <- 9364 4.43% linux/elf386 DEC Analizamos el fichero con el IDA Una vez interpretado el código es el siguiente : .text:080484DC mov [esp+0FF8h+var_pBUF_RES], offset aPassword ; "password: " .text:080484E3 call _printf .text:080484E8 call _getchar .text:080484ED mov [ebp+VAR_CHAR_STDIN], al .text:080484F3 cmp [ebp+VAR_CHAR_STDIN], 58h ; X .text:080484FA jnz short DO_PRINTF .text:080484FC mov [ebp+var_IND], 0 .text:08048503 .text:08048503 loc_8048503: ; CODE XREF: main+166j .text:08048503 cmp [ebp+var_IND], 12h .text:08048507 jle short ACTUALITZA .text:08048509 jmp short DO_PRINTF .text:0804850B ; --------------------------------------------------------------------------- .text:0804850B .text:0804850B ACTUALITZA: ; CODE XREF: main+133j .text:0804850B cmp [ebp+VAR_CHAR_STDIN], 58h .text:08048512 jnz short DO_PROXIM .text:08048514 lea eax, [ebp+var_BUFFER_INIT_0] .text:0804851A mov ecx, eax .text:0804851C add ecx, [ebp+var_IND] .text:0804851F lea eax, [ebp+BUFFER_PASS] .text:08048525 mov edx, eax .text:08048527 add edx, [ebp+var_IND] .text:0804852A movzx eax, [ebp+VAR_CHAR_STDIN] .text:08048531 xor al, [edx] .text:08048533 mov [ecx], al Luego printea el BUFFER_INIT_0, que solo se actualiza si recibe "X" con lo que .. $ ./DEC password: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX level17-gaud3amuS http://hackit.ekparty.org/level17-gaud3amuS.html ----------------------------------------------------------------------- Nivel 17: Binario ELF protegido con ... burneye? Viajando en el packer ... Encontramos los primeros trucos antidebug a evitar. 0x53714ba: add esi,0x5375a00 0x53714c0: mov DWORD PTR [ebp-732],esi 0x53714c6: int3 0x53714c7: cmp ds:0x5375748,0x0 0x53714ce: jne 0x53714e2 0x53714d0: xor eax,eax 0x53714d2: xor ebx,ebx 0x53714d4: xor ecx,ecx 0x53714d6: xor edx,edx 0x53714d8: xor esi,esi 0x53714da: xor edi,edi 0x53714dc: xor ebp,ebp 0x53714de: xor esp,esp 0x53714e0: jmp esi Invertimos el antidebug. EL Programa no funciona en 2.6!!, debido a que la pila se asigna de forma diferente y el burneye usa los aux vectors que residen en ella. el programa da cuelgues tremendos con 2.6 ( 4 horas!! mirandolo ) (gdb) set $eip=0x53714e2 (gdb) break *0x537191d Breakpoint 1 at 0x537191d (gdb) c Continuing. password: Encontramos y analizamos la mayoria del binario. Pero las rutinas de hashing son extremadamente grandes y buscamos si alguien ha hecho este trabajo anteriormente. Existe el programa burndump, que crackea archivos burneye pero este programa no nos coje el ejecutable. Creamos un burneye cifrado, comparamos ejecutables y añadimos la tag necesaria. C:\Documents and Settings\Uri\Escritorio\hackit>burncrack.exe -f level17-gaud3amuS -b alpha -d bu.dmp UNFburninhell by [ByteRage] / UNF ---[ removing layer 1 (obfuscation layer) burneye signature found @ 0000100C obfuscation layer (layer 1) decryption key : D071230F length : 00007B4C start : 05371090 ---[ loading file data burneye signature found @ 0000100C burneye stub hash : 66 CC 2F 96 65 3D 4E 36 4D 37 19 20 85 8C AC 91 39 DA FD 88 encrypted length : 12703 encrypted start : 0x00005A34 encrypted dword : 0x0D2D513C checksum : 0xF2A5CEDD magic XOR block : C2 83 FF 6F 11 CC A5 A5 76 BA 0B 15 D1 7B 31 63 3E 7D 18 85 ---[ simple bruteforce cracker ???? password "hola" okay! cracked in 0 seconds. performing sanity check... found checksum : 0xF2A5CEDD ---[ dumping wrapped binary start of binary : 00005A34 binary filesize : 12703 "bu.dmp" written! ---[ bailing out Ya tenemos el archivo original!! El algoritmo construye la url de la pagina a partir de 2 streams y un array de casos. Dependiendo del caso se realiza una suma, una resta, o un XOR. Vemos en el código : .text:080484DF cmp [ebp+VAR_IMPORTANT1], 62h ; 'b' ; CODI BASURA .text:080484E6 jnz FINAL_NO_PRINT .text:080484EC cmp [ebp+VAR_IMPORTANT_2], 72h ; 'r' .text:080484F3 jnz FINAL_NO_PRINT .text:080484F9 cmp [ebp+VAR_IMPORTANT3], 75h ; 'u' .text:08048500 jnz FINAL_NO_PRINT .text:08048506 cmp [ebp+VAR_IMPORTANT4], 6Ah ; 'j' .text:0804850D jnz FINAL_NO_PRINT .text:08048513 cmp [ebp+VAR_IMPORTANT5], 61h ; 'a' .text:0804851A jnz FINAL_NO_PRINT .text:08048520 mov [ebp+var_C], 0 Donde FINAL_NO_PRINT es la salida inmediata de la función: Esas variables importantes ya estan inicializadas, y no hay forma de canviarlas, así que las canviamos con el gdb directamente set *(char *)($ebp-200)=0x62 set *(char *)($ebp-199)=0x72 set *(char *)($ebp-198)=0x75 set *(char *)($ebp-197)=0x6a set *(char *)($ebp-196)=0x61 c <= continue level18-4y34y3sir url: http://hackit.ekparty.org/level18-4y34y3sir.html Nivel 18: El programa hace esto........ short Buffer[MAX_LEN_USER]; int len = 0; for (int i = 0; i < strlen(User); i++) { len++; short magic = Buffer[i]; aux = magic; for (int j = 0; j < 15; j++) { aux <<= 1; magic ^= aux; if (magic < 0) len++; magic = aux; } } printf(len); ---------------------------------------------------- for (int i = 2; Torpedo(Serial[i]) % 7; i++); if (Torpedo(Serial[i]) % 13 == 0) OOOOOOOOOOOOK; ---------------------------------------------------- int Torpedo(char caracter) { short magic; short bit; bool majuscula; depend = 0; if (!majuscula(caracter)) // minuscula { depend = " "; majuscula = false; } else majuscula = true; depend += "A"; contador = 0; while (depend <= caracter) { magic = Buffer[contador/16]; bit = magic << (contador & 0xF); if (bit < 0 && !majuscula) // bit = 1 && minuscula return 70; // Pifia else if (bit >= 0 && majuscula) // bit = 0 && majuscula return 21; // Pifia contador++; depend++; } if (contador < strlen(Name) * 16) { if ((contador & 0xF) == 0) return 54; // Continua bucle magic = Buffer[contador/16]; bit = magic << (contador & 0xF); if (bit < 0 && majuscula) // bit = 1 && majuscula return 70; // Pifia else if (bit >= 0 && !majuscula) // bit = 0 && minuscula return 21; // Pifia } return 91; // OK } Hemos hecho un pequeño keygen: ----/ cut here /---- [License] USER=euskal12 SKEY=IoaAaBaCcAcaBaAaAeAcaBaAeCcaBeEcaAaAaFaAcaBdDebAaBcBaAcbAaBaAaAaAd ----/ cut here /---- http://hackit.ekparty.org/level19-IoaAaBaCcAcaBaAaAeAcaBaAeCcaBeEcaAaAaFaAcaBdDebAaBcBaAcbAaBaAaAaAd.html ------------------------------------------------------------------------------------------------ Nivel 19: keygen: int main(int argc, char **argv) { int i; int len; unsigned short *act; unsigned short max, min; unsigned short maxmin; char *key; if (argc < 2) { printf("%s \n", argv[1]); exit(0); } act = argv[1]; max = *act; min = *act; len = strlen(argv[1])/2; for (i = 0 ; i < len ; i++) { if (act[i] > max) max = act[i]; if (act[i] < min) min = act[i]; } key = (char *)malloc(len * 4 + 1); maxmin = max + min; printf("MaxMin = %i\n", maxmin); for (i = 0 ; i < len * 4 ; i++) { printf("%x - %x\n", act[i/4], maxmin); if (act[i/4] > maxmin) { key[i] = 'A' + (((act[i/4] % maxmin) >> ((12 - i * 4) & 0xF)) & 0xF); printf("C1 : '%c'\n", key[i]); } else { key[i] = 'A' + (((maxmin % act[i/4]) >> ((12 - i * 4) & 0xF)) & 0xF); printf("C2 : '%c'\n", key[i]); } } key[i] = 0; printf("\n----/ cut here /----\n"); printf("[License]\n"); printf("USER=%s\n", argv[1]); printf("SKEY=%s\n", key); printf("----/ cut here /----\n"); return 0; } ----/ cut here /---- [License] USER=euskal12 SKEY=DCDBDMCDDLDFBBAD ----/ cut here /---- http://hackit.ekparty.org/level20-DCDBDMCDDLDFBBAD.html