- Introducción
- Javascript 1 (Serial a la vista)
- Javascript 2 (La función charAt())
- Javascript 3 (Input)
- Javascript 4 (Fuerza bruta manual)
- Javascript 5 (Fuerza bruta)
- Enlaces
Introducción
Los retos de Javascript son los retos más sencillos que podemos encontrar. Muchas veces solamente mirando el código fuente obtenemos la respuesta. Suponen una mala implementación de seguridad debido a que el código se ejecuta del lado del cliente, por lo que el código fuente es accesible y por lo tanto, javascript no garantiza seguridad alguna. En estos cinco casos haremos un recorrido por lo más básico, cinco retos fáciles de superar y que nos proporcionan los conocimientos base para Javascript. Dicho esto os puedo asegurar que en ocasiones he encontrado retos javascript realmente complicados que requieren de horas descifrarlos y en los que es fácil tirar la toalla.
Cuando el reto lo requiera, es buena idea utilizar un compilador online para obtener de forma rápida el valor de una variable o realizar una prueba concreta. Yo utilizo Jsfiddle para realizar pruebas pero existen muchos más.
Javascript 1
Este primer reto es lo básico, en el código fuente se pueden apreciar directamente el usuario y la clave.
<script language=JavaScript> function Verify(name,pass) { if (name=="admin" & pass=="3***3") { location.href = name + pass + '.htm'; } else { alert("Si ya fallamos el primero..."); }; } </script>
Javascript 2
Este segundo reto es bastante sencillo pero ya te obliga a conocer la función charAt() de Javascript. Dicha función lo que hace es coger el caracter indicado mediante un índice que comienza en cero. Por ejemplo si nombre = deurus y hacemos letra = nombre.charAt(3), estariámos extrayendo la cuarta letra, es decir, la letra r de la variable nombre.
function Verify(name,pass) { var name1 = "CrawlinG", pass1 = "capriccio" if (name==name1 & pass==pass1) { location.href = name + ".htm"; } else { var x = name1.charAt(7) + pass1.charAt(3)+ name1.charAt(2) + pass1.charAt(5) + name1.charAt(5) + pass1.charAt(1);x = x.toLowerCase(); var y = name.charAt(3) + name.charAt(1) + pass.charAt(1)+ pass.charAt(6) + pass.charAt(7) + name.charAt(2);var x1 = "des" + y; if (x==y){location.href = x1 + ".htm"}else{alert("Esto no va bien");location.href = "js2.htm"} } }
Lo interesante está en la formación de las variables x e y. La variable x se forma de las variables name1 y pass1, formando la palabra gracia. Por otro lado, la variable y se forma con el nombre y clave que introduzcamos nosotros. Vemos que la variable x e y deben ser iguales, por lo tanto debemos construir un nombre (name) y una clave (pass) que cumpla con lo siguiente:
- 4ª letra del nombre = 1ª letra de la palabra «gracia»
- 2ª letra del nombre = 2ª letra de la palabra «gracia»
- 2ª letra de la clave = 3ª letra de la palabra «gracia»
- 7ª letra de la clave = 4ª letra de la palabra «gracia»
- 8ª letra de la clave = 5ª letra de la palabra «gracia»
- 3ª letra del nombre = 6ª letra de la palabra «gracia«
Como véis simplemente se trata de interpretar correctamente la función charAt() y de fijarse bien en los nombres de las variables.
Javascript 3
Este reto nos muestra diálogo donde nos pide la contraseña para validar el reto. Al fallar o cancelar vuelve al índice para no dejarnos ver el código fuente. Aquí se pueden seguir varios caminos como bloquear el uso de javascript en el navegador o instalar un plugin en chrome o firefox para habilitar/deshabilitar de forma rápida el uso de javascript.
Una vez deshabilitado javascript vemos lo siguiente:
<script language="JavaScript" src="js3.gif" type=text/javascript> <!-- function verify() { var pass="thebest"; var password=prompt("Introduce el password para superar el nivel",""); if (password==pass) { location.href = pass + ".htm"; } else { alert("No vamos bien..."); location.href = "index.htm"; } } //--> </script>
Aquí el truco es darse cuenta que el código que se está ejecutando esta en «js3.gif» y no el código que nos muestra como válida la clave thebest. Si descargamos el archivo js3.gif y lo abrimos con un archivo de texto vemos nuestra querida clave.
function verify() { var pass="mo****ver"; var password=prompt("Introduce el password para superar el nivel",""); if (password==pass) { location.href = pass + ".htm"; } else { alert("No vamos bien..."); location.href = "index.htm"; } }
Javascript 4
En este reto ya entramos con que la clave no es reversible y la debemos obtener por fuerza bruta. En este reto utiliza una nueva función como charCodeAt() que lo que hace es obtener el valor ascii del caracter indicado.
function Verify(pass1) { var cont1= 2, cont2= 6 var suma1 = 0, suma2 = 0 var pass2 = "FDRLF" for(i = 0; i < pass1.length; i++) { suma1 += (pass1.charCodeAt(i) * cont1); cont1++ } for(i = 0; i < pass2.length; i++) { suma2 += (pass2.charCodeAt(i) * cont2); cont2++ } if (suma1==suma2) { window.location=suma1+".htm"; } else { alert ("Algo no va bien..."); } }
Vemos dos bucles en los que se calculan sendos valores suma que finalmente se comparan. la variable suma1 se calcula mediante nuestro password y la variable suma2 la obtiene de la palabra «FDRLF». Con el script que os muestro a continuación obtenemos que usando como clave deurus, suma1 = 3048 y suma2 = 2936. Nuestro punto de referencia es suma2 = 2936, de modo que vamos alterando con paciencia la variable pass1 obteniendo valores cercanos a 2936. Por ejemplo «deurua» nos da suma1 = 2922, un valor bastante cercano.
var pass1 = "deurus"; var cont1= 2, cont2= 6 var suma1 = 0, suma2 = 0 var pass2 = "FDRLF" for(i = 0; i < pass1.length; i++) { suma1 += (pass1.charCodeAt(i) * cont1); cont1++ } for(i = 0; i < pass2.length; i++) { suma2 += (pass2.charCodeAt(i) * cont2); cont2++ } alert (suma1); alert (suma2);
La solución a este reto es múltiple. Dos claves válidas son por ejemplo dfurqf y zwfabz.
Javascript 5
Este último reto es similar al anterior pero ya nos obliga a crearnos una pequeña herramienta que nos busque el serial válido.
function Verify(pass) { var suma=0 var cadena = "abcdefghijklmnopqrstuvwxyz" for (var i = 0; i < pass.length; i++) { var letra = pass.charAt(i) var valor = (cadena.indexOf(letra)) valor++ suma *= 26 suma += valor } if (suma==6030912063) { window.location=pass+".htm"; } else { alert ("Algo no va bien..."); } }
Para esta ocasión utiliza una nueva función llamada indexOf() que lo que hace es devolver un número entero que representa la posición en la que se encuentra el parámetro pasado a la función. Por ejemplo, si tengo variable = deurus y realizo posición = variable.indexOf(«s»), obtengo como resultado 5 (se empieza a contar desde cero).
Las operaciones que realiza el bucle son las siguientes:
- Coge las letras del nombre una a una.
- valor = posición de nuestra letra dentro de la variable de texto llamada cadena.
- valor = valor + 1.
- Multiplica la variable suma por 26.
- Suma = suma + valor.
Aunque el proceso de recuperación de esta clave es algo más largo, podemos acortarlo introduciendo una clave de inicio de fuerza bruta próxima al objetivo. Al ser una función bastante lineal podemos rápidamente mediante pruebas con nuestro código de fuerza bruta o con un compilador online, establecer que la clave tendrá 7 caracteres e incluso que para ahorrar tiempo podemos aproximar la clave para que su valor suma esté cercano al valor suma buscado 6030912063.
Realizando pruebas obtenemos:
- Clave = aaaaaaa -> suma = 321272407
- Clave = zzzzzzz -> suma = 8353082582
- Clave = smaaaaa -> suma = 6024332887
- Clave = smkkkkk -> suma = 6029085437
Como vemos, la clave smkkkkk ya está bastante próxima al objetivo y será un buen punto para lanzar la fuerza bruta.
Os dejo el código de fuerza bruta en .Net
Module Module1 Sub Main() inicio: Console.WriteLine("-------------------------") Console.WriteLine("Modo [1] Prueba password") Console.WriteLine("Modo [2] Fuerza bruta") Console.WriteLine("-------------------------") Dim modo = Console.ReadLine() ' If modo = 2 Then Console.WriteLine("¿Password para comenzar?") Dim pass = Console.ReadLine() inicio2: Dim cadena As String = "abcdefghijklmnopqrstuvwxyz" Dim valor As Integer = 0 Dim suma As Long = 0 Dim letra As String For i = 0 To pass.Length - 1 letra = Mid(pass, i + 1, 1) valor = cadena.IndexOf(letra) valor += 1 suma *= 26 suma += valor Next Console.WriteLine("Password: " & pass & " - Sum: " & suma.ToString) pass = IncrementString(pass) If suma = 6030912063 Then MsgBox("Password is " & pass) Else If pass = "aaaaaaaa" Then Console.WriteLine("pass not found") Console.ReadKey() Else GoTo inicio2 End If End If End If '------------------------------------------------ If modo = 1 Then Console.WriteLine("Password:") Dim pass = Console.ReadLine() Dim cadena As String = "abcdefghijklmnopqrstuvwxyz" Dim valor As Integer = 0 Dim suma As Long = 0 Dim letra As String For i = 0 To pass.Length - 1 letra = Mid(pass, i + 1, 1) valor = cadena.IndexOf(letra) valor += 1 suma *= 26 suma += valor Next Console.WriteLine("Password: " & pass & " - Sum: " & suma.ToString) Console.WriteLine(".......") Console.WriteLine("Good = 6030912063") Console.WriteLine("Suma = " & suma.ToString) Console.ReadKey() Console.Clear() GoTo inicio End If End Sub Function IncrementString(ByVal strString As String) As String ' ' Increments a string counter ' e.g. "a" -> "b" ' "az" -> "ba" ' "zzz" -> "aaaa" ' ' strString is the string to increment, assumed to be lower-case alphabetic ' Return value is the incremented string ' Dim lngLenString As Long Dim strChar As String Dim lngI As Long lngLenString = Len(strString) ' Start at far right For lngI = lngLenString To 0 Step -1 ' If we reach the far left then add an A and exit If lngI = 0 Then strString = "a" & strString Exit For End If ' Consider next character strChar = Mid(strString, lngI, 1) If strChar = "z" Then ' If we find Z then increment this to A ' and increment the character after this (in next loop iteration) strString = Left$(strString, lngI - 1) & "a" & Mid(strString, lngI + 1, lngLenString) Else ' Increment this non-Z and exit strString = Left$(strString, lngI - 1) & Chr(Asc(strChar) + 1) & Mid(strString, lngI + 1, lngLenString) Exit For End If Next lngI IncrementString = strString Exit Function End Function End Module
Enlaces
- Web del reto
- Jsfiddle (compilador online)