2

I'm working on a Padding Oracle attack and which involves altering an IV and sending it back with a HTML post request. The simple version is that I'm trying to alter the last byte of a string....and I think I might be doing it wrong. First we start out with a Raw IV from the Oracle.

IV = 'NFhS0jOCAR0ymB2MM+3Pfg=='

We can't work with that so we do base-64 decoding on it.

IV = base64.b64decode(IV)

That turns it into garbage on our screen (4XR�3�2��3��~) but now it's in a form that we can work with. Now we want to find out the last byte of the IV so we say

LastByte = IV[len(IV)-1]

Which gives us "~" as the last byte. NOW things get crazy, we want to change the last byte of the IV by XOR'ing it with a number we will call X.

NewByte = ord(LastByte) ^ x
newIV = IV[:len(IV)-1] + str(NewByte)

And then we base64 encode it and move on

newIV = base64.b64encode(newIV)

When I check the length of the newIV it's the same length as the original raw IV but I just feel like something isn't right here. Am I messing it up by doing str(NewByte)? I feel like I should be doing this with a bytearray somehow but I don't know enough about using them do it in one. Did I alter the last byte correctly?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
OneManRiot
  • 941
  • 3
  • 8
  • 22

1 Answers1

1

You want to use the chr() function to turn your XORed integer back into a one-character string:

NewByte = chr(ord(LastByte) ^ x)

chr() is the inverse of ord():

>>> ord('~')
126
>>> chr(126)
'~'

You can use negative indices to slice or select relative to the end of a string, no need to use len(IV) here:

IV = base64.b64decode(IV)
LastByte = IV[-1]
NewByte = chr(ord(LastByte) ^ x)
newIV = IV[:-1] + NewByte
newIV = base64.b64encode(newIV)

or, more concicely:

IV = base64.b64decode(IV)
newIV = base64.b64encode(IV[:-1] + chr(ord(IV[-1]) ^ x))

Demo:

>>> IV = 'NFhS0jOCAR0ymB2MM+3Pfg=='
>>> x = 128
>>> IV = base64.b64decode(IV)
>>> base64.b64encode(IV[:-1] + chr(ord(IV[-1]) ^ x))
'NFhS0jOCAR0ymB2MM+3P/g=='
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • chr() was the answer alright. My code now looks closer to what it should be doing but I'm still a ways away from my final goal. Big thanks! – OneManRiot Mar 16 '14 at 01:44