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