http://mercury.picoctf.net:1896/index.html
The challenge gives us a link which opens a webpage that allows us to guess the flag and check whether it is correct. Seeing nothing of interest there we check the source and see an obfuscated javascript file called 'G82XCw5CX3.js'. Seeing as the javascript is horribly obfuscated we can try to make it more readable using a website such as jsnice.org. Here is the resulting slightly less obfuscated javascript code:
'use strict';
const _0x402c = ["value", "2wfTpTR", "instantiate", "275341bEPcme", "innerHTML", "1195047NznhZg", "1qfevql", "input", "1699808QuoWhA", "Correct!", "check_flag", "Incorrect!", "./JIFxzHyW8W", "23SMpAuA", "802698XOMSrr", "charCodeAt", "474547vVoGDO", "getElementById", "instance", "copy_char", "43591XxcWUl", "504454llVtzW", "arrayBuffer", "2NIQmVj", "result"];
const _0x4e0e = function(url, whensCollection) {
/** @type {number} */
url = url - 470;
let _0x402c6f = _0x402c[url];
return _0x402c6f;
};
(function(data, oldPassword) {
const toMonths = _0x4e0e;
for (; !![];) {
try {
const userPsd = -parseInt(toMonths(491)) + parseInt(toMonths(493)) + -parseInt(toMonths(475)) * -parseInt(toMonths(473)) + -parseInt(toMonths(482)) * -parseInt(toMonths(483)) + -parseInt(toMonths(478)) * parseInt(toMonths(480)) + parseInt(toMonths(472)) * parseInt(toMonths(490)) + -parseInt(toMonths(485));
if (userPsd === oldPassword) {
break;
} else {
data["push"](data["shift"]());
}
} catch (_0x41d31a) {
data["push"](data["shift"]());
}
}
})(_0x402c, 627907);
let exports;
(async() => {
const findMiddlePosition = _0x4e0e;
let leftBranch = await fetch(findMiddlePosition(489));
let rightBranch = await WebAssembly[findMiddlePosition(479)](await leftBranch[findMiddlePosition(474)]());
let module = rightBranch[findMiddlePosition(470)];
exports = module["exports"];
})();
/**
* @return {undefined}
*/
function onButtonPress() {
const navigatePop = _0x4e0e;
let params = document["getElementById"](navigatePop(484))[navigatePop(477)];
for (let i = 0; i < params["length"]; i++) {
exports[navigatePop(471)](params[navigatePop(492)](i), i);
}
exports["copy_char"](0, params["length"]);
if (exports[navigatePop(487)]() == 1) {
document[navigatePop(494)](navigatePop(476))[navigatePop(481)] = navigatePop(486);
} else {
document[navigatePop(494)](navigatePop(476))[navigatePop(481)] = navigatePop(488);
}
}
;
The "let leftBranch = await fetch(findMiddlePosition(489));" line of code looks interesting so we try to figure out what it does. The "findMiddlePosition()" function will simply subtract 470 from the number passed to it and use the result of the subtraction to get a string from the initially declared array. In this case it gets the string "./JIFxzHyW8W" and runs fetch() on it. Heading to http://mercury.picoctf.net:1896/JIFxzHyW8W to see what file that fetch() call could be dealing with. As a result we download a file called "JIFxzHyW8W". Simply printing out its contents will get us the flag.
zerodaytea@Patryk:/mnt/d/Coding/CTFs/PicoCTF2021/WebExploitation$ strings JIFxzHyW8W
memory
__wasm_call_ctors
strcmp
check_flag
input
copy_char
__dso_handle
__data_end
__global_base
__heap_base
__memory_base
__table_base
j!
F!!A
!" ! "q!# #
!% $ %q!&
!( ' (q!) & )k!*
!+ +
q!
+picoCTF{a2843c6ba4157dc1bc052818a6242c3f}
picoCTF{a2843c6ba4157dc1bc052818a6242c3f}