Hack This Site - Javascript

Hack This Site - Javascript cover image

Category: CTF

Posted at: Jan 28, 2024

7 Minutes Read

We will walk through HackThisSite's JavaScript challenges and try to solve them. Spoiler alert, they are easy and fun. LET'S DO THIS!

Idiot Test

So, there's this button that screams "Click me!" It calls a function named "check"

<button onclick="javascript:check(document.getElementById('pass').value)">Check Password</button


I peeked into the source code and found the function:

function check(x) {
  if (x == "cookies") {
    alert("win!");
    window.location += "?lvl_password=" + x;
  } else {
    alert("Fail D:");
  }
}

Easy-peasy, just type in "cookies" and bam! 🍪

Disable Javascript

Next up, it says "Disable JavaScript and click the link." Simple! JavaScript off, link clicked! ✅

Math time!

Got hit with some math equations

var foo = 5 + 6 * 7;
var bar = foo % 8;
var moo = bar * 2;
var rar = moo / 3;
function check(x) {
  if (x.length == moo) {
    alert("win!");
    window.location += "?lvl_password=" + x;
  } else {
    alert("fail D:");
  }
}

I crunched those numbers and found out I needed a password with a length of 14:

(6*7) + 5 = 47

47 mod 8 = 7

7 * 2 = 14


So just type anything with a length of 14 characters or numbers.

var?

They threw some JavaScript lingo at me, checking if my input matched the variable "RawrRawr" that holds the string "moo”

RawrRawr = "moo";
function check(x) {
  "+RawrRawr+" == "hack_this_site";
  if (x == "" + RawrRawr + "") {
    alert("Rawr! win!");
    window.location = "../../../missions/javascript/4/?lvl_password=" + x;
  } else {
    alert("Rawr, nope, try again!");
  }
}

Escape!

The 'unescape' function simply decodes the URL string, resulting in 'ilovemoo' 🐄❤️.

moo = unescape("%69%6C%6F%76%65%6D%6F%6F");
function check(x) {
  if (x == moo) {
    alert("Ahh.. so that's what she means");
    window.location = "../../../missions/javascript/5/?lvl_password=" + x;
  } else {
    alert("Nope... try again!");
  }
}

go go away .js

In this challenge the script was in an external file:

dairycow = "moo";
moo = "pwns";
rawr = "moo";


function checkpass(pass) {
  if (pass == rawr + " " + moo) {
    alert("How did you do that??? Good job!");
    window.location = "../../../missions/javascript/6/?lvl_password=" + pass;
  } else {
    alert("Nope, try again");
  }
}

As you can notice the password is a concatenation of the two variables rawr+" "+moo = moo pwns

JS Obfuscation. FTW!

This time the script was obfuscated

var _0x4e9d=["\\x66\\x72\\x6F\\x6D\\x43\\x68\\x61\\x72\\x43\\x6F\\x64\\x65","\\x77\\x72\\x69\\x74\\x65"];document[_0x4e9d[0x1]](String[_0x4e9d[0x0]](0x3c,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x6f,0x6e,0x63,0x6c,0x69,0x63,0x6b,0x3d,0x27,0x6a,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x3a,0x69,0x66,0x20,0x28,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x70,0x61,0x73,0x73,0x22,0x29,0x2e,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x22,0x6a,0x30,0x30,0x77,0x31,0x6e,0x22,0x29,0x7b,0x61,0x6c,0x65,0x72,0x74,0x28,0x22,0x59,0x6f,0x75,0x20,0x57,0x49,0x4e,0x21,0x22,0x29,0x3b,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x2b,0x3d,0x20,0x22,0x3f,0x6c,0x76,0x6c,0x5f,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x3d,0x22,0x2b,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x70,0x61,0x73,0x73,0x22,0x29,0x2e,0x76,0x61,0x6c,0x75,0x65,0x7d,0x65,0x6c,0x73,0x65,0x20,0x7b,0x61,0x6c,0x65,0x72,0x74,0x28,0x22,0x57,0x52,0x4f,0x4e,0x47,0x21,0x20,0x54,0x72,0x79,0x20,0x61,0x67,0x61,0x69,0x6e,0x21,0x22,0x29,0x7d,0x27,0x3e,0x43,0x68,0x65,0x63,0x6b,0x20,0x50,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x3c,0x2f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3e));

JavaScript obfuscation transforms easy-to-read code into another form that is more complex and harder to understand and reverse engineer


I used an online Deobfuscator and got this:

document.write(String.fromCharCode(60, 98, 117, 116, 116, 111, 110, 32, 111, 110, 99, 108, 105, 99, 107, 61, 39, 106, 97, 118, 97, 115, 99, 114, 105, 112, 116, 58, 105, 102, 32, 40, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 66, 121, 73, 100, 40, 34, 112, 97, 115, 115, 34, 41, 46, 118, 97, 108, 117, 101, 61, 61, 34, 106, 48, 48, 119, 49, 110, 34, 41, 123, 97, 108, 101, 114, 116, 40, 34, 89, 111, 117, 32, 87, 73, 78, 33, 34, 41, 59, 119, 105, 110, 100, 111, 119, 46, 108, 111, 99, 97, 116, 105, 111, 110, 32, 43, 61, 32, 34, 63, 108, 118, 108, 95, 112, 97, 115, 115, 119, 111, 114, 100, 61, 34, 43, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 66, 121, 73, 100, 40, 34, 112, 97, 115, 115, 34, 41, 46, 118, 97, 108, 117, 101, 125, 101, 108, 115, 101, 32, 123, 97, 108, 101, 114, 116, 40, 34, 87, 82, 79, 78, 71, 33, 32, 84, 114, 121, 32, 97, 103, 97, 105, 110, 33, 34, 41, 125, 39, 62, 67, 104, 101, 99, 107, 32, 80, 97, 115, 115, 119, 111, 114, 100, 60, 47, 98, 117, 116, 116, 111, 110, 62));


As you can see we have UTF-16 codes as parameter to the function fromCharCode() which is simply returns a string created from the specified sequence of UTF-16 code units:

`<button onclick='javascript:if (document.getElementById("pass").value=="j00w1n"){alert("You WIN!");window.location += "?lvl_password="+document.getElementById("pass").value}else {alert("WRONG! Try again!")}'>Check Password</button>`


Simple right?