El level 2 sigue estando entre los clasificados como muy fáciles.
https://ikasten.io/ee32/hackit/level2/level2.html
Igual que en el level anterior, analizamos qué operaciones se llevan a cabo para comprobar que el password introducido es correcto (al final se compara con un string concreto: umcjqhmdohdzchm)
$(document).ready(function(){$("#password").keyup(function(o){
r=$("#password").val();function num(s){x=s+'';y=x.charCodeAt(0);if(0xD800<=y&&y<=0xDBFF){q = y;if(x.length === 1){return y;}z=x.charCodeAt(1);return ((q - 0xD800)*0x400)+(z - 0xDC00)+0x10000;}if(0xDC00<=y&&y<=0xDFFF){return y;}return y;}
d="txhupnqbgvzyjvfbadnzkmytwdauwpeeojiowkzrmrnxlxcsskbjtrifhlomldsivceyqggphcfqua";c=0;o="";for(var i=0;i<r.length;i++){c=(num(r.charAt(i))+c)%78;o+=d.charAt(c);}
$("#password").css({"background-color":o == "umcjqhmdohdzchm"?"#8f8":"#f88"});
});});
y revertimos el proceso:
def num(s):
x = s + ''
y = ord(x[0])
if 0xD800 <= y <= 0xDBFF:
q = y
if len(x) == 1:
return y
z = ord(x[1])
return ((q - 0xD800) * 0x400) + (z - 0xDC00) + 0x10000
if 0xDC00 <= y <= 0xDFFF:
return y
return y
d = "txhupnqbgvzyjvfbadnzkmytwdauwpeeojiowkzrmrnxlxcsskbjtrifhlomldsivceyqggphcfqua"
target = "umcjqhmdohdzchm"
c = 0
password = []
for char in target:
target_index = d.index(char)
for potential_char in range(32, 127): # ASCII printable range
temp_c = (num(chr(potential_char)) + c) % 78
if temp_c == target_index:
password.append(chr(potential_char))
c = temp_c
break
password = ''.join(password)
print("The password is:", password)
Curiosamente, aquí pedimos que se revisara la prueba, porque obteníamos claves válidas (esta prueba mostraba el input text de la página en verde cuando introducías una clave que pasaba las validaciones correctamente) que el servidor no aceptaba al enviarla. Desde la org nos atendieron enseguida y modificaron el level para que diera por buena cualquier clave que pasara correctamente las validaciones.