Skip to content

Latest commit

 

History

History
135 lines (131 loc) · 5.33 KB

File metadata and controls

135 lines (131 loc) · 5.33 KB

Some Assembly Required 2

Category - Web Exploitation

Author - SEARS SCHULZ

Description:

http://mercury.picoctf.net:15406/index.html

Solution:

The challenge gives us a link which opens a webpage allowing us check our flag, exactly the same as the first part of the challenge. Following the steps of the last challenge we find the objuscated javascript file "Y8splx37qY.js":

const _0x6d8f = ['copy_char', 'value', '207aLjBod', '1301420SaUSqf', '233ZRpipt', '2224QffgXU', 'check_flag', '408533hsoVYx', 'instance', '278338GVFUrH', 'Correct!', '549933ZVjkwI', 'innerHTML', 'charCodeAt', './aD8SvhyVkb', 'result', '977AzKzwq', 'Incorrect!', 'exports', 'length', 'getElementById', '1jIrMBu', 'input', '615361geljRK'];
const _0x5c00 = function(_0x58505a, _0x4d6e6c) {
    _0x58505a = _0x58505a - 0xc3;
    let _0x6d8fc4 = _0x6d8f[_0x58505a];
    return _0x6d8fc4;
};
(function(_0x12fd07, _0x4e9d05) {
    const _0x4f7b75 = _0x5c00;
    while (!![]) {
        try {
            const _0x1bb902 = -parseInt(_0x4f7b75(0xc8)) * -parseInt(_0x4f7b75(0xc9)) + -parseInt(_0x4f7b75(0xcd)) + parseInt(_0x4f7b75(0xcf)) + parseInt(_0x4f7b75(0xc3)) + -parseInt(_0x4f7b75(0xc6)) * parseInt(_0x4f7b75(0xd4)) + parseInt(_0x4f7b75(0xcb)) + -parseInt(_0x4f7b75(0xd9)) * parseInt(_0x4f7b75(0xc7));
            if (_0x1bb902 === _0x4e9d05)
                break;
            else
                _0x12fd07['push'](_0x12fd07['shift']());
        } catch (_0x4f8a) {
            _0x12fd07['push'](_0x12fd07['shift']());
        }
    }
}(_0x6d8f, 0x4bb06));
let exports;
(async()=>{
    const _0x835967 = _0x5c00;
    let _0x1adb5f = await fetch(_0x835967(0xd2))
      , _0x355961 = await WebAssembly['instantiate'](await _0x1adb5f['arrayBuffer']())
      , _0x5c0ffa = _0x355961[_0x835967(0xcc)];
    exports = _0x5c0ffa[_0x835967(0xd6)];
}
)();
function onButtonPress() {
    const _0x50ea62 = _0x5c00;
    let _0x5f4170 = document[_0x50ea62(0xd8)](_0x50ea62(0xda))[_0x50ea62(0xc5)];
    for (let _0x19d3ca = 0x0; _0x19d3ca < _0x5f4170['length']; _0x19d3ca++) {
        exports[_0x50ea62(0xc4)](_0x5f4170[_0x50ea62(0xd1)](_0x19d3ca), _0x19d3ca);
    }
    exports['copy_char'](0x0, _0x5f4170[_0x50ea62(0xd7)]),
    exports[_0x50ea62(0xca)]() == 0x1 ? document['getElementById'](_0x50ea62(0xd3))[_0x50ea62(0xd0)] = _0x50ea62(0xce) : document[_0x50ea62(0xd8)](_0x50ea62(0xd3))['innerHTML'] = _0x50ea62(0xd5);
}

Deobfuscating this with jsnice.org we get:

'use strict';
const _0x6d8f = ["copy_char", "value", "207aLjBod", "1301420SaUSqf", "233ZRpipt", "2224QffgXU", "check_flag", "408533hsoVYx", "instance", "278338GVFUrH", "Correct!", "549933ZVjkwI", "innerHTML", "charCodeAt", "./aD8SvhyVkb", "result", "977AzKzwq", "Incorrect!", "exports", "length", "getElementById", "1jIrMBu", "input", "615361geljRK"];
const _0x5c00 = function(url, whensCollection) {
  /** @type {number} */
  url = url - 195;
  let _0x6d8fc4 = _0x6d8f[url];
  return _0x6d8fc4;
};
(function(data, oldPassword) {
  const toMonths = _0x5c00;
  for (; !![];) {
    try {
      const userPsd = -parseInt(toMonths(200)) * -parseInt(toMonths(201)) + -parseInt(toMonths(205)) + parseInt(toMonths(207)) + parseInt(toMonths(195)) + -parseInt(toMonths(198)) * parseInt(toMonths(212)) + parseInt(toMonths(203)) + -parseInt(toMonths(217)) * parseInt(toMonths(199));
      if (userPsd === oldPassword) {
        break;
      } else {
        data["push"](data["shift"]());
      }
    } catch (_0x4f8a) {
      data["push"](data["shift"]());
    }
  }
})(_0x6d8f, 310022);
let exports;
(async() => {
  const edgeId = _0x5c00;
  let _0x1adb5f = await fetch(edgeId(210));
  let rpm_traffic = await WebAssembly["instantiate"](await _0x1adb5f["arrayBuffer"]());
  let updatedEdgesById = rpm_traffic[edgeId(204)];
  exports = updatedEdgesById[edgeId(214)];
})();
/**
 * @return {undefined}
 */
function onButtonPress() {
  const navigatePop = _0x5c00;
  let params = document[navigatePop(216)](navigatePop(218))[navigatePop(197)];
  for (let i = 0; i < params["length"]; i++) {
    exports[navigatePop(196)](params[navigatePop(209)](i), i);
  }
  exports["copy_char"](0, params[navigatePop(215)]);
  if (exports[navigatePop(202)]() == 1) {
    document["getElementById"](navigatePop(211))[navigatePop(208)] = navigatePop(206);
  } else {
    document[navigatePop(216)](navigatePop(211))["innerHTML"] = navigatePop(213);
  }
}
;

This appears to be the exact same as the last challenge so we head to http://mercury.picoctf.net:15406/aD8SvhyVkb to download our file. Running strings on it we see what appears to be some encoded text where the flag was last time:

zerodaytea@Patryk:/mnt/d/Coding/CTFs/PicoCTF2021/WebExploitation$ strings aD8SvhyVkb
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!
+xakgK\Nsmn;j8j<9;<?=l?k88mm1n9i1j>:8k?l0u

After trying some various encoding methods I come across XOR and see that this string was just the flag XORed with the byte 0x08. Using CyberChef with the XOR Bruteforce recipe and "xakgK\Nsmn;j8j<9;<?=l?k88mm1n9i1j>:8k?l0u" as the input will give the flag: https://gchq.github.io/CyberChef/#recipe=XOR_Brute_Force(1,100,0,'Standard',false,true,false,'')&input=eGFrZ0tcTnNtbjtqOGo8OTs8Pz1sP2s4OG1tMW45aTFqPjo4az9sMHU

Flag:

picoCTF{ef3b0b413475d7c00ee9f1a9b620c7d8}