1

This crackme contains a text input element on the screen and a button to validate

The value you enter is set into _inputValue, afterwards you click on a button, the function executes, in the last lines, if selectedOption is 2 it will print "Congratz" otherwise there are 5 bad options in the optionsArr.

after unpacking and cleaning the main function is :

Password: <input/><br/>
<button>Check</button>
<script id="urchin">
    (function () {
        var optionsArr = [
            function () {
                console.warn("boo")
            },
            function () {
                console.warn(":(")
            },
            function () {
                console.log("Congratz!")
            },
            function () {
                console.warn("allmost there")
            },
            function () {
                console.warn("muhaha")
            },
            function () {
                console.warn("nahhh")
            },
            function () {
                console.warn("not even close")
            }
        ];
        var mainFunction = function () {
            var arr = [];
            for (var i = 0; i < 256; i++) {
                arr[i] = i;
            }
            var inputVal = document.getElementsByTagName('input')[0].value;
            var varX = 0;
//            for (var i2 = 0; i2 < 256; i2++) {
//                var secret = 'click';
//                varX = (varX + arr[i2] + secret.charCodeAt(i2 % 5)) % 256;
//                arr[i2] ^= arr[varX];
//                arr[varX] ^= arr[i2];
//                arr[i2] ^= arr[varX];
//            }
            arr = [99, 116, 115, 37, 16, 120, 211, 90, 197, 22, 166, 63, 146, 59, 123, 237, 93, 44, 76, 118, 168, 91, 55, 187, 62, 220, 135, 49, 127, 185, 153, 8, 66, 155, 152, 181, 117, 149, 31, 87, 169, 6, 172, 34, 101, 134, 107, 157, 199, 231, 124, 2, 243, 35, 241, 139, 68, 3, 159, 86, 77, 225, 105, 29, 144, 19, 32, 42, 227, 147, 133, 15, 160, 73, 190, 148, 82, 97, 170, 201, 212, 14, 18, 13, 193, 121, 143, 141, 182, 122, 21, 108, 112, 111, 217, 60, 250, 27, 137, 244, 191, 38, 171, 214, 248, 132, 228, 43, 232, 213, 223, 129, 28, 64, 247, 205, 138, 95, 202, 235, 61, 119, 224, 88, 238, 206, 230, 94, 195, 5, 179, 54, 72, 92, 136, 98, 188, 200, 173, 226, 198, 4, 71, 196, 126, 9, 69, 110, 84, 48, 85, 210, 30, 180, 229, 216, 162, 56, 75, 0, 67, 253, 163, 167, 53, 26, 7, 12, 174, 57, 130, 194, 209, 165, 1, 140, 183, 70, 23, 89, 150, 25, 145, 104, 233, 74, 142, 151, 222, 65, 207, 96, 154, 218, 106, 131, 255, 109, 254, 33, 113, 164, 203, 40, 246, 83, 192, 236, 189, 78, 158, 234, 177, 175, 161, 251, 100, 221, 219, 103, 50, 41, 242, 10, 249, 240, 20, 184, 24, 80, 52, 51, 81, 11, 156, 245, 114, 239, 186, 125, 17, 204, 128, 47, 36, 39, 215, 208, 46, 176, 178, 58, 45, 102, 252, 79];
            var idx = varX = 0;
            var cmpStr = '';
            for (var i3 = idx; i3 < inputVal.length; i3 += 2) {
                idx = (idx + 1) % 256;
                varX = (varX + arr[idx]) % 256;
                arr[idx] ^= arr[varX];
                arr[varX] ^= arr[idx];
                arr[idx] ^= arr[varX];
                var curHex = inputVal.substr(i3, 2);
                var hex2int = parseInt(curHex, 16);
                var charCode = hex2int ^ arr[(arr[idx] + arr[varX]) % 256];
                cmpStr += String.fromCharCode(charCode);
            }
            var selectedOption = cmpStr.charCodeAt(cmpStr.charCodeAt(0) % cmpStr.length) % 6;

            if (cmpStr != 'input128' && selectedOption == 2) selectedOption++;
            optionsArr[selectedOption]();
        };
        var btn = document.getElementsByTagName('button')[0];
        if (typeof(btn.addEventListener) != typeof(mainFunction)) {
            btn.attachEvent('onclick', mainFunction);
        } else {
            btn.addEventListener('click', mainFunction, true);
        }
        btn = document.getElementById('urchin');
        btn.parentNode.removeChild(btn);
    })();
