Skip to main content

Client-side-again

  • Description: Can you break into this super secure portal?
  • Difficulty: Medium

πŸ”Ž Solution​

By viewing the page source, we can identify the following embedded script:

<script type="text/javascript">
var _0x5a46=['daf93}','_again_4','this','Password\x20Verified','Incorrect\x20password','getElementById','value','substring','picoCTF{','not_this'];(function(_0x4bd822,_0x2bd6f7){var _0xb4bdb3=function(_0x1d68f6){while(--_0x1d68f6){_0x4bd822['push'](_0x4bd822['shift']());}};_0xb4bdb3(++_0x2bd6f7);}(_0x5a46,0x1b3));var _0x4b5b=function(_0x2d8f05,_0x4b81bb){_0x2d8f05=_0x2d8f05-0x0;var _0x4d74cb=_0x5a46[_0x2d8f05];return _0x4d74cb;};function verify(){checkpass=document[_0x4b5b('0x0')]('pass')[_0x4b5b('0x1')];split=0x4;if(checkpass[_0x4b5b('0x2')](0x0,split*0x2)==_0x4b5b('0x3')){if(checkpass[_0x4b5b('0x2')](0x7,0x9)=='{n'){if(checkpass[_0x4b5b('0x2')](split*0x2,split*0x2*0x2)==_0x4b5b('0x4')){if(checkpass[_0x4b5b('0x2')](0x3,0x6)=='oCT'){if(checkpass[_0x4b5b('0x2')](split*0x3*0x2,split*0x4*0x2)==_0x4b5b('0x5')){if(checkpass['substring'](0x6,0xb)=='F{not'){if(checkpass[_0x4b5b('0x2')](split*0x2*0x2,split*0x3*0x2)==_0x4b5b('0x6')){if(checkpass[_0x4b5b('0x2')](0xc,0x10)==_0x4b5b('0x7')){alert(_0x4b5b('0x8'));}}}}}}}}else{alert(_0x4b5b('0x9'));}}
</script>

The script starts with an array _0x5a46 and an immediately invoked function expression (IIFE) that rotates/shuffles this array. After this transformation, the decoder function _0x4b5b maps hexadecimal indices to meaningful string values:

  • _0x4b5b('0x0') β†’ getElementById
  • _0x4b5b('0x1') β†’ value
  • _0x4b5b('0x2') β†’ substring
  • _0x4b5b('0x3') β†’ picoCTF{
  • _0x4b5b('0x4') β†’ not_this
  • _0x4b5b('0x5') β†’ daf93}
  • _0x4b5b('0x6') β†’ _again_4
  • _0x4b5b('0x7') β†’ this
  • _0x4b5b('0x8') β†’ Password Verified
  • _0x4b5b('0x9') β†’ Incorrect password

The verify() function retrieves the value from the input field (pass) and validates different portions of the string using split = 4 as the base unit. We can reconstruct the password by analyzing each substring check in logical order:

  • checkpass.substring(0, 8) == 'picoCTF{'
  • checkpass.substring(7, 9) == '{n'
  • checkpass.substring(8, 16) == 'not_this'
  • checkpass.substring(3, 6) == 'oCT'
  • checkpass.substring(24, 32) == 'daf93}'
  • checkpass.substring(6, 11) == 'F{not'
  • checkpass.substring(16, 24) == 'again_4'
  • checkpass.substring(12, 16) == 'this'

From the index ranges, the string can be divided into the following segments:

  • Position 0 - 8 : picoCTF{
  • Position 8 - 16 : not_this
  • Position 16 - 24 : _again_4
  • Position 24 - 32 : daf93}

By concatenating these segments according to their correct positions in the string, we obtain the complete flag.

🚩Flag​

picoCTF{not_this_again_4daf93}