| categories:writeups series:9447 Security Society CTF 2014
9447 CTF 2014 - nosql
For this challenge we have a client and server scripts that implement a Redis-like database and a network dump of the communication between the client and the server. They both share an AES key: the client encrypts the commands using ECB mode and the server decrypts the payload it receives and then executes the commands.
Of course we do not have the AES key used by the server, however we have a previous valid communication that we can replay. If we dump the data sent by the client using Wireshark we obtain this blob.
As ECB is used we can arbitrarily reorder the blocks in the encrypted message. We have the encryption of the following blocks:
` 'HELLO\nSHOW VERSI'
'ON\nSET example T'
'his tiny script '
'is basically a R'
'edisStore...\nGET'
' example\nSHOW KE'
'YS\nSET brucefact'
'#1 Bruce Schneie'
'r can break elli'
'ptic curve crypt'
'ography by bendi'
'ng it into a cir'
'cle\nSET brucefac'
't#2 Bruce Schnei'
'er always cooks '
'his eggs scrambl'
'ed. When he want'
's hardboiled egg'
's, he unscramble'
's them\nSET bruce'
'fact#3 Bruce Sch'
'neier could solv'
'e this by invert'
'ing md5 hash of '
'the flag\nENCRYPT'
'ION HEX\nMD5 flag'
'\n'
Our goal is construct a message like “GET flag” or equivalent. The block ’edisStore…\nGET’ looks interesting as if we’d have another block starting with ‘flag\n’ we would easily solve the task. Unfortunately this is not the case.
However it is interesting to look at the server code: if we pass an invalid command or a command without arguments the args variable is not overwritten and thus its value remains the one of the previous command! Also, if we pass a command without spaces in it the previous value of args is used
So, we can send the following blocks to get the flag:
'ION HEX\nMD5 flag'
'\n'
'edisStore...\nGET'
'\n'`
This will be interpreted as:
- Execute “ION HEX” -> invalid command
- Execute “MD5 flag” -> valid command, the output is useless to us but it sets args to “flag”
- Execute “edisStore…” -> invalid command
- Execute “GET” -> as args is set to “flag” this will get us the flag