[Web] Bugs Bunny Ctf – Web 100

Web100
100

My secure system is secure even you have my code
http://52.53.151.123/web/web100.html

This one was fairly easy the first thing that showed up on the web page was a http auth which was asking for a password my first thought was to bruteforce the password but first I checked up the website executing the command curl with bash:

curl 'http://52.53.151.123/web/web100.html'

And then showed up some javascript code:

var generate = function(string) {

    function RT(lValue, iShiftBits) {
        return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
    }

    function AU(lX, lY) {
        var lX4, lY4, lX8, lY8, lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
        if (lX4 & lY4) {
            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        }
        if (lX4 | lY4) {
            if (lResult & 0x40000000) {
                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            } else {
                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
            }
        } else {
            return (lResult ^ lX8 ^ lY8);
        }
    }
    function F(x, y, z) { return (x & y) | ((~x) & z); }
    function G(x, y, z) { return (x & z) | (y & (~z)); }
    function H(x, y, z) { return (x ^ y ^ z); }
    function I(x, y, z) { return (y ^ (x | (~z))); }

    function FF(a, b, c, d, x, s, ac) {
        a = AU(a, AU(AU(F(b, c, d), x), ac));
        return AU(RT(a, s), b);
    };

    function GG(a, b, c, d, x, s, ac) {
        a = AU(a, AU(AU(G(b, c, d), x), ac));
        return AU(RT(a, s), b);
    };

    function HH(a, b, c, d, x, s, ac) {
        a = AU(a, AU(AU(H(b, c, d), x), ac));
        return AU(RT(a, s), b);
    };

    function II(a, b, c, d, x, s, ac) {
        a = AU(a, AU(AU(I(b, c, d), x), ac));
        return AU(RT(a, s), b);
    };

    function CTWA(bytes) {
        var lWordCount;
        var lMessageLength = bytes.length;
        var lNumberOfWords_temp1 = lMessageLength + 8;
        var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
        var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
        var lWordArray = Array(lNumberOfWords - 1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while (lByteCount < lMessageLength) {
            lWordCount = (lByteCount - (lByteCount % 4)) / 4;
            lBytePosition = (lByteCount % 4) * 8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | (bytes[lByteCount] << lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount - (lByteCount % 4)) / 4;
        lBytePosition = (lByteCount % 4) * 8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
        lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
        lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
        return lWordArray;
    };

    function WordToHex(lValue) {
        var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
        for (lCount = 0; lCount <= 3; lCount++) {
            lByte = (lValue >>> (lCount * 8)) & 255;
            WordToHexValue_temp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
        }
        return WordToHexValue;
    };

    function Utf8Encode(string) {
        string = string.replace(/\r\n/g, "\n");
        var result = Array();

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                result.push(c);
            }
            else if ((c > 127) && (c < 2048)) {
                result.push((c >> 6) | 192);
                result.push((c & 63) | 128);
            }
            else {
                result.push((c >> 12) | 224);
                result.push(((c >> 6) & 63) | 128);
                result.push((c & 63) | 128);
            }
        }
        return result;
    };

    var x = Array();
    var k, AA, BB, CC, DD, a, b, c, d;
    var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
    var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
    var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
    var S41 = 6, S42 = 10, S43 = 15, S44 = 21;

    var bytes = Utf8Encode(string);
    x = CTWA(bytes);

    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

    for (k = 0; k < x.length; k += 16) {
        AA = a; BB = b; CC = c; DD = d;
        a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
        d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
        c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
        b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
        a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
        d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
        c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
        b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
        a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
        d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
        c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
        b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
        a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
        d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
        c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
        b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
        a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
        d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
        c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
        b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
        a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
        d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
        c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
        b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
        a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
        d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
        c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
        b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
        a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
        d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
        c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
        b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
        a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
        d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
        c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
        b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
        a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
        d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
        c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
        b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
        a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
        d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
        c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
        b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
        a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
        d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
        c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
        b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
        a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
        d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
        c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
        b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
        a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
        d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
        c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
        b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
        a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
        d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
        c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
        b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
        a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
        d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
        c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
        b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
        a = AU(a, AA);
        b = AU(b, BB);
        c = AU(c, CC);
        d = AU(d, DD);
    }

    var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);

    return temp.toLowerCase();
}
__seceret = '622b010e27e3f82d0f4e2e69a3785a395767c7a39599aea7114553448239eb41cab90bfecd4a8a0881d0a8128f27c483';
var _=__=___='';
for (var i = 0; i < __seceret.length; i+=3) {
   _+=__seceret[i+0]; 
   __+=__seceret[i+1];
   ___+=__seceret[i+2];
}
var h = prompt("Please enter your passowrd");
if(generate(h[11]+h[8]+h[1]+h[0]+h[9]+h[4]+h[13]) == _ && generate(h[15]+h[10]+h[3]+h[5]+h[6]) ==__ && generate(h[16]+h[12]+h[14]+h[2]+h[7])==___){
    alert('your flag is Bugs_Bunny{'+h+'}');
}else{
    alert('I\'m sorry my son it\' not easy');
}

