ThisIsLegal.com – Realistic Challenge 1

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
Firebug
Links
Canyouhack.it – Cryptography Challenge 13

Los retos criptográficos son muy variados y muchas veces la dificultad está en saber a que te enfrentas. En este caso pasa eso, te dan un código y si no has visto algo parecido en la vida, no sabes por donde empezar. El título del autor da una pequeña pista pero para los desconocedores no es suficiente. La pista es el título y dice «WTF?!?» y el código a descifrar es el siguiente:
[-]>[-]< >+++++++++++[<+++++++++++>-]<. >+++[<--->-]<-. >++[<++>-]<++. +. >++++[<---->-]<-. ---. +++. . >+++[<+++>-]<. >+++[<--->-]<+. >++++[<++++>-]<-. >++++[<---->-]<--. >+++[<+++>-]<-. >++[<-->-]<--. -.
Si eres una persona con recursos, realizaras varias búsquedas por la red y al final llegarás a la conclusión de que te enfrentas a BRAINFUCK, un lenguaje de programación esotérico como ya vimos en el reto de Root-Me.
Enlaces
Sotanez’s Crackme1 Keygen

Introducción
Este es un crackme de la web de Karpoff programado por Sotanez y realizado en Delphi. Como máximo nos deja meter nombres de 10 dígitos.
El algoritmo
Es un algoritmo muy sencillo pero veremos que nos tendremos que fijar en el DUMP de Olly para saber que demonios hace. Como de costumbre abrimos Olly y en las «Referenced Strings» localizamos la palabra «Registrado«, pinchamos en ella y localizamos la porción de código que nos interesa. Vamos a analizarla.
Vemos 3 bucles, el primero pone la memoria (Dump) a cero, el segundo guarda nuestro nombre (errata en la imagen) en el Dump y el tercero realiza la suma de los valores ascii del nombre. Hasta aquí todo bien, pero vamos a hacer una prueba para el nombre deurus.
- Nombre: deurus
- Serial: 64+65+75+72+75+73 = 298 (664 en decimal)
Probamos el serial en el programa y nos da error, vale, vamos a analizar más a fondo los bucles.
El primer bucle hemos dicho que pone la memoria a 0, en concreto desde «45BC60» y de 4 en 4 (fíjate en el Add 4), es decir, pone a 0 los offsets 45BC60, 45BC64, 45BC68, 45BC6C, 45BC70, 45BC74, 45BC78, 45BC7C, 45BC80, 45BC84, ya que el bucle se repite 10 veces. En la imágen queda claro.
El segundo bucle se repite 11 veces y lo que hace es guardar en el dump el valor ascii de las letras de nuestro nombre. En la imagen lo vemos.
A primera vista ya vemos un valor extraño en la posición 45BC80, y es que cuando debiera haber un 0, hay un 12. Vamos a ver como afecta esto al serial final.
El tercer bucle se repite 10 veces y lo que hace es sumar los valores que haya en el DUMP en las posiciones anteriormente citadas.
En concreto suma 64+65+75+72+75+73+0+0+12+0 = 2AA (682 en decimal). Probamos 682 como serial y funciona. Realizando más pruebas vemos que para nombres con un tamaño inferior a 5 letras se ocupan las posiciones 45BC70 y 45BC80 con valores extraños, el resto de posiciones se mantienen a 0. En las imágenes inferiores se pueden apreciar más claramente los valores extraños.
Nombre de tamaño < 5.
Nombre de tamaño >5 y <9
Nombre de tamaño = 10
En resumen:
Nombre de tamaño < 5 –> Ascii SUM + 14h
Nombre de tamaño >5 y <9 –> Ascii SUM + 12h
Nombre de tamaño =10 –> Ascii SUM
Con esto ya tenemos todo lo que necesitamos para nuestro keygen.
char Nombre[11];
GetWindowText(hwndEdit1, Nombre, 11);
char Serial[20];
int len = strlen(Nombre);
int suma = 0;
for(int i = 0; i <= len; i = i + 1)
{
suma += Nombre[i];
}
if(len < 5){
suma +=0x14;
}
if(len > 5 && len < 9){
suma +=0x12;
}
wsprintf(Serial,"%d",suma);
SetWindowText(hwndEdit2, TEXT(Serial));
Links
Solución al PGC Official KeygenMe

