Hands-On Penetration Testing on Windows
上QQ阅读APP看书,第一时间看更新

Manipulating the IV to generate predictable results

Navigate to OWASP 2017 on the left, then Injection | Other, and then CBC Bit Flipping to arrive at the site shown in the previous screenshot. So, let's get acquainted: we see here that we're currently running with User ID 174 with Group ID 235. We need to be user 000 in group 000 to become the almighty root user. The site is protected with SSL, so intercepting the traffic in transit would be a bit of a pain. What else do you notice about this site?

How about the URL itself? https://192.168.108.104/index.php?page=view-user-privilege-level.php&iv=6bc24fc1ab650b25b4114e93a98f1eba

Oh my – it's an IV field, right there for the taking. We've seen how the IV is XOR with the plaintext before encryption to create the encrypted block, so manipulating the IV would necessarily change the encrypted output. First, let's take a look at the IV itself: 6bc24fc1ab650b25b4114e93a98f1eba. We know that it's hexadecimal and it's 32 characters long; thus the length is 128 bits.

Remember when we experimented with CBC encryption with openssl? We used AES, which always has a 128-bit block size. Considering our IV is 128 bits long, it's possible that the application is AES-encrypting a single block of data, which would make it the first (and only) block, and thus with CBC requires an IV. Remember that any plaintext block that's shorter than the algorithm's block size must be padded. Note what happens to the user data when you try changing the bytes at the end of the IV.

We can sit here analyzing all day but by now you've figured out I like breaking things, so let's modify the IV in the URL, submit it, and see if anything happens. I'm changing the initial character into a zero, making the IV 0bc24fc1ab650b25b4114e93a98f1eba:

Our IDs didn't change, but check out what happened to the Application ID. Now it's !1B2. It used to be A1B2. What if I change the first two hexadecimal digits to zeroes? Our Application ID is now *1B2. If I change the first three, then the next character in the Application ID falls apart because the resulting binary doesn't have an ASCII representation. Now we know that the first two hexadecimal characters in the IV (8 bits) modify the first ASCII character in the Application ID (8 bits). This is a breakthrough that pretty much translates into the final stretch to privilege escalation, because we've just established a direct relationship between the plaintext and the IV, which means we can figure out the ciphertext. And when we know two of the three, in any order, we can calculate the third by virtue of simple binary XOR math. Now, we haven't found which hexadecimal digits are where the User ID and Group ID are manipulable just yet, but let's take a quick break to see if we can figure out this relationship based on what we have so far.

We saw the Application ID change from A to ! to *. Thus, the ID is represented in ASCII, the most common modern standard for character encoding. What's important to us here is that a single ASCII character is 8 bits (1 byte) long. Hexadecimal, on the other hand, is simply a base-16 numeral system. We see hexadecimal everywhere in the gritty underbelly of computing because 16 is a power of 2, which means converting from base-2 (that is, binary) to base-16 is easy as pie (how is pie easy? Never mind, I digress); 2 to the power of 4 equals 16, which means a hexadecimal digit is 4 bits long. Back to our lab:

 

Do you see our golden ticket yet? Well, let's XOR the binary IV values with the known binary ASCII result in the Application ID, because if they match, then we have the value that was XORed with the IV values to generate the Application ID. Remember, if we know two out of three, we know the third.

First, the original IV:

  • Hexadecimal 6b0110 1011
  • ASCII A0100 0001
  • XOR result: 0010 1010

And now, our test manipulated IV:

  • Hexadecimal 00:  0000 0000
  • ASCII *0010 1010
  • XOR result: 0010 1010

And that, my friends, is why they call it bit-flipping. We figured out that the application is taking this byte of the IV and XORing it with 0010 1010 during decryption. Let's test our theory by calculating what we'll get if we replace the first two hexadecimal digits with, say, 45:

  • Hexadecimal 450100 0101
  • Ciphertext XOR: 0010 1010
  • Binary result: 0110 1111

01101111 encodes to an ASCII o (lowercase O). So let's test our theory and see if we end up with an Application ID of o1B2:

Doesn't that just get your blood pumping? This is an exciting breakthrough, but we just picked up on some behind-the-scenes mechanisms; we still aren't root. So let's get to work on finding the bits we really need to flip.