We get a PCAP and need to find the hidden flag.
Looking at the traffic in the PCAP, there doesn't seem to be anything interesting ... a bunch of HTTP requests (some HTTPS, hence the TLS).
Seeing as how there were numerous requests towards Google, Facebook, Twitter, csaw.engineering.nyu.edu, and other sites... I tried the next logical thing and took a look at the files that were transferred. This is easily done using Wiresharks file export feature.
Sure enough, there are quite bit of files to be seen. Here is a summary based on only the names and sizes of the files retrieved.
- 4 files roughly 153KB in size, having the name %5c - probably the HTML source of the sites that were visited
- 4 files roughly 24KB in size having the same name %5c - probably some CSS/JavaScript that came with the HTML source
- 123 files roughly 1KB in size having the name object<number> - no idea what that would be...
- 8 files roughly 1KB in size having the name %5c- probably various redirects (would make sense based on the 4+4 sites that were visited)
Looking at the files named %5c it's easy enough to confirm the above assumptions without taking to much time. Now for the hard part ... analyzing the many object<number> files ...
Luckily, opening up the very first one (in my case it's called object60) reviles a Python script!
import string
import random
from base64 import b64encode, b64decode
FLAG = 'flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}'
enc_ciphers = ['rot13', 'b64e', 'caesar']
# dec_ciphers = ['rot13', 'b64d', 'caesard']
def rot13(s):
_rot13 = string.maketrans(
"ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",
"NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
return string.translate(s, _rot13)
def b64e(s):
return b64encode(s)
def caesar(plaintext, shift=3):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
def encode(pt, cnt=50):
tmp = '2{}'.format(b64encode(pt))
for cnt in xrange(cnt):
c = random.choice(enc_ciphers)
i = enc_ciphers.index(c) + 1
_tmp = globals()[c](tmp)
tmp = '{}{}'.format(i, _tmp)
return tmp
if __name__ == '__main__':
print encode(FLAG, cnt=?)
Well this looks promising! :)
It looks like a simple encoder/decoder, and it even has the flag template flag{xxx} embedded in it. There are four distinct functions here:
- rot13 - a simple substitution cipher that replaces a letter with the letter 13 letters after it in the alphabet
- b64e - a function that simply encodes a string to Base64
- caesar - another simple substitution cipher that replaces a letter with the letter 3 letters after it in the alphabet
- encode - this seams to be the master function which is used to encrypt the flag (notice a call to the encrypt function at the main part of the script!). It seems to first encode the flag into Base64, but first it ads the number 2 before the encoded string is concatenated. The number 2 seems to align with the index of the b64e function in the enc_ciphers variable. The rest of the function seems to randomly pick a function from the enc_ciphers variable and then apply the chosen algorithm to the entire string, thus forming a new one. Each time, the index of the used algorithm is added before the string.
Obviously, we now have a way of decrypting the encrypted flag - we just need to find the string which was encoded. Looking at the rest of the object files, we see a bunch of seemingly random letters:
2Mk16Sk5iakYxVFZoS1RsWnZXbFZaYjFaa1prWmFkMDVWVGs1U2IyODFXa1ZuTUZadU1YVldiVkphVFVaS1dGWXlkbUZXTVdkMVprWnJWMlZHYzFsWGJscHVVekpOWVZaeFZsUmxWMnR5VkZabU5HaFdaM1pYY0hkdVRXOWFSMVJXYTA5V1YwcElhRVpTVm1WSGExUldWbHBrWm05dk5sSnZVbXhTVm5OWVZtNW1NV1l4V1dGVWJscFVaWEJoVjF
This seems to be our encrypted flag scattered across a bunch of files. As we can see, the number 2 at the beginning makes the first file (the one with the smallest number in object<number>) the first part of the encrypted string.
First we need to create two decryption functions: b64d, caesard.
b64d is simple - we just call Python's b64decode to decode the Base64 string back to it's original form.
caesard is also simple - we just use a -3 offset to revert the changes of the original caesar cypher
Adding it all together, we get the flag
flag{li0ns_and_tig3rs_4nd_b34rs_0h_mi}
import string
from base64 import b64decode
import os
mypath = "D:\CTFs/CSAW_2015/forensic/100/files/"
files = [ f for f in os.listdir(mypath) if os.path.isfile(os.path.join(mypath,f)) ]
encodedParts = []
for file in files:
if "object" in file:
encodedParts.append(int(file[6:]))
encodedParts = sorted(encodedParts)
# remove first element since it is the script itself ...
encodedParts.pop(0)
# print encodedParts
encodedFlag = ""
for file in encodedParts:
pathToFile = mypath + "object" + str(file)
encodedFlag += open(pathToFile, "r").read()
# print encodedFlag
dec_ciphers = ['rot13', 'b64d', 'caesard']
def rot13(s):
_rot13 = string.maketrans(
"ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",
"NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
return string.translate(s, _rot13)
def b64d(s):
return b64decode(s)
def caesard(plaintext, shift=-3):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
while(1):
if (encodedFlag[0] == "1"):
encodedFlag = rot13(encodedFlag[1:])
elif (encodedFlag[0] =="2"):
encodedFlag = b64d(encodedFlag[1:])
elif (encodedFlag[0] =="3"):
encodedFlag = caesard(encodedFlag[1:])
else:
print "finished..."
print encodedFlag
exit()
No comments:
Post a Comment