Introducción
Siguiendo con los crackmes que contienen RSA, esta vez tenemos un Keygenme del grupo PGC (Pirates Gone Crazy) que incluso servía para ser admitido en el grupo si mandabas la solución. Como veremos usa RSA32 + MD5 y en la parte de RSA ni siquiera usa el descifrado por lo que es de los sencillitos.
Resumen RSA
Parámetros
p = Primer número primo
q = Segundo número primo
e = Exponente público que cumpla MCD(e,(p-1)*(q-1))==1
n = Módulo público siendo n=p*q
d = Exponente privado que cumpla d=e^(-1) mod ((p-1)*(q-1))
De este modo e y n son la parte pública de la clave y d y n la parte privada. Los número primos p y q se utilizan solo para generar los parámetros y de ahí en adelante se pueden desechar.
Funciones de Cifrado/Descifrado
cifrado = descifrado ^ e mod n
descifrado = cifrado ^ d mod n
Debug
En las referencias de texto se ven a simple vista el exponente público e (10001) y el módulo n (8e701a4c793eb8b739166bb23b49e421)
Text strings referenced in RSA32+MD:.text
Address Disassembly Text string
00401848 PUSH RSA32+MD.00404104 ASCII "%.8x%.8x%.8x%.8x"
00401A72 PUSH RSA32+MD.0040429C ASCII "[PGCTRiAL/2oo2]"
00401AEE PUSH RSA32+MD.00404275 ASCII "10001"
00401AFE PUSH RSA32+MD.0040427B ASCII "8e701a4c793eb8b739166bb23b49e421"
00401B43 PUSH RSA32+MD.00404404 ASCII "Name Must Be >= 1 Character."
00401B57 PUSH RSA32+MD.00404421 ASCII "Key Must Be >= 1 Character."
00401B6D PUSH RSA32+MD.0040443D ASCII "Congratulations!"
00401B72 PUSH RSA32+MD.0040444E ASCII " You've done it!
Please send your keygen along with
source code to pgc@dangerous-minds.com
if you would like to be considered as
a new member of PGC."
00401BE7 PUSH 0 (Initial CPU selection)
00401C47 MOV [DWORD SS:EBP-24],RSA32+MD.00404119 ASCII "PGCWinClass"
00401C7C MOV [DWORD SS:EBP-24],RSA32+MD.0040424E ASCII "STATIC"
00401CDB PUSH RSA32+MD.00404115 ASCII "PGC"
00401CE0 PUSH RSA32+MD.00404119 ASCII "PGCWinClass"
00401D13 PUSH RSA32+MD.00404125 ASCII "EDIT"
00401D46 PUSH RSA32+MD.00404125 ASCII "EDIT"
00401DFB PUSH RSA32+MD.00404115 ASCII "PGC"
00401E00 PUSH RSA32+MD.0040424E ASCII "STATIC"
Rutina de comprobación
00401A0E /$ 53 PUSH EBX
00401A0F |. 57 PUSH EDI
00401A10 |. 56 PUSH ESI
00401A11 |. 6A 11 PUSH 11 ; /Count = 11 (17.)
00401A13 |. 68 AC424000 PUSH RSA32+MD.004042AC ; |Buffer = RSA32+MD.004042AC
00401A18 |. FF35 94454000 PUSH [DWORD DS:404594] ; |hWnd = NULL
00401A1E |. E8 49080000 CALL <JMP.&USER32.GetWindowTextA> ; \GetWindowTextA
00401A23 |. 83F8 01 CMP EAX,1
00401A26 |. 0F8C 17010000 JL RSA32+MD.00401B43
00401A2C |. A3 6D424000 MOV [DWORD DS:40426D],EAX
00401A31 |. 6A 22 PUSH 22 ; /Count = 22 (34.)
00401A33 |. 68 BD424000 PUSH RSA32+MD.004042BD ; |Buffer = RSA32+MD.004042BD
00401A38 |. FF35 98454000 PUSH [DWORD DS:404598] ; |hWnd = NULL
00401A3E |. E8 29080000 CALL <JMP.&USER32.GetWindowTextA> ; \GetWindowTextA
00401A43 |. 83F8 01 CMP EAX,1
00401A46 |. 0F8C 0B010000 JL RSA32+MD.00401B57
00401A4C |. A3 71424000 MOV [DWORD DS:404271],EAX
00401A51 |. 6A 00 PUSH 0
00401A53 |. E8 C8080000 CALL RSA32+MD.00402320
00401A58 |. A3 69424000 MOV [DWORD DS:404269],EAX
00401A5D |. A1 71424000 MOV EAX,[DWORD DS:404271]
00401A62 |. FF35 69424000 PUSH [DWORD DS:404269] ; /Arg2 = 00000000
00401A68 |. 68 BD424000 PUSH RSA32+MD.004042BD ; |Arg1 = 004042BD
00401A6D |. E8 510A0000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401A72 |. 68 9C424000 PUSH RSA32+MD.0040429C ; /StringToAdd = "[PGCTRiAL/2oo2]"
00401A77 |. 68 AC424000 PUSH RSA32+MD.004042AC ; |ConcatString = ""
00401A7C |. E8 51080000 CALL <JMP.&KERNEL32.lstrcatA> ; \lstrcatA
00401A81 |. 68 AC424000 PUSH RSA32+MD.004042AC ; /String = ""
00401A86 |. E8 4D080000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA
00401A8B |. 68 DF424000 PUSH RSA32+MD.004042DF ; /Arg4 = 004042DF
00401A90 |. 68 10454000 PUSH RSA32+MD.00404510 ; |Arg3 = 00404510
00401A95 |. 50 PUSH EAX ; |Arg2
00401A96 |. 68 AC424000 PUSH RSA32+MD.004042AC ; |Arg1 = 004042AC
00401A9B |. E8 60F5FFFF CALL RSA32+MD.00401000 ; \RSA32+MD.00401000
00401AA0 |. 6A 00 PUSH 0
00401AA2 |. E8 79080000 CALL RSA32+MD.00402320
00401AA7 |. A3 5D424000 MOV [DWORD DS:40425D],EAX
00401AAC |. 6A 00 PUSH 0
00401AAE |. E8 6D080000 CALL RSA32+MD.00402320
00401AB3 |. A3 59424000 MOV [DWORD DS:404259],EAX
00401AB8 |. 6A 00 PUSH 0
00401ABA |. E8 61080000 CALL RSA32+MD.00402320
00401ABF |. A3 61424000 MOV [DWORD DS:404261],EAX
00401AC4 |. 6A 00 PUSH 0
00401AC6 |. E8 55080000 CALL RSA32+MD.00402320
00401ACB |. A3 65424000 MOV [DWORD DS:404265],EAX
00401AD0 |. B8 02000000 MOV EAX,2
00401AD5 |. C1E0 04 SHL EAX,4
00401AD8 |. FF35 5D424000 PUSH [DWORD DS:40425D] ; /Arg2 = 00000000
00401ADE |. 68 DF424000 PUSH RSA32+MD.004042DF ; |Arg1 = 004042DF
00401AE3 |. E8 DB090000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401AE8 |. FF35 65424000 PUSH [DWORD DS:404265] ; /Arg2 = 00000000
00401AEE |. 68 75424000 PUSH RSA32+MD.00404275 ; |Arg1 = 00404275 ASCII "10001"
00401AF3 |. E8 CB090000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401AF8 |. FF35 61424000 PUSH [DWORD DS:404261] ; /Arg2 = 00000000
00401AFE |. 68 7B424000 PUSH RSA32+MD.0040427B ; |Arg1 = 0040427B ASCII "8e701a4c793eb8b739166bb23b49e421"
00401B03 |. E8 BB090000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401B08 |. FF35 59424000 PUSH [DWORD DS:404259]
00401B0E |. FF35 61424000 PUSH [DWORD DS:404261]
00401B14 |. FF35 65424000 PUSH [DWORD DS:404265]
00401B1A |. FF35 5D424000 PUSH [DWORD DS:40425D]
00401B20 |. E8 87120000 CALL RSA32+MD.00402DAC
00401B25 |. FF35 69424000 PUSH [DWORD DS:404269]
00401B2B |. FF35 59424000 PUSH [DWORD DS:404259]
00401B31 |. E8 61080000 CALL RSA32+MD.00402397
00401B36 |. 85C0 TEST EAX,EAX
00401B38 |. 74 31 JE SHORT RSA32+MD.00401B6B
00401B3A |. E8 85000000 CALL RSA32+MD.00401BC4
00401B3F |. 5E POP ESI
00401B40 |. 5F POP EDI
00401B41 |. 5B POP EBX
00401B42 |. C3 RET
00401B43 |> 68 04444000 PUSH RSA32+MD.00404404 ; /Text = "Name Must Be >= 1 Character."
00401B48 |. FF35 98454000 PUSH [DWORD DS:404598] ; |hWnd = NULL
00401B4E |. E8 5B070000 CALL <JMP.&USER32.SetWindowTextA> ; \SetWindowTextA
00401B53 |. 5E POP ESI
00401B54 |. 5F POP EDI
00401B55 |. 5B POP EBX
00401B56 |. C3 RET
00401B57 |> 68 21444000 PUSH RSA32+MD.00404421 ; /Text = "Key Must Be >= 1 Character."
00401B5C |. FF35 98454000 PUSH [DWORD DS:404598] ; |hWnd = NULL
00401B62 |. E8 47070000 CALL <JMP.&USER32.SetWindowTextA> ; \SetWindowTextA
00401B67 |. 5E POP ESI
00401B68 |. 5F POP EDI
00401B69 |. 5B POP EBX
00401B6A |. C3 RET
00401B6B |> 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401B6D |. 68 3D444000 PUSH RSA32+MD.0040443D ; |Title = "Congratulations!"
00401B72 |. 68 4E444000 PUSH RSA32+MD.0040444E ; |Text = " You've done it!
Please send your keygen along with
source code to pgc@dangerous-minds.com
if you would like to be considered as
a new member of PGC."
00401B77 |. FF35 8C454000 PUSH [DWORD DS:40458C] ; |hOwner = NULL
00401B7D |. E8 02070000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
00401B82 |. EB 00 JMP SHORT RSA32+MD.00401B84
00401B84 |> FF35 5D424000 PUSH [DWORD DS:40425D]
00401B8A |. E8 BE070000 CALL RSA32+MD.0040234D
00401B8F |. FF35 59424000 PUSH [DWORD DS:404259]
00401B95 |. E8 B3070000 CALL RSA32+MD.0040234D
00401B9A |. FF35 61424000 PUSH [DWORD DS:404261]
00401BA0 |. E8 A8070000 CALL RSA32+MD.0040234D
00401BA5 |. FF35 65424000 PUSH [DWORD DS:404265]
00401BAB |. E8 9D070000 CALL RSA32+MD.0040234D
00401BB0 |. FF35 69424000 PUSH [DWORD DS:404269]
00401BB6 |. E8 92070000 CALL RSA32+MD.0040234D
00401BBB |. E8 04000000 CALL RSA32+MD.00401BC4
00401BC0 |. 5E POP ESI
00401BC1 |. 5F POP EDI
00401BC2 |. 5B POP EBX
00401BC3 \. C3 RET
Como vemos comprueba que tanto el nombre como el número de serie tengan al menos un dígito y a continuación comienza el chequeo del serial. El chequeo es muy sencillo ya que ni siquiera tenemos que buscar los números primos p y q y a continuación n, simplemente podemos obtener el número de serie con la parte pública de la clave (par de número e y n). Lo resumimos a continuación:
- Concatena nuestro nombre con la cadena «[PGCTRiAL/2oo2]»
- Crea el hash MD5 de la cadena concatenada.
- Cifra el hash usando el par de números e y n obtenidos en las referencias de texto.
1. deurus[PGCTRiAL/2oo2] 2. md5(deurus[PGCTRiAL/2oo2]) = dc8a39282da8539d11b8a6aec000c45a 3. dc8a39282da8539d11b8a6aec000c45a^10001 mod 8e701a4c793eb8b739166bb23b49e421 = 1FF83ECC5A65334DA2BC93C675A9BA15 Nombre: deurus Serial: 1FF83ECC5A65334DA2BC93C675A9BA15
Keygen
//
// md5(deurus[PGCTRiAL/2oo2]) = dc8a39282da8539d11b8a6aec000c45a
//
var c = BigInt("0xdc8a39282da8539d11b8a6aec000c45a");
var e = BigInt("0x10001");
var n = BigInt("0x8e701a4c793eb8b739166bb23b49e421");
//
var serial = BigInt(0);
serial = powmod(c, e, n);
document.write(serial.toString(16));
//
//POWMOD
//
function powmod(base, exp, modulus) {
var accum = BigInt("1");
var i = BigInt("0");
var basepow2 = BigInt(base);
while ((BigInt(exp) >> BigInt(i) > BigInt(0))) {
if (((BigInt(exp) >> BigInt(i)) & BigInt(1)) == BigInt(1)) {
accum = (BigInt(accum) * BigInt(basepow2)) % BigInt(modulus);
}
basepow2 = (BigInt(basepow2) * BigInt(basepow2)) % BigInt(modulus);
i++;
}
return BigInt(accum);
}
Enlaces
- RSA (wikipedia)
- Exponenciación modular (wikipedia)
- Big Integer Calculator v1.14
- Crackme
Wechall Training LSB Challenge (Esteganografía)

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
Resumidamente, esta técnica consiste en ocultar información en el bit menos significativo de cada uno de los píxeles de una imagen, consiguiendo así que el cambio realizado sea invisible al ojo humano. El problema de esta técnica, es que la información oculta puede obtenerse fácilmente si esta no se ha codificado previamente o si no se sigue un patrón concreto a la hora de ocultarla.
Desde la web del reto nos avisan de que esto es un simple truco pero espectacular. Nos animan a descargar una imágen y a encontrar la solución oculta.
Aprovecho este reto para presentaros una herramienta vital al enfrentaros a ciertos retos sobre esteganografía, steganabara.
Steganabara tiene dos apartados muy interesantes, uno es «color table» y otro «bit mask«, hoy veremos en acción a «bit mask».
No os preocupéis por la solución ya que cambia para cada usuario y sesión.
Buscando la solución oculta
Abrimos steganabara y empezamos a trastear con bit mask.
Al poco tiempo ya vemos que vamos bien encaminados.
Finalmente no nos cuesta dar con la solución.
Links
- Web del reto
- Steganabara
- Steganabara explained (english)
- Esteganografía: Ocultando el uso de LSB (securityartwork.es)
Crypto – Vodka