</script>

I understand my input after decrypt needs to be "input128", how can I reverse the process to encrypt "input128" ?

  • BTW, It's using rc4 encryption
3

To extend on EWD-0- about the reversibility of RC4 here's how I tried it:

From your actual code and reversing it a little to get "input128" encoded:

arr = [99, 116, 115, 37, 16, 120, 211, 90, 197, 22, 166, 63, 146, 59, 123, 237, 93, 44, 76, 118, 168, 91, 55, 187, 62, 220, 135, 49, 127, 185, 153, 8, 66, 155, 152, 181, 117, 149, 31, 87, 169, 6, 172, 34, 101, 134, 107, 157, 199, 231, 124, 2, 243, 35, 241, 139, 68, 3, 159, 86, 77, 225, 105, 29, 144, 19, 32, 42, 227, 147, 133, 15, 160, 73, 190, 148, 82, 97, 170, 201, 212, 14, 18, 13, 193, 121, 143, 141, 182, 122, 21, 108, 112, 111, 217, 60, 250, 27, 137, 244, 191, 38, 171, 214, 248, 132, 228, 43, 232, 213, 223, 129, 28, 64, 247, 205, 138, 95, 202, 235, 61, 119, 224, 88, 238, 206, 230, 94, 195, 5, 179, 54, 72, 92, 136, 98, 188, 200, 173, 226, 198, 4, 71, 196, 126, 9, 69, 110, 84, 48, 85, 210, 30, 180, 229, 216, 162, 56, 75, 0, 67, 253, 163, 167, 53, 26, 7, 12, 174, 57, 130, 194, 209, 165, 1, 140, 183, 70, 23, 89, 150, 25, 145, 104, 233, 74, 142, 151, 222, 65, 207, 96, 154, 218, 106, 131, 255, 109, 254, 33, 113, 164, 203, 40, 246, 83, 192, 236, 189, 78, 158, 234, 177, 175, 161, 251, 100, 221, 219, 103, 50, 41, 242, 10, 249, 240, 20, 184, 24, 80, 52, 51, 81, 11, 156, 245, 114, 239, 186, 125, 17, 204, 128, 47, 36, 39, 215, 208, 46, 176, 178, 58, 45, 102, 252, 79];
var idx = varX = 0;
var cmpStr = '';
for (var i3 = idx; i3 < 'input128'.length; i3 += 1) {
  idx = (idx + 1) % 256;
  varX = (varX + arr[idx]) % 256;
  arr[idx] ^= arr[varX];
  arr[varX] ^= arr[idx];
  arr[idx] ^= arr[varX];

  var hex2int = 'input128'.charCodeAt(i3);
  var charCode = hex2int ^ arr[(arr[idx] + arr[varX]) % 256];

  cmpStr += charCode.toString(16)+" ";
}
console.log(cmpStr);

Main difference in the loop is running by step of 1 by char, and taking each character code to xor with the corresponding key value. It is then encoded in hex as your original code does read hex values (the loop run by step of 2) to get character code (curHex then hex2int).

This give me: 95 69 18 b1 82 8 c1 59

You just have to add a 0 to the 6th entry and remove the spaces to fill inputValue and you'll get back 'input128' in cmpStr.

1

RC4 is a Symmetric Key algorithm. So give "input128" as your input. Then debug the code to see what it generates after applying the algorithm on "input128". That would be the original input you have to gave.

Symmetric Key Algorithms:

plaintext + key = ciphertext

ciphertext + key = plaintext

  • A little more complex than that imho, at least the input can't be given as is as it need to be entered in hexadecimal form. – Tensibai Oct 26 '17 at 16:01
  • (sounds promising anyway, but I should be failing my reversal program on the numbers part) – Tensibai Oct 26 '17 at 16:23
  • I don't understand – Jim West Oct 26 '17 at 21:40
  • I do understand symmetric key, I have the secret + key I can xor them to decrypt.. what about the hex part ? – Jim West Oct 26 '17 at 21:57
  • @IddoE check the actual code, it takes input 2 chars by 2 chars as hex value which are then converted to integer and then xored with the corresponding key character code. It's just an extra obfuscation part. – Tensibai Oct 27 '17 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.