<

Capture the flag javascript challenges 1 to 4

I’ve been playing more of the challenges on the ringzer0 website, but this time looking at the javascript challenges. Here is how I solved the first 4 challenges.

https://ringzer0ctf.com/challenges

Challenge 1 - Client side validation is so secure?

I checked the script on the page and noticed the following:

$(".c_submit").click(function(event) {
            event.preventDefault()
            var u = $("#cuser").val();
            var p = $("#cpass").val();
            if(u == "admin" && p == String.fromCharCode(74,97,118,97,83,99,114,105,112,116,73,115,83,101,99,117,114,101)) {
                if(document.location.href.indexOf("?p=") == -1) {   
                    document.location = document.location.href + "?p=" + p;
                }
            } else {
                $("#cresponse").html("<div class='alert alert-danger'>Wrong password sorry.</div>");
            }
        });

So I ran the suspicious password check in the console

String.fromCharCode(74,97,118,97,83,99,114,105,112,116,73,115,83,101,99,117,114,101)

Which returned JavaScriptIsSecure

So I logged in with user admin and password JavaScriptIsSecure

Challenge 2 - Is hashing more secure?

I checked the script again on the page

$(".c_submit").click(function(event) {
    event.preventDefault();
    var p = $("#cpass").val();
    if(Sha1.hash(p) == "b89356ff6151527e89c4f3e3d30c8e6586c63962") {
        if(document.location.href.indexOf("?p=") == -1) {   
            document.location = document.location.href + "?p=" + p;
        }
    } else {
        $("#cresponse").html("<div class='alert alert-danger'>Wrong password sorry.</div>");
    }
});		

I copied the sha1 hash, and used an online service to reverse lookup the hash

https://md5hashing.net/hash/sha1/b89356ff6151527e89c4f3e3d30c8e6586c63962

The captcha made me find cats!!

anyway, the hash matches adminz, so I logged in using the password adminz

Challenge 3 - Then obfuscation is more secure?

Again I found the script embedded on the page

var _0xc360=["\x76\x61\x6C","\x23\x63\x70\x61\x73\x73","\x61\x6C\x6B\x33","\x30\x32\x6C\x31","\x3F\x70\x3D","\x69\x6E\x64\x65\x78\x4F\x66","\x68\x72\x65\x66","\x6C\x6F\x63\x61\x74\x69\x6F\x6E","\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x27\x65\x72\x72\x6F\x72\x27\x3E\x57\x72\x6F\x6E\x67\x20\x70\x61\x73\x73\x77\x6F\x72\x64\x20\x73\x6F\x72\x72\x79\x2E\x3C\x2F\x64\x69\x76\x3E","\x68\x74\x6D\x6C","\x23\x63\x72\x65\x73\x70\x6F\x6E\x73\x65","\x63\x6C\x69\x63\x6B","\x2E\x63\x5F\x73\x75\x62\x6D\x69\x74"];$(_0xc360[12])[_0xc360[11]](function (){var _0xf382x1=$(_0xc360[1])[_0xc360[0]]();var _0xf382x2=_0xc360[2];if(_0xf382x1==_0xc360[3]+_0xf382x2){if(document[_0xc360[7]][_0xc360[6]][_0xc360[5]](_0xc360[4])==-1){document[_0xc360[7]]=document[_0xc360[7]][_0xc360[6]]+_0xc360[4]+_0xf382x1;} ;} else {$(_0xc360[10])[_0xc360[9]](_0xc360[8]);} ;} );

I haven’t seen anything like this before, but I googled javascript unofuscate and found a nice tool to deobfuscate the javascript

http://jsnice.org/

So now I have this, which isn’t as bad

'use strict';
/** @type {!Array} */
var _0xc360 = ["val", "#cpass", "alk3", "02l1", "?p=", "indexOf", "href", "location", "<div class='error'>Wrong password sorry.</div>", "html", "#cresponse", "click", ".c_submit"];
$(_0xc360[12])[_0xc360[11]](function() {
  var _oldCopyrightNotice = $(_0xc360[1])[_0xc360[0]]();
  var _thisYear = _0xc360[2];
  if (_oldCopyrightNotice == _0xc360[3] + _thisYear) {
    if (document[_0xc360[7]][_0xc360[6]][_0xc360[5]](_0xc360[4]) == -1) {
      document[_0xc360[7]] = document[_0xc360[7]][_0xc360[6]] + _0xc360[4] + _oldCopyrightNotice;
    }
  } else {
    $(_0xc360[10])[_0xc360[9]](_0xc360[8]);
  }
});

Its still quite complex, so I tried a different tool

https://lelinhtinh.github.io/de4js/

Which outputted

$('.c_submit')['click'](function () {
    var _0xf382x1 = $('#cpass')['val']();
    var _0xf382x2 = 'alk3';
    if (_0xf382x1 == '02l1' + _0xf382x2) {
        if (document['location']['href']['indexOf']('?p=') == -1) {
            document['location'] = document['location']['href'] + '?p=' + _0xf382x1;
        };
    } else {
        $('#cresponse')['html']('<div class=\'error\'>Wrong password sorry.</div>');
    };
});

So the if statement is based on '02l1' + _0xf382x2 which is 02l1alk3

It worked!

Challenge 4 - Most Secure Crypto Algo

Again, script embedded in page


			$(".c_submit").click(function(event) {
				event.preventDefault();
				var k = CryptoJS.SHA256("\x93\x39\x02\x49\x83\x02\x82\xf3\x23\xf8\xd3\x13\x37");
				var u = $("#cuser").val();
				var p = $("#cpass").val();
				var t = true;
			
				if(u == "\x68\x34\x78\x30\x72") {
					if(!CryptoJS.AES.encrypt(p, CryptoJS.enc.Hex.parse(k.toString().substring(0,32)), { iv: CryptoJS.enc.Hex.parse(k.toString().substring(32,64)) }) == "ob1xQz5ms9hRkPTx+ZHbVg==") {
						t = false;
					}
				} else {
					$("#cresponse").html("<div class='alert alert-danger'>Wrong password sorry.</div>");
					t = false;
				}
				if(t) {
					if(document.location.href.indexOf("?p=") == -1) {
						document.location = document.location.href + "?p=" + p;
               			}
				}
			});
		

I first decoded the hex username \x68\x34\x78\x30\x72 to h4x0r

Then I resolved what k would equate to

CryptoJS.SHA256("\x93\x39\x02\x49\x83\x02\x82\xf3\x23\xf8\xd3\x13\x37")

which is

d8439507642eb76a4050adb27891d38a01fdb35ac5309d45a99f89c0a4ca0db6

the key is being used in two parts, d8439507642eb76a4050adb27891d38a for the key and 01fdb35ac5309d45a99f89c0a4ca0db6 for the initialisation vector

Since we have the value ob1xQz5ms9hRkPTx+ZHbVg== available, we can just decrypt it, by reversing the logic.

e.g.

CryptoJS.AES.encrypt(p, CryptoJS.enc.Hex.parse(k.toString().substring(0,32)), { iv: CryptoJS.enc.Hex.parse(k.toString().substring(32,64)) }) == "ob1xQz5ms9hRkPTx+ZHbVg=="

can be rewritten as

CryptoJS.AES.decrypt("ob1xQz5ms9hRkPTx+ZHbVg==", CryptoJS.enc.Hex.parse(k.toString().substring(0,32)), { iv: CryptoJS.enc.Hex.parse(k.toString().substring(32,64)) }).toString()

which is 50617373573052442132383925212a, which converted from hex to string is PassW0RD!289%!*

So I log in with h4x0r and PassW0RD!289%!*

Written on May 24, 2019.