c0c0n XI DomeCTF Write-Up- Greenland- Team RedX!!

Chetan Singh
4 min readOct 8, 2018

--

This is the story of how we cracked Greenland challenge of c0c0n CTF organized by AppFabs and Kerala Police Cyberdome.

  1. We begin with greenland challenge you can see the challenge in the below screenshot.

2. After downloading the file we extracted the zip file and from that we found a pcap file.

3. We started opening this pcap file using wireshark and started analyzing it.

Our first guess was to search for http packets we gave the filter “http” and then we found something useful.

4. After running follow tcp we found something interesting a website with a list of directories and file name flag.txt and we thought we are done with challenge.

5. After visiting that site and opening flag.txt we found file content was “xxoo” we scratched our head and then started looking for some other files but after 1 hour we gave up and started checking the wireshark again,

6. After sometime we found something interesting.

7. It was sequence of packet having some juicy data, we ran again follow tcp and we found something useful.

8. It was a python code, we copied the code in a file.

import random
import string

from base64 import b64decode
from base64 import b64encode

FLAG = ‘domectf{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}’

enc_ciphers = [‘rotate’, ‘base64e’, ‘shiftrans’, ‘reverse’]

def rotate(s):
_rot13 = string.maketrans(
“ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz”,
“NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm”)
return string.translate(s, _rot13)

def base64e(s):
return b64encode(s)

def shiftrans(plaintext, shift=4):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)

def reverse(string):
return “”.join(reversed(string))

def encode(encode, count=20):
length = len(encode)
length = int(length / 2)
fst = encode[:length]
lst = encode[length:]
for cnt in range(count):
c = random.choice(enc_ciphers)
i = enc_ciphers.index(c) + 1
fst = globals()[c](fst)
fst = str(i) + fst

c = random.choice(enc_ciphers)
i = enc_ciphers.index(c) + 1
lst = globals()[c](lst)
lst = lst + str(i)

return len(fst), len(lst), fst + lst

if __name__ == ‘__main__’:
print(encode(FLAG, count=?))

9. And in the end of the file we found following data.

(14850, 7584, ‘32MTQ9RFFBMFt3WoJbSEhrMTBFSrodSUpXMUpLgUpzeU1……………..)

10. After reading the encode function we found that 14850 is fst length and 7584 is lst length.

Initial of fst string ie. is 3 signify that which encoding function is use to encode fst and tail of lst string signify encode function for lst.

And then we quickly wrote decode function to decode encoded string.

import random
import string

from base64 import b64decode
from base64 import b64encode

FLAG = ‘domectf{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}’

enc_ciphers = [‘rotate’, ‘base64e’, ‘shiftrans’, ‘reverse’]
dec_ciphers = [‘rotate’, ‘base64d’, ‘shiftrans’, ‘reverse’]

data = [14850, 7584, ‘32MTQ9RFFBMFt3WoJbSEhrMTBFSrodSUpXMUpLgUpzeU15RUJBiUp..’]
def rotate(s):
_rot13 = string.maketrans(
“ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz”,
“NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm”)
return string.translate(s, _rot13)

def base64e(s):
return b64encode(s)

def base64d(s):
return b64decode(s)

def shiftrans(plaintext, shift=-4):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)

def reverse(string):
return “”.join(reversed(string))

def encode(encode, count=20):
length = len(encode)
length = int(length / 2)
fst = encode[:length]
lst = encode[length:]
print str(len(fst)) + str(len(lst))
for cnt in range(count):
c = random.choice(enc_ciphers)
i = enc_ciphers.index(c) + 1
fst = globals()[c](fst)
fst = str(i) + fst

c = random.choice(enc_ciphers)
print str(c)
i = enc_ciphers.index(c) + 1
lst = globals()[c](lst)
lst = lst + str(i)
print str(lst)
print len(fst), len(lst), fst + lst
return len(fst), len(lst), fst + lst

def decode(data, cnt):
foo = data[:14850]
count = 0
while “dome” not in foo:
i = foo[0]
_foo = globals()[dec_ciphers[int(i) — 1]](foo[1:])
foo = _foo
count = count + 1
foox = foo
foo = data[14850:]
for x in range(0,count):
i = foo[-1]
_foo = globals()[dec_ciphers[int(i) — 1]](foo[:-1])
foo = _foo
print foox + foo

if __name__ == ‘__main__’:
decode(data[2], 100)

11. And finally we were having our final ctf flag.

domectf{vNJyRMJ5wF78zp63NFvWWPppERYtIRr6}

Greetz.

Team RedX ❤

Team RedRaptor ❤

--

--