Hemos interceptado un mensaje secreto, pero ninguno de nuestros traductores lo sabe interpretar, ¿sabrías interpretarlo tú? Lo único que hemos encontrado es esto en un foro: шжзклмнпфъ = 1234567890
Mensaje secreto: нж, фн, фф, шън, нф, шшъ, шжз, мф, шъп, фл, пк, шъш, шшм, шшк, шъл, шшл, фл, шъш, шшл, фл, шшн, шшъ, фл, шъм, шшн, шъш, шъз, шшш, фл, пж, шшн, шшл, шшш, шжл
Solución
Parece que el mensaje secreto está encriptado utilizando un alfabeto cifrado que corresponde a números. Según la clave proporcionada (шжзклмнпфъ = 1234567890), cada letra del alfabeto cirílico se sustituye por un número.
Primero, descompondremos la clave dada:
ш = 1
ж = 2
з = 3
к = 4
л = 5
м = 6
н = 7
п = 8
ф = 9
ъ = 0
Ahora, aplicamos esta clave al mensaje secreto:
нж, фн, фф, шън, нф, шшъ, шжз, мф, шъп, фл, пк, шъш, шшм, шшк, шъл, шшл, фл, шъш, шшл, фл, шшн, шшъ, фл, шъм, шшн, шъш, шъз, шшш, фл, пж, шшн, шшл, шшш, шжл
Sustituyendo cada letra según la clave:
нж = 72
фн = 97
фф = 99
шън = 107
нф = 79
шшъ = 110
шжз = 123
мф = 69
шъп = 108
фл = 95
пк = 84
шъш = 101
шшм = 116
шшк = 114
шъл = 105
шшл = 115
фл = 95
шъш = 101
шшл = 115
фл = 95
шшн = 117
шшъ = 110
фл = 95
шъм = 106
шшн = 117
шъш = 101
шъз = 130
шшш = 111
фл = 95
пж = 82
шшн = 117
шшл = 115
шшш = 111
шжл = 125
El mensaje traducido a números es:
72, 97, 99, 107, 79, 110, 123, 69, 108, 95, 84, 101, 116, 114, 105, 115, 95, 101, 115, 95, 117, 110, 95, 106, 117, 101, 130, 111, 95, 82, 117, 115, 111, 125
Este parece ser un mensaje cifrado en números. La secuencia de números se puede interpretar de varias maneras (como ASCII, coordenadas, etc.). Si asumimos que es un texto codificado en ASCII:
Convertimos cada número a su correspondiente carácter ASCII:
72 = H
97 = a
99 = c
107 = k
79 = O
110 = n
123 = {
69 = E
108 = l
95 = _
84 = T
101 = e
116 = t
114 = r
105 = i
115 = s
95 = _
101 = e
115 = s
95 = _
117 = u
110 = n
95 = _
106 = j
117 = u
101 = e
130 = ?
111 = o
95 = _
82 = R
117 = u
115 = s
111 = o
125 = }
Juntando todo:
HackOn{El_Tetris_e_s_u_n_j_u_e?o_Ruso}
La parte «{El_Tetris_e_s_u_n_j_u_e?o_Ruso}» parece un mensaje en español. Probablemente deba ser leído como: HackOn{El_Tetris_es_un_juego_Ruso}
Así, el mensaje secreto es: HackOn{El_Tetris_es_un_juego_Ruso}.
La imagen de portada de la entrada ha sido generada con ChatGPT.
Yoire PE Stage 3 Reversing Challenge (Benten) – Fuerza Bruta

Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si continuas leyendo este manual es que no utilices la respuesta para completar la prueba sin esfuerzo. 😉
Analizando
Pinchamos sobre cualquiera.
Vemos un «Call» donde seguramente se generará un SUM en función del serial metido ya que después del Call vemos una comprobación contra «B79E763E» lo que nos da una pista de que vamos a tener que utilizar fuerza bruta para llegar a ese valor. Vamos a explorar el Call.
MOV EDI,5EED - EDI = 5EED JMP SHORT 01_crack.004010D7 /MOV EAX,EDI <----Bucle |SHL EAX,5 - 5EED * 32 = BDDA0 |MOVZX EDX,BYTE PTR DS:[EBX] - Coge el dígito |XOR EAX,EDX - BDDA0 XOR digito |MOV EDI,EAX |XOR EDI,1D0B1EED - XOR 1D0B1EED |INC EBX |.. |MOV ESI,EAX CMP BYTE PTR DS:[EBX],0 JNZ SHORT 01_crack.004010B4 - Bucle ---->
Para un serial de tres dígitos la secuencia sería esta (valores en hexadecimal):
2º Digit —> Temp = Temp * 20 Xor 1D0B1EED XOR 2ºDigit
3º Digit —> Temp = Temp * 20 Xor 1D0B1EED XOR 3ºDigit
…
CMP Temp, B79E763E
Aplicando Fuerza Bruta
La creación del «BruteForcer» os la dejo a vosotros. Aquí teneis un fragmento hecho en VB.Net.
Dim temp As Long Dim temp2 As String Dim letter As Integer Dim brute As String brute = TextBox4.Text temp = 0 temp = Asc(Mid(brute, 1, 1)) Xor 487268077 Xor 777632 temp2 = Hex(temp) temp2 = Microsoft.VisualBasic.Right(temp2, 8) temp = Convert.ToUInt64(temp2, 16) For i = 2 To Len(brute) letter = Asc(Mid(brute, i, 1)) temp = temp * 32 temp2 = Hex(temp) temp2 = Microsoft.VisualBasic.Right(temp2, 8) temp = Convert.ToUInt64(temp2, 16) temp = temp Xor 487268077 temp2 = Hex(temp) temp2 = Microsoft.VisualBasic.Right(temp2, 8) temp = Convert.ToUInt64(temp2, 16) temp = temp Xor letter ' temp2 = Hex(temp) Next
Links
Stego d33p

