Search code examples
javascriptencryptionbitwise-operatorsbitwise-xorblock-cipher

Cracking a Bitwise cipher


    var reverse_flag = [-63, -105, -103, -121, -95, -73, -39, -101, -83, -29, -125, -121, -95, -73, -225, -203, -213, -223, -213, -119];
    function check_flag()
    {
        var i, flag = document.getElementById('flag').value;
        if(flag.length != reverse_flag.length)
            return false;
        for(i=0;i<flag.length;i++)
        {
            var code = flag.charCodeAt(i);
            code = code<<1;
            code ^= 0xba;
            code = ~code;
            if(code != reverse_flag[i])
                return false;
        }
        return true;
    }

The Answer is checked via Form

    <form method="post" id="form"><input type="password" id="flag" name="flag"><input type="submit" value="Check" onclick="return check_flag()"></form>

In my Uni we have recently started this Bitwise topic, and as the first hometask we are given the cipher mentioned beforehand. I've read all the documentation there is about Javascript Bitwise but I am failing to understand what it has to do with this.

If anybody knows, how do you need to approach this question? And what books/ articles would you advise to crack such stuff?

Thank you in advance


Solution

  • The algorithm is doing the following with each letter of the given input:

    • Convert letter to charcode
    • Do a binary shift left one time
    • XOR with 0xba
    • Invert all bits
    • Compare it to the fixed array of codes

    To get the correct input, do the inverse operations in reverse order:

    • Invert all bits
    • XOR with 0xba
    • Shift right one time

    Here is an example where you can click the "Reverse Computation" button, copy the output print to the input box and use the "Check without submit" to execute the original algorithm (without executing the submit, which would trigger a navigation).

    var reverse_flag = [-63, -105, -103, -121, -95, -73, -39, -101, -83, -29, -125, -121, -95, -73, -225, -203, -213, -223, -213, -119];
    
    function check_flag()
    {
        var i, flag = document.getElementById('flag').value;
        if(flag.length != reverse_flag.length)
        {
            console.log("false")
            return false;
        }
        for(i=0;i<flag.length;i++)
        {
            var code = flag.charCodeAt(i);
            code = code<<1;
            code ^= 0xba;
            code = ~code;
            if(code != reverse_flag[i])
            {
                console.log("false")
                return false;
            }
        }
        console.log("true")
        return true;
    }
    
    function reverse_computation()
    {
      let reverse_string = ""
      for(i=0;i<reverse_flag.length;i++)
      {
          var code = reverse_flag[i];
          code = ~code;
          code ^= 0xba;
          code = code>>1;
          reverse_string += String.fromCharCode(code)
      }
      console.log(reverse_string)
    }
    <form method="post" id="form"><input type="password" id="flag" name="flag"><input type="submit" value="Check" onclick="return check_flag()"></form>
    
    <button onclick="reverse_computation()">Reverse Computation</button>
    <button onclick="check_flag()">Check without submit</button>