Some Assembly Required 1
Point: 70
Category
Web Exploitation
Question
http://mercury.picoctf.net:1896/index.html
Hint
None
Solution
Looking at the website, I could see a text box and submit button. I tried to submit random stuff but I got incorrect. Thus, I tried to look at the source code, then I got a js file but it's already obfuscated -> I tried to deobfuscate it by using the only tool as you can see in the result below.
'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) {
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('./JIFxzHyW8W'));
let rightBranch = await WebAssembly[findMiddlePosition('instantiate')](
await leftBranch[findMiddlePosition('arrayBuffer')]()
);
let module = rightBranch[findMiddlePosition('instance')];
exports = module['exports'];
})();
function onButtonPress() {
const navigatePop = _0x4e0e; // undefined
let params = document['getElementById'](navigatePop('input'))[
navigatePop('value')
];
for (let i = 0; i < params['length']; i++) {
exports[navigatePop('copy_char')](params[navigatePop('charCodeAt')](i), i);
}
exports['copy_char'](0, params['length']);
if (exports[navigatePop('check_flag')]() == 1) {
document[navigatePop('getElementById')](navigatePop('result'))[
navigatePop('innerHTML')
] = navigatePop('Correct!');
} else {
document[navigatePop('getElementById')](navigatePop('result'))[
navigatePop('innerHTML')
] = navigatePop('Incorrect!');
}
}
Basically, It's web assembly code so I used the dev tool to translate it. You can do like this
const findMiddlePosition = _0x4e0e;
undefined;
findMiddlePosition(484);
('input');
findMiddlePosition(492);
('charCodeAt');
findMiddlePosition(471);
('copy_char');

After analyzing the code, basically, the text box takes each character of the user's flag and then submits it to WebAssembly using copy_char
then calls check_flag
to see if the flag is correct. From here, I thought I have to dive deep into WebAssembly to get the flag. From
From the JS code above, I could see let leftBranch = await fetch(findMiddlePosition('./JIFxzHyW8W'));
-> I tried to get the WebAssembly code from mercury.picoctf.net:1896/JIFxzHyW8W
then open it as a text file in vscode -> got the flag

Flag
picoCTF{a2843c6ba4157dc1bc052818a6242c3f}
Last updated