En este reto se nos entrega un archivo WAV de 9,92 MB. Tras escucharlo y analizarlo por encima con Audacity no llego a ningún lado por lo que me tiro al descarte de herramientas conocidas, y en ésta ocasión sale a escena DeepSound.
Sin más dilación extraemos el JPG y continuamos.
La aparición en escena de DeepSound me hace sospechar sobre el uso de herramientas conocidas y ¡bingo!, sale a escena StegHide. En esta ocasión el autor del reto nos lo ha puesto fácil y la extracción no requiere clave.
Al abrir el archivo TXT como texto vemos lo siguiente:
y si lo abrimos con un editor hexadecimal vemos esto otro:
Claramente el archivo esconde algo que por la repetición de los caracteres me hace sospechar de un simple XOR y efectivamente la flag está XOReada. Tras un ataque preliminar, digamos que los árboles no me dejaban ver el bosque, de modo que limpié los bytes correspondientes a la frase «this is the flag :)» y procesé de nuevo obteniendo por fin la ansiada flag.
RAW bytes
FF FE 74 00 68 00 69 00 73 00 20 00 40 DB 53 DC 40 DB 48 DC 40 DB 53 DC 40 DB 7B DC 40 DB 74 DC 69 00 73 00 20 00 40 DB 30 DC 40 DB 30 DC 40 DB 5F DC 40 DB 33 DC 40 DB 34 DC 74 00 68 00 65 00 20 00 40 DB 73 DC 40 DB 79 DC 40 DB 5F DC 40 DB 6D DC 40 DB 34 DC 66 00 6C 00 61 00 67 00 20 00 40 DB 6E DC 40 DB 7D DC 40 DB 20 DC 3A 00 29 00
Cleaned bytes [quitando this is the flag :)]
FF FE 40 DB 53 DC 40 DB 48 DC 40 DB 53 DC 40 DB 7B DC 40 DB 74 DC 40 DB 30 DC 40 DB 30 DC 40 DB 5F DC 40 DB 33 DC 40 DB 34 DC 40 DB 73 DC 40 DB 79 DC 40 DB 5F DC 40 DB 6D DC 40 DB 34 DC 40 DB 6E DC 40 DB 7D DC 40 DB 20 DC
clave XOR == 00fc60fb
Resultado
S H S { t 0 0 _ 3 4 s y _ m 4 n }
QR Stego Challenge

AVISO: Debido a que este reto está en activo no publicaré a donde pertenece.
Ya sabéis que los retos stego son muy variopintos. El otro día me encontré con uno que parecía que iba a ser complejo pero en realidad era bastante sencillo.
Tras varias pruebas complejas infructuosas, se me ocurrió descomponer por canales y efectivamente ese era el camino. Para ello yo utilicé la herramienta StegSolve de mi querido Caesum, pero podéis resolverlo incluso online con Pinetools.

WinFan’s NETCrackMe#1 Keygen

Introducción
Desempaquetado
Decompilado
Links
Migas de pan

Se nos entrega el siguiente ELF:
/* This file was generated by the Hex-Rays decompiler version 8.4.0.240320.
Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>
Detected compiler: GNU C++
*/
#include <defs.h>
//-------------------------------------------------------------------------
// Function declarations
__int64 (**init_proc())(void);
void sub_1020();
// int printf(const char *format, ...);
// int getchar(void);
// int fflush(FILE *stream);
// __int64 __isoc99_scanf(const char *, ...); weak
// void __noreturn exit(int status);
// int __fastcall _cxa_finalize(void *);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
FILE **deregister_tm_clones();
__int64 register_tm_clones(); // weak
FILE **_do_global_dtors_aux();
__int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD); // weak
int __fastcall main(int argc, const char **argv, const char **envp);
_BOOL8 __fastcall comprobacion(char a1, char a2, int a3);
void _libc_csu_fini(void); // idb
void term_proc();
// int __fastcall _libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// int __fastcall __cxa_finalize(void *);
// __int64 _gmon_start__(void); weak
//-------------------------------------------------------------------------
// Data declarations
_UNKNOWN _libc_csu_init;
__int64 (__fastcall *_frame_dummy_init_array_entry)() = &frame_dummy; // weak
__int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)() = &_do_global_dtors_aux; // weak
void *_dso_handle = &_dso_handle; // idb
char *a = "MdfnJk"; // weak
char *b = "jYx}"; // weak
char *c = "gWmfk"; // weak
char *d = "mlvpc"; // weak
char *f = "neU++w"; // weak
FILE *_bss_start; // idb
char completed_0; // weak
//----- (0000000000001000) ----------------------------------------------------
__int64 (**init_proc())(void)
{
__int64 (**result)(void); // rax
result = &_gmon_start__;
if ( &_gmon_start__ )
return (__int64 (**)(void))_gmon_start__();
return result;
}
// 40D0: using guessed type __int64 _gmon_start__(void);
//----- (0000000000001020) ----------------------------------------------------
void sub_1020()
{
JUMPOUT(0LL);
}
// 1026: control flows out of bounds to 0
//----- (0000000000001090) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
__int64 v3; // rax
int v4; // esi
__int64 v5; // [rsp-8h] [rbp-8h] BYREF
char *retaddr; // [rsp+0h] [rbp+0h] BYREF
v4 = v5;
v5 = v3;
_libc_start_main(
(int (__fastcall *)(int, char **, char **))main,
v4,
&retaddr,
(void (*)(void))_libc_csu_init,
_libc_csu_fini,
a3,
&v5);
__halt();
}
// 1096: positive sp value 8 has been found
// 109D: variable 'v3' is possibly undefined
//----- (00000000000010C0) ----------------------------------------------------
FILE **deregister_tm_clones()
{
return &_bss_start;
}
//----- (00000000000010F0) ----------------------------------------------------
__int64 register_tm_clones()
{
return 0LL;
}
// 10F0: using guessed type __int64 register_tm_clones();
//----- (0000000000001130) ----------------------------------------------------
FILE **_do_global_dtors_aux()
{
FILE **result; // rax
if ( !completed_0 )
{
if ( &__cxa_finalize )
_cxa_finalize(_dso_handle);
result = deregister_tm_clones();
completed_0 = 1;
}
return result;
}
// 4080: using guessed type char completed_0;
//----- (0000000000001175) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4; // [rsp+7h] [rbp-9h] BYREF
int v5; // [rsp+8h] [rbp-8h]
bool v6; // [rsp+Fh] [rbp-1h]
v6 = 1;
v5 = 0;
while ( v6 )
{
fflush(_bss_start);
printf("\nIntroduce la letra correcta:\t");
__isoc99_scanf("%c", &v4);
getchar();
if ( v5 > 5 )
{
if ( v5 > 9 )
{
if ( v5 > 14 )
{
if ( v5 > 19 )
v6 = comprobacion(v4, f[v5 - 20], 10);
else
v6 = comprobacion(v4, d[v5 - 15], 2);
}
else
{
v6 = comprobacion(v4, c[v5 - 10], 8);
}
}
else
{
v6 = comprobacion(v4, b[v5 - 6], 17);
}
}
else
{
v6 = comprobacion(v4, a[v5], 5);
}
if ( !v6 )
{
printf("Incorrecta");
exit(1);
}
printf("\n%c\n", (unsigned int)v4);
if ( v5 == 25 )
{
printf("Ya tienes la flag!!");
exit(1);
}
++v5;
}
return 0;
}
// 1060: using guessed type __int64 __isoc99_scanf(const char *, ...);
// 4050: using guessed type char *a;
// 4058: using guessed type char *b;
// 4060: using guessed type char *c;
// 4068: using guessed type char *d;
// 4070: using guessed type char *f;
//----- (0000000000001352) ----------------------------------------------------
_BOOL8 __fastcall comprobacion(char a1, char a2, int a3)
{
return a1 == (a3 ^ a2);
}
//----- (0000000000001390) ----------------------------------------------------
void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{
signed __int64 v4; // rbp
__int64 i; // rbx
init_proc();
v4 = &_do_global_dtors_aux_fini_array_entry - &_frame_dummy_init_array_entry;
if ( v4 )
{
for ( i = 0LL; i != v4; ++i )
((void (__fastcall *)(_QWORD, __int64, __int64))*(&_frame_dummy_init_array_entry + i))(a1, a2, a3);
}
}
// 1170: using guessed type __int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD);
// 3DE8: using guessed type __int64 (__fastcall *_frame_dummy_init_array_entry)();
// 3DF0: using guessed type __int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)();
//----- (00000000000013F4) ----------------------------------------------------
void term_proc()
{
;
}
Extracción de la Flag
Si nos fijamos en las líneas 41 a la 45 vemos las siguientes cadenas:
a = «MdfnJk»
b = «jYx}»
c = «gWmfk»
d = «mlvpc»
f = «neU++w»
Usaremos las cadenas y los valores XOR especificados para cada rango de v5 en el main (líneas 123 a 182) para determinar los caracteres correctos.
Para v5 de 0 a 5: v6 = comprobacion(v4, a[v5], 5);
Significa que: v4 debe ser igual a a[v5] ^ 5
Para v5 de 6 a 9: v6 = comprobacion(v4, b[v5 – 6], 17);
Significa que: v4 debe ser igual a b[v5 – 6] ^ 17
Para v5 de 10 a 14: v6 = comprobacion(v4, c[v5 – 10], 8);
Significa que: v4 debe ser igual a c[v5 – 10] ^ 8
Para v5 de 15 a 19: v6 = comprobacion(v4, d[v5 – 15], 2);
Significa que: v4 debe ser igual a d[v5 – 15] ^ 2
Para v5 de 20 a 25: v6 = comprobacion(v4, f[v5 – 20], 10);
Significa que: v4 debe ser igual a f[v5 – 20] ^ 10
Cálculo de los caracteres correctos:
Para v5 de 0 a 5:
a[0] = ‘M’, M ^ 5 = 0x4D ^ 0x05 = 0x48 -> ‘H’
a[1] = ‘d’, d ^ 5 = 0x64 ^ 0x05 = 0x61 -> ‘a’
a[2] = ‘f’, f ^ 5 = 0x66 ^ 0x05 = 0x63 -> ‘c’
a[3] = ‘n’, n ^ 5 = 0x6E ^ 0x05 = 0x6B -> ‘k’
a[4] = ‘J’, J ^ 5 = 0x4A ^ 0x05 = 0x4F -> ‘O’
a[5] = ‘k’, k ^ 5 = 0x6B ^ 0x05 = 0x6E -> ‘n’
Resulta en la cadena: HackOn
Para v5 de 6 a 9:
b[0] = ‘j’, j ^ 17 = 0x6A ^ 0x11 = 0x7B -> ‘{‘
b[1] = ‘Y’, Y ^ 17 = 0x59 ^ 0x11 = 0x48 -> ‘H’
b[2] = ‘x’, x ^ 17 = 0x78 ^ 0x11 = 0x69 -> ‘i’
b[3] = ‘}’, } ^ 17 = 0x7D ^ 0x11 = 0x6C -> ‘l’
Resulta en la cadena: {Hil
Para v5 de 10 a 14:
c[0] = ‘g’, g ^ 8 = 0x67 ^ 0x08 = 0x6F -> ‘o’
c[1] = ‘W’, W ^ 8 = 0x57 ^ 0x08 = 0x5F -> ‘_’
c[2] = ‘m’, m ^ 8 = 0x6D ^ 0x08 = 0x65 -> ‘e’
c[3] = ‘f’, f ^ 8 = 0x66 ^ 0x08 = 0x6E -> ‘n’
c[4] = ‘k’, k ^ 8 = 0x6B ^ 0x08 = 0x63 -> ‘c’
Resulta en la cadena: o_enc
Para v5 de 15 a 19:
d[0] = ‘m’, m ^ 2 = 0x6D ^ 0x02 = 0x6F -> ‘o’
d[1] = ‘l’, l ^ 2 = 0x6C ^ 0x02 = 0x6E -> ‘n’
d[2] = ‘v’, v ^ 2 = 0x76 ^ 0x02 = 0x74 -> ‘t’
d[3] = ‘p’, p ^ 2 = 0x70 ^ 0x02 = 0x72 -> ‘r’
d[4] = ‘c’, c ^ 2 = 0x63 ^ 0x02 = 0x61 -> ‘a’
Resulta en la cadena: ontra
Para v5 de 20 a 25:
f[0] = ‘n’, n ^ 10 = 0x6E ^ 0x0A = 0x64 -> ‘d’
f[1] = ‘e’, e ^ 10 = 0x65 ^ 0x0A = 0x6F -> ‘o’
f[2] = ‘U’, U ^ 10 = 0x55 ^ 0x0A = 0x5F -> ‘_‘
f[3] = ‘+’, + ^ 10 = 0x2B ^ 0x0A = 0x21 -> ‘!’
f[4] = ‘+’, + ^ 10 = 0x2B ^ 0x0A = 0x21 -> ‘!’
f[5] = ‘w’, w ^ 10 = 0x77 ^ 0x0A = 0x7D -> ‘}’
Resulta en la cadena: do_!!}
Uniendo todas las partes, obtenemos la flag completa: HackOn{Hilo_enc_ontrado_!!}
Reto Stego 1 de Hacker Games

Cambio de extensión (paso opcional)
Al descargar la imagen de la web del reto vemos que tiene la extensión php y lo más probable es que no nos abra correctamente.
... <br/> <img src="steg1img.php"/> <br/> ...
Abrimos la imagen con nuestro editor hexadecimal favorito y nos fijamos en la cabecera.
00000000h: 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 ; ‰PNG........IHDR
Renombramos entonces la extensión a png y continuamos.
Imagen oculta
Esta parte la afrontaremos con Steganabara, una herramienta muy útil que siempre uso cuando me enfrento a un reto «stego». En esta ocasión utilizaremos el análisis de color. Para ello pulsamos sobre «Analyse > Color table«.
En la tabla de colores tenemos la descomposición de colores RGBA y su frecuencia de aparición. Ordenamos por frecuencia descendiente y hacemos doble clic sobre la fila para abrir la imagen resultante.
A continuación un resumen de las imágenes obtenidas.
Como podéis observar, la imagen oculta es un código QR. Lo escaneamos con nuestra app preferida y obtenemos un texto encriptado.
dtsfwqutisvqtesymkuvabbujwhfecuvlshwopcyeghguywjvlaibflcacyahckyqvypjntfhihgtvyxeqakjwouldltuiuhbhjumgkxuugqahvwhotduqtahcknheypjetxpvlhxtlrpjagyjzcgijgfjmcupsslkzpuxegaillytlfbygeptzjtuzlvlwkzdznxqwpabbe
Descifrando el mensaje
A partir de aquí el reto pasa a ser de encriptación. Con el tiempo diferenciareis fácilmente el tipo de cifrado con sólo ver el texto. En este caso lo primero que se nos ocurre es comprobar dos cifrados clásicos como son el cifrado César y el Vigenere.
Tras desestimar el cifrado César realizamos un ataque de «fuerza bruta» al cifrado Vigenere mediante análisis estadístico. En la imagen que muestro a continuación se puede ver que la clave está cerca de ser «HPHQTC» pero todavía no se lee correctamente.
Ya que la fuerza bruta de por sí no termina de darnos la respuesta correcta, pasamos a probar algo muy útil, esto es, descifrar por fuerza bruta pero dándole una palabra para comparar. En este caso en concreto vemos que una posible palabra que pudiera estar en el texto encriptado es «PASSWORD», probamos y reto terminado.
Enlaces
CanYouHack.it Crack6 Challenge – Lights Out (English)

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Intro
This crackme is for the crack challenge 6 of canyouhack.it.
Tools
Exeinfo (For crackme info)
Delphi Decompiler (For decompile)
OllyDbg (For debug)
Decompiling
Links
Retos reversing de Challengeland.co

Introducción
Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro uso y disfrute. Desgraciadamente ya no está en activo la web de retos de donde los saqué así que os los dejo en descargas.
Los cuatro primero están realizados en Dev-C++ 4.9.9.2 siendo de estilo consola de comandos. Los dos restantes compilados con MingWin32 GCC 3.x carecen de GUI y vamos, que no se han esmerado mucho en darles forma.
Level 1
No cuesta mucho dar con el código interesante mediante las referencias de texto. En Ollydbg clic derecho sobre el código y Search for > All referenced text strings.
004012E1 |. 8845 E8 MOV BYTE PTR SS:[EBP-18],AL ; |||| 004012E4 |. C70424 11304000 MOV DWORD PTR SS:[ESP],level1.00403011 ; ||||ASCII "Input Serial: " 004012EB |. E8 C0050000 CALL <JMP.&msvcrt.printf> ; |||\printf 004012F0 |. 8D45 C8 LEA EAX,[LOCAL.14] ; ||| 004012F3 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; ||| 004012F7 |. C70424 20304000 MOV DWORD PTR SS:[ESP],level1.00403020 ; |||ASCII "%s" 004012FE |. E8 9D050000 CALL <JMP.&msvcrt.scanf> ; ||\scanf 00401303 |. 8D45 D8 LEA EAX,[LOCAL.10] ; || 00401306 |. 8D55 C8 LEA EDX,[LOCAL.14] ; || 00401309 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; || 0040130D |. 891424 MOV DWORD PTR SS:[ESP],EDX ; ||level1.00403022 00401310 |. E8 7B050000 CALL <JMP.&msvcrt.strcmp> ; |\strcmp 00401315 |. 8945 C4 MOV [LOCAL.15],EAX ; | 00401318 |. 837D C4 00 CMP [LOCAL.15],0 ; | 0040131C |. 75 0E JNZ SHORT level1.0040132C ; | 0040131E |. C70424 23304000 MOV DWORD PTR SS:[ESP],level1.00403023 ; |ASCII "Well done. \n" 00401325 |. E8 86050000 CALL <JMP.&msvcrt.printf> ; \printf 0040132A |. EB 0C JMP SHORT level1.00401338 0040132C |> C70424 30304000 MOV DWORD PTR SS:[ESP],level1.00403030 ; |ASCII "Wrong. \n" 00401333 |. E8 78050000 CALL <JMP.&msvcrt.printf> ; \printf 00401338 |> C70424 39304000 MOV DWORD PTR SS:[ESP],level1.00403039 ; |ASCII "PAUSE" 0040133F |. E8 3C050000 CALL <JMP.&msvcrt.system> ; \system 00401344 |. B8 00000000 MOV EAX,0 00401349 |. C9 LEAVE 0040134A \. C3 RETN
La madre del cordero está en la dirección 401310 que es donde se lleva a cabo la función de comparación strcmp.
756296A0 msvcrt.strcmp 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4] 756296A4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8] 756296A8 F7C2 03000000 TEST EDX,3 ; 0-3 = 4 bucles. Divide la comprobación en 4 bloques 756296AE 75 3C JNZ SHORT msvcrt.756296EC ; salta si hemos terminado los 4 bucles 756296B0 > 8B02 MOV EAX,DWORD PTR DS:[EDX] ; coge 4 caracteres del serial (INICIO BUCLE) 756296B2 3A01 CMP AL,BYTE PTR DS:[ECX] ; compara el 1º/5º/9º/13º dígito en función del bucle 756296B4 75 2E JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296B6 0AC0 OR AL,AL 756296B8 74 26 JE SHORT msvcrt.756296E0 756296BA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1] ; compara el 2º/6º/10º/14º dígito en función del bucle 756296BD 75 25 JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296BF 0AE4 OR AH,AH 756296C1 74 1D JE SHORT msvcrt.756296E0 756296C3 C1E8 10 SHR EAX,10 756296C6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2] ; compara el 3º/7º/11º/15º dígito en función del bucle 756296C9 75 19 JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296CB 0AC0 OR AL,AL 756296CD 74 11 JE SHORT msvcrt.756296E0 756296CF 3A61 03 CMP AH,BYTE PTR DS:[ECX+3] ; compara el 4º/8º/12º/16º dígito en función del bucle 756296D2 75 10 JNZ SHORT msvcrt.756296E4 ; salto a zona mala 756296D4 83C1 04 ADD ECX,4 756296D7 83C2 04 ADD EDX,4 756296DA 0AE4 OR AH,AH 756296DC ^ 75 D2 JNZ SHORT msvcrt.756296B0 ; Si no hemos terminado... 756296DE 8BFF MOV EDI,EDI 756296E0 33C0 XOR EAX,EAX ; EAX = 0 que es lo deseado 756296E2 C3 RETN ; salimos de la función superando la comprobación 756296E3 90 NOP 756296E4 1BC0 SBB EAX,EAX ; Zona mala 756296E6 D1E0 SHL EAX,1 756296E8 83C0 01 ADD EAX,1 ; EAX = 1 implica bad boy 756296EB C3 RETN ; salimos de la función
Si atendemos al volcado vemos el serial bueno Kcgcv8LsmV3nizfJ.
0060FEF0 31 32 33 34 35 36 37 38 39 30 00 75 40 19 18 00 1234567890.u@. 0060FF00 4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A Kcgcv8LsmV3nizfJ
Curiosamente, si introducimos el serial bueno el crackme no lo acepta. Fijándome en la comprobación veo que al introducir un serial de 16 caracteres inserta un carácter nulo (0x00) alterando el serial correcto y falseando la comprobación.
0060FEF0 4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A Kcgcv8LsmV3nizfJ 0060FF00 00 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A .cgcv8LsmV3nizfJ
Ahora ya no podemos comprobarlo pero recuerdo que la web consideraba válido el serial Kcgcv8LsmV3nizfJ, por lo que considero lo anteriormente citado un bug o un intento de despiste del autor.
Level 2
Es exactamente igual que el anterior cambiando el serial por 6LPw3vDYja9KrT2V.
Level 3
La comprobación del serial es igual a las dos anteriores pero añade una función intermedia que suma 0xD a cada carácter de nuestro serial
00401355 |. A1 03304000 MOV EAX,DWORD PTR DS:[403003] ; || 0040135A |. 8945 E8 MOV [LOCAL.6],EAX ; || 0040135D |. A1 07304000 MOV EAX,DWORD PTR DS:[403007] ; || 00401362 |. 8945 EC MOV [LOCAL.5],EAX ; || 00401365 |. A1 0B304000 MOV EAX,DWORD PTR DS:[40300B] ; || 0040136A |. 8945 F0 MOV [LOCAL.4],EAX ; || 0040136D |. A1 0F304000 MOV EAX,DWORD PTR DS:[40300F] ; || 00401372 |. 8945 F4 MOV [LOCAL.3],EAX ; || 00401375 |. C70424 13304000 MOV DWORD PTR SS:[ESP],level3.00403013 ; ||ASCII "Input Serial: " 0040137C |. E8 CF050000 CALL <JMP.&msvcrt.printf> ; |\printf 00401381 |. 8D45 D8 LEA EAX,[LOCAL.10] ; | 00401384 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; | 00401388 |. C70424 00304000 MOV DWORD PTR SS:[ESP],level3.00403000 ; |ASCII "%s" 0040138F |. E8 AC050000 CALL <JMP.&msvcrt.scanf> ; \scanf 00401394 |. 8D5D E8 LEA EBX,[LOCAL.6] 00401397 |. 8D45 D8 LEA EAX,[LOCAL.10] 0040139A |. 890424 MOV DWORD PTR SS:[ESP],EAX 0040139D |. E8 EEFEFFFF CALL level3.00401290 ; NUEVA FUNCIÓN SUMA 004013A2 |. 895C24 04 MOV DWORD PTR SS:[ESP+4],EBX ; || 004013A6 |. 890424 MOV DWORD PTR SS:[ESP],EAX ; || 004013A9 |. E8 82050000 CALL <JMP.&msvcrt.strcmp> ; |\strcmp 004013AE |. 8945 D4 MOV [LOCAL.11],EAX ; | 004013B1 |. 837D D4 00 CMP [LOCAL.11],0 ; | 004013B5 |. 75 0E JNZ SHORT level3.004013C5 ; | 004013B7 |. C70424 22304000 MOV DWORD PTR SS:[ESP],level3.00403022 ; |ASCII "Well done." 004013BE |. E8 8D050000 CALL <JMP.&msvcrt.printf> ; \printf 004013C3 |. EB 0C JMP SHORT level3.004013D1 004013C5 |> C70424 2D304000 MOV DWORD PTR SS:[ESP],level3.0040302D ; |ASCII "Wrong. \n" 004013CC |. E8 7F050000 CALL <JMP.&msvcrt.printf> ; \printf 004013D1 |> C70424 36304000 MOV DWORD PTR SS:[ESP],level3.00403036 ; |ASCII "PAUSE" 004013D8 |. E8 43050000 CALL <JMP.&msvcrt.system> ; \system 004013DD |. B8 00000000 MOV EAX,0 004013E2 |. 8B5D FC MOV EBX,[LOCAL.1] 004013E5 |. C9 LEAVE 004013E6 \. C3 RETN -------- 004012A4 |> /8B45 08 /MOV EAX,[ARG.1] ; | 004012A7 |. |890424 |MOV DWORD PTR SS:[ESP],EAX ; | 004012AA |. |E8 B1060000 |CALL <JMP.&msvcrt.strlen> ; \strlen 004012AF |. |3945 FC |CMP [LOCAL.1],EAX 004012B2 |. |73 1C |JNB SHORT level3.004012D0 004012B4 |. |8B45 08 |MOV EAX,[ARG.1] 004012B7 |. |8B55 FC |MOV EDX,[LOCAL.1] 004012BA |. |01C2 |ADD EDX,EAX 004012BC |. |8B45 08 |MOV EAX,[ARG.1] 004012BF |. |0345 FC |ADD EAX,[LOCAL.1] 004012C2 |. |0FB600 |MOVZX EAX,BYTE PTR DS:[EAX] 004012C5 |. |04 0D |ADD AL,0D ; char + 0xD 004012C7 |. |8802 |MOV BYTE PTR DS:[EDX],AL 004012C9 |. |8D45 FC |LEA EAX,[LOCAL.1] 004012CC |. |FF00 |INC DWORD PTR DS:[EAX] 004012CE |.^\EB D4 \JMP SHORT level3.004012A4 -------- 756296A0 msvcrt.strcmp 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4] 756296A4 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8] 756296A8 F7C2 03000000 TEST EDX,3 756296AE 75 3C JNZ SHORT msvcrt.756296EC 756296B0 8B02 MOV EAX,DWORD PTR DS:[EDX] 756296B2 3A01 CMP AL,BYTE PTR DS:[ECX] 756296B4 75 2E JNZ SHORT msvcrt.756296E4 756296B6 0AC0 OR AL,AL 756296B8 74 26 JE SHORT msvcrt.756296E0 756296BA 3A61 01 CMP AH,BYTE PTR DS:[ECX+1] 756296BD 75 25 JNZ SHORT msvcrt.756296E4 756296BF 0AE4 OR AH,AH 756296C1 74 1D JE SHORT msvcrt.756296E0 756296C3 C1E8 10 SHR EAX,10 756296C6 3A41 02 CMP AL,BYTE PTR DS:[ECX+2] 756296C9 75 19 JNZ SHORT msvcrt.756296E4 756296CB 0AC0 OR AL,AL 756296CD 74 11 JE SHORT msvcrt.756296E0 756296CF 3A61 03 CMP AH,BYTE PTR DS:[ECX+3] 756296D2 75 10 JNZ SHORT msvcrt.756296E4 756296D4 83C1 04 ADD ECX,4 756296D7 83C2 04 ADD EDX,4 756296DA 0AE4 OR AH,AH 756296DC ^ 75 D2 JNZ SHORT msvcrt.756296B0 756296DE 8BFF MOV EDI,EDI 756296E0 33C0 XOR EAX,EAX 756296E2 C3 RETN 756296E3 90 NOP 756296E4 1BC0 SBB EAX,EAX 756296E6 D1E0 SHL EAX,1 756296E8 83C0 01 ADD EAX,1 756296EB C3 RETN
En la comparación vemos que el serial bueno es AvrQQsXjDk25Jrh por lo que si restamos 0xD (13 en decimal) a cada carácter obtendremos el serial bueno.
0060FF10 41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 00 AvrQQsXjDk25Jrh. 41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 - D 34 69 65 44 44 66 4B 5D 37 5E 25 28 3D 65 5B 4 i e D D f K ] 7 ^ % ( = e [ Serial bueno: 4ieDDfK]7^%(=e[
Level 4
La comprobación del serial es igual que la anterior pero sustituyendo la función que sumaba un valor a cada dígito del serial por una que genera un hash con nuestro serial y después lo compara con otro hash almacenado en memoria. Si no nos viene a la mente el tipo de hash que puede ser PEiD ya nos avisaba de que efectivamente el crackme incorpora la función MD5.
La función MD5 hace tiempo que no se considera segura debido a la existencia de numerosos «diccionarios» de hashes que hacen que encontremos la solución en segundos. Yo he utilizado la web MD5 online pero existen muchas más.
0060FE5C 004013BF RETURN to level4.004013BF from <JMP.&msvcrt.strcmp> 0060FE60 0060FEA0 ASCII "e807f1fcf82d132f9bb018ca6738a19f" 0060FE64 0060FEE0 ASCII "fe01d67a002dfa0f3ac084298142eccd" e807f1fcf82d132f9bb018ca6738a19f == 1234567890 fe01d67a002dfa0f3ac084298142eccd == orange
Level 5
La carta de presentación de este crackme es la imagen que veis arriba. Al explorarlo unos minutos enseguida nos damos cuenta de que no realiza ninguna comprobación y que nos está haciendo perder el tiempo. Ahí es cuando empezamos a revisar el ejecutable más a fondo y enseguida encontramos la solución con nuestro amigo el editor hexadecimal.
Level 6
Misma carta de presentación que el anterior y misma ausencia de comprobación del serial. En esta ocasión echando un vistazo a los recursos encontramos la solución rápidamente.
Enlaces
Keygen para el KeygenMe#01 de eBuC – Comparación lineal

Primeras impresiones
Determinando la rutina de creación del serial con Ollydbg
Generando un serial válido
Como se muestra en la imagen siguiente, la creación del serial es muy sencilla y al final la comparación es lineal ya que se compara nuestro serial con el serial válido. Veamos el serial válido para el usuario “abc” cuyos dígitos en hexadecimal son 0x61, 0x62 y 0x63.
|
Letra a
|
Letra b
|
Letra c
|
|
Suma + 0x61
Suma * 0x20
Suma xor 0xBEFF
Suma / 4
Suma = 0x2CB7
|
Suma + 0x62
Suma * 0x20
Suma xor 0xBEFF
Suma / 4
Suma = 0x14777
|
Suma + 0x63
Suma * 0x20
Suma xor 0xBEFF
Suma / 4
Suma = 0xA116F
|
|
Suma xor 0xBEA4 = 0xAAFCB
|
||
|
Serial válido = 700363
|
||
Generando un keygen con WinASM studio desde cero
- szFormat está declarada en formato integer (%i). Más tarde la utilizaremos junto a la función wsprintf para dar formato a un número.
- szSizeMin: habla por sí misma.
- szSizeMax: habla por sí misma.
- szCap: habla por sí misma.
- szName: contendrá el nombre introducido.
- szCode: contendrá el serial válido.
Enlaces
QR Stego Challenge

AVISO: Debido a que este reto está en activo no publicaré a donde pertenece.
Ya sabéis que los retos stego son muy variopintos. El otro día me encontré con uno que parecía que iba a ser complejo pero en realidad era bastante sencillo.
Tras varias pruebas complejas infructuosas, se me ocurrió descomponer por canales y efectivamente ese era el camino. Para ello yo utilicé la herramienta StegSolve de mi querido Caesum, pero podéis resolverlo incluso online con Pinetools.

ThisIsLegal.com – Realistic Challenge 5

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
Analizando a la víctima
Echamos un vistazo a la web y lo único interesante que vemos es un buscador.
Miramos el código fuente y vemos una ruta interesante.
Ahora fijémonos en el menú productos. Pinchamos sobre cualquier producto y a continuación en la imagen para ampliarla, veremos el siguiente enlace.
Explotando la víctima
Vamos a ver si podemos explotar «i.php«. Probamos a obtener información sensible del servidor.
Probamos «http://www.thisislegal.com/nc/i.php?img=adm/login.pwd» y nos da error, seguramente por que está anexionando la extensión de la imagen, es decir, el script está interpretando esto:
Vamos a anularlo con un caracter nulo. Probamos y ahora si.
El password está en base64. Lo decodificamos online, nos logueamos y reto superado.
Links
Descargar contenido multimedia de ciertas webs

Hoy en día, la descarga de contenido multimedia de ciertas webs es imposible o muy difícil. En ciertos casos lo entiendo, exponer el contenido supone una pérdida de ingresos y eso es inaceptable. Las cadenas de TV son tema aparte, emiten contenido por varios medios y les gusta que lo veas y que lo compartas, eso sí, que lo compartas desde su plataforma, ya que lo que estás compartiendo es un enlace, no el vídeo.
Este caso es un caso intermedio entre una plataforma de pago que codifica sus contenidos y una web que nos permita descargar su contenido directamente.
Imaginemos que vemos un vídeo y queremos mandarlo por Whatsapp a nuestros amigos. Lo primero es echar un vistazo al código fuente de la web y localizar el código del reproductor web (player). Para esta tarea podemos ayudarnos de una extensión muy conocida para navegadores como es Firebug. Una vez instalada, la activamos con F12 y mediante el botón Inspect localizamos el player.
...
<p itemprop="keywords" itemscope="itemscope" itemtype="http://schema.org/Text" class="antetitulo" lang="es">EL INTERMEDIO LE PILLA EN "EL TRONO"</p>
<h1 class="title-new" itemprop="headline">Joaquín Reyes se mete en la piel de Juan Carlos I: "Soy tan campechano que podéis llamarme Juan Carlos Palote"</h1>
<sumary class="entradilla" itemprop="description">
<p><p class="MsoNormal">Los reyes eméritos han celebrado sus bodas de esmeralda y
con motivo de tan señalada fecha, Juan Carlos I ha hecho un hueco en su
apretada agenda para concederle unos minutos a <a title="<b>El Intermedio</b>" href="http://www.lasexta.com/temas/el_intermedio-1" target="_blank"><b>El Intermedio</b></a>. Eso sí, en su
versión de <a title="<b>Joaquín Reyes</b>" href="http://www.lasexta.com/temas/joaquin_reyes-1" target="_blank"><b>Joaquín Reyes</b></a>. <o:p></o:p></p> </sumary>
<div class="great-element-multimedia">
<section class="modVideo a3mod_player" data-mod="a3mod_player" data-model="/json/video/7/2017/05/15/591a08c1986b2810b31577c1.json">
<a itemprop="url" href="#" class="icon link-content" title="" data-mod-elem="icon">
<div class="wrap-img" role="banner">
<div itemprop="video" itemscope itemtype="http://schema.org/VideoObject">
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source media="(max-width:520px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/64.jpg" />
<source media="(max-width:1023px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/60.jpg" />
<source media="(min-width:1024px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/58.jpg" />
<!--[if IE 9]></video><![endif]-->
<img src="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/58.jpg" alt="Joaquín Reyes, como el rey Juan Carlos I" title="Joaquín Reyes, como el rey Juan Carlos I" />
</picture>
<meta itemprop="description" content=""/>
<meta itemprop="name" content=""/>
<meta itemprop="thumbnailUrl" content="" />
<meta itemprop="uploadDate" content=""/>
<meta itemprop="url" content=""/>
<meta itemprop="width" content=""/>
<meta itemprop="height" content=""/>
</div>
</div>
</a>
</section>
</div>
...
Si os fijáis bien, el reproductor hace referencia a un archivo json (591a08c1986b2810b31577c1.json), reconstruimos la url y miramos su contenido
{"id":"591a08c1986b2810b31577c1","type":"video","tipo":"video","subtipo":"video","imgThumb":"http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/29.jpg","imgPoster":"http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/31.jpg","live":false,"autoplay":true,"sources":[{"src":"http://vclip.atresmedia.com/vclip/_definst_/smil:assets10/2017/05/15/01229E28-A57E-4AC9-AFE7-EF1C27B5AA2A/es.smil/manifest_mvlist.mpd","type":"application/dash+xml"},{"src":"http://vclip.atresmedia.com/vclip/_definst_/smil:assets10/2017/05/15/01229E28-A57E-4AC9-AFE7-EF1C27B5AA2A/es.smil/playlist.m3u8","type":"application/vnd.apple.mpegurl"}],"omniture":{"section":"Joaquín Reyes","category":"El Intermedio","channel":"lasexta","type":"short","name":"Joaquín Reyes se mete en la piel de Juan Carlos I: \"Soy tan campechano que podéis llamarme Juan Carlos Palote\"","embeddedMode":false},"comscore":{"comscoreTag":"LASEXTA.COM","channel":"lasexta","kantar":{"programID":"1019","firstBroadcastDate":"*null","firstBroadcastTime":"*null","typeTvStream":"0002","kantarGenre":"0","channelId":"240"},"content_form":"short_form"},"urlHits":"http://hits.lasexta.com/l6//591a08c1986b2810b31577c1/3/348128,351435,351827,351865/","duration":"211.797333","embeddedUrl":"<iframe src=\"http://www.lasexta.com/embed/el-intermedio-le-pilla-en-el-trono/video/7/2017/05/15/591a08c1986b2810b31577c1\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen></iframe>","playondraw":true,"nextRelated":{"service_url":"http://www.lasexta.com/json/video/7/2017/05/15/591a08c1986b2810b31577c1_related.json"},"subtitle":[],"titulo":"Joaquín Reyes se mete en la piel de Juan Carlos I: \"Soy tan campechano que podéis llamarme Juan Carlos Palote\"","descripcion":"","sociales":{"hasTwitter":true,"hasFacebook":true,"hasGooglePlus":true,"hasWhatsapp":true,"twitter":"EL INTERMEDIO LE PILLA EN “EL TRONO”","facebook":"EL INTERMEDIO LE PILLA EN “EL TRONO”","googlePlus":"EL INTERMEDIO LE PILLA EN “EL TRONO”","whatsapp":"","hashtag":"","via":"sextaNoticias","urlPage":"https://goo.gl/cu98f0"},"vp_data":{"vp_category":"Atresmedia/Lasexta/programas/el-intermedio*","vp_tags":"","vp_content_form":"short_form"}}
Se puede ver a simple vista una lista de reproducción playlist.m3u8, cuyo contenido contiene más listas de reproducción con diferentes calidades.
#EXTM3U #EXT-X-VERSION:3 #EXT-X-STREAM-INF:BANDWIDTH=796400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=640x360 chunklist_b724000.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1159400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=640x360 chunklist_b1054000.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1643400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=720x404 chunklist_b1494000.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=2248400,CODECS="avc1.77.31,mp4a.40.5",RESOLUTION=1280x720 chunklist_b2044000.m3u8
Reconstruimos la URL para la lista de reproducción de mayor calidad e inspeccionamos su contenido.
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, media_b2044000_0.ts #EXTINF:10.0, media_b2044000_1.ts #EXTINF:10.0, media_b2044000_2.ts #EXTINF:10.0, media_b2044000_3.ts #EXTINF:10.0, media_b2044000_4.ts #EXTINF:10.0, media_b2044000_5.ts #EXTINF:10.0, media_b2044000_6.ts #EXTINF:10.0, media_b2044000_7.ts #EXTINF:10.0, media_b2044000_8.ts #EXTINF:10.0, media_b2044000_9.ts #EXTINF:10.0, media_b2044000_10.ts #EXTINF:10.0, media_b2044000_11.ts #EXTINF:10.0, media_b2044000_12.ts #EXTINF:10.0, media_b2044000_13.ts #EXTINF:10.0, media_b2044000_14.ts #EXTINF:10.0, media_b2044000_15.ts #EXTINF:10.0, media_b2044000_16.ts #EXTINF:10.0, media_b2044000_17.ts #EXTINF:10.0, media_b2044000_18.ts #EXTINF:10.0, media_b2044000_19.ts #EXTINF:10.0, media_b2044000_20.ts #EXTINF:1.92, media_b2044000_21.ts #EXT-X-ENDLIST
Se pueden ver 21 archivos con extensión TS de 10 segundos cada uno a excepción del último que dura 1.92 segundos. Los archivos TS no son más que archivos MP4 por lo que una vez descargados, los podemos unir con MP4Tools por ejemplo.
La tarea es costosa, pero si os apetece enviar un vídeo en vez de un enlace, ya sabéis que en determinados casos se puede hacer.
CanYouHack.it Mobile1 Challenge – Simple Comparison (English)

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
























































































