Challenge
JS Obfuscation. FTW!
Find the password:
索引名
JS Obfuscation. FTW!,难度 moderate。密码比较逻辑藏在一个运行时由十六进制字符串数组加String.fromCharCode(...)生成出来的<button>里。要先把混淆还原出来。
Solution
$ curl -s -b "$HTS_COOKIE" \ -H "Referer: https://www.hackthissite.org/missions/javascript/7/" \ "https://www.hackthissite.org/missions/javascript/7/" -o lvl7.htmlvar _0x4e9d=["\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","\x77\x72\x69\x74\x65"];document[_0x4e9d[0x1]](String[_0x4e9d[0x0]](0x3c,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x6f,0x6e,0x63,0x6c,0x69,0x63,0x6b,0x3d,0x27,0x6a,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x3a,0x69,0x66,0x20,0x28,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x70,0x61,0x73,0x73,0x22,0x29,0x2e,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x22,0x6a,0x30,0x30,0x77,0x31,0x6e,0x22,0x29,0x7b,0x61,0x6c,0x65,0x72,0x74,0x28,0x22,0x59,0x6f,0x75,0x20,0x57,0x49,0x4e,0x21,0x22,0x29,0x3b,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x2b,0x3d,0x20,0x22,0x3f,0x6c,0x76,0x6c,0x5f,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x3d,0x22,0x2b,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x70,0x61,0x73,0x73,0x22,0x29,0x2e,0x76,0x61,0x6c,0x75,0x65,0x7d,0x65,0x6c,0x73,0x65,0x20,0x7b,0x61,0x6c,0x65,0x72,0x74,0x28,0x22,0x57,0x52,0x4f,0x4e,0x47,0x21,0x20,0x54,0x72,0x79,0x20,0x61,0x67,0x61,0x69,0x6e,0x21,0x22,0x29,0x7d,0x27,0x3e,0x43,0x68,0x65,0x63,0x6b,0x20,0x50,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x3c,0x2f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3e));#!/usr/bin/env python3"""Recover the JavaScript Mission 7 password from the obfuscated source.
The level ships two hex-string arrays and rebuilds a <button> at run time byturning a numeric char-code list into HTML:
var _0x4e9d=["\\x66\\x72\\x6F\\x6D\\x43\\x68\\x61\\x72\\x43\\x6F\\x64\\x65", "\\x77\\x72\\x69\\x74\\x65"];
Step 1 unescapes the \\xNN literals into identifier names("fromCharCode","write"); step 2 turns the numeric char-code list into thebutton HTML and reads the compared literal out of it -- the password."""import re
src = open("lvl7.html", encoding="utf-8", errors="replace").read()
# Step 1: \xNN string literals -> identifier namesarr = re.search(r"_0x4e9d=\[(.*?)\]", src, re.S).group(1)names = [bytes(b, "latin1").decode("unicode_escape") for b in re.findall(r'"((?:\\x[0-9a-fA-F]{2})+)"', arr)]print("identifiers:", names)
# Step 2: rebuild the button HTML from the String.fromCharCode() code listcall = re.search(r"String\[_0x4e9d\[0x0\]\]\(([^)]*)\)", src, re.S).group(1)codes = [int(x, 16) for x in re.findall(r"0x([0-9a-fA-F]+)", call)]button = "".join(chr(c) for c in codes)print("button HTML:")print(button)
# Step 3: the compared literal inside the button is the passwordpassword = re.search(r'value=="([^"]+)"', button).group(1)print("password:", password)$ uv run python decode7.pyidentifiers: ['fromCharCode', 'write']button HTML:<button onclick='javascript:if (document.getElementById("pass").value=="j00w1n"){alert("You WIN!");window.location += "?lvl_password="+document.getElementById("pass").value}else {alert("WRONG! Try again!")}'>Check Password</button>password: j00w1nj00w1n