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

Assembly

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

Flag

picoCTF{a2843c6ba4157dc1bc052818a6242c3f}

Last updated