I’ve seen this before and realized this was almost the same challenge it happened in trend micro ctf about 1 year ago, which for coincidence did a write up for it! you can check it up here https://kinyabitch.wordpress.com/2016/07/31/ctf/.
Doing a fast analysis to the code we can see that the “generate function” is actually an known hash function which you could quickly find it by just searching it on google to identify it as md5 and find it in places like this https://gist.github.com/nduphuong/752463

__seceret = '622b010e27e3f82d0f4e2e69a3785a395767c7a39599aea7114553448239eb41cab90bfecd4a8a0881d0a8128f27c483';
var _=__=___='';
for (var i = 0; i < __seceret.length; i+=3) {
   _+=__seceret[i+0]; 
   __+=__seceret[i+1];
   ___+=__seceret[i+2];
}
var h = prompt("Please enter your passowrd");
if(generate(h[11]+h[8]+h[1]+h[0]+h[9]+h[4]+h[13]) == _ && generate(h[15]+h[10]+h[3]+h[5]+h[6]) ==__ && generate(h[16]+h[12]+h[14]+h[2]+h[7])==___){
    alert('your flag is Bugs_Bunny{'+h+'}');
}else{
    alert('I\'m sorry my son it\' not easy');
}
Now analysing the rest of the code we can see that variable __seceret is splited  into 3 variables "_", "__" and "___". If you ran this code on your browser you could easily find the values of these 3 variables instead of doing the calculations:
_ = 6b07fd4ea837c39e1542e1bbca01a224 
__ = 20ee80e63596799a1543bc9fd88d8878 
___ = 21232f297a57a5a743894a0e4a801fc3

This are obviously md5 hashes now cracking them(john the ripper, hashcat or even searching the hashes on google) will get:

6b07fd4ea837c39e1542e1bbca01a224 -> tunisia
20ee80e63596799a1543bc9fd88d8878 -> bunny
21232f297a57a5a743894a0e4a801fc3 -> admin
if(generate(h[11]+h[8]+h[1]+h[0]+h[9]+h[4]+h[13]) == _ && generate(h[15]+h[10]+h[3]+h[5]+h[6]) ==__ && generate(h[16]+h[12]+h[14]+h[2]+h[7])==___){
    alert('your flag is Bugs_Bunny{'+h+'}');
}else{
    alert('I\'m sorry my son it\' not easy');
}

Analysing the password verification we can see that the that instruction to be true we will need those strings concatenation be our cracked hashes:

h[11]+h[8]+h[1]+h[0]+h[9]+h[4]+h[13] = 't'+'u'+'n'+'i'+'s'+'i'+'a';
h[15]+h[10]+h[3]+h[5]+h[6] = 'b'+'u'+'n'+'n'+'y';
h[16]+h[12]+h[14]+h[2]+h[7] = 'a'+'d'+'m'+'i'+'n';

Now reordering the string from the index 0 to 16 we get “inininynusutdamba”. We can conclude that is the password to be entered into the prompt, after submitting it the flag showed up at the webpage.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s