Tags: rot13 python base64 bacon atbash 

Rating: 5.0

Organisers ask us to NetCat chal.ctf.b01lers.com on Port 2008.

After connecting on the server we got some interfface like this one:

https://abbishal.me/CTF/totem1.png


There is 3 option called: Method (which declare the method of encryption), Ciphertext (which declare the encrypted text) Input (this is a input field to submit decrypted text)

Organisers also provided a python script template which is:

# You can install these packages to help w/ solving unless you have others in mind
# i.e. python3 -m pip install {name of package}
from pwn import *
import codecs
from base64 import b64decode
from string import ascii_lowercase

HOST = ''
PORT = 0

r = remote(HOST,PORT)

def bacon(s):
    # Do this

def rot13(s):
    # And this

def atbash(s):
    # And this one

def Base64(s):
    # Lastly this one

if __name__ == '__main__':
    count = 0
    while True:     
        r.recvuntil('Method: ')
        method = r.recvuntil('\n').strip()
        r.recvuntil('Ciphertext: ')
        argument = r.recvuntil('\n').strip()

        result = globals()[method.decode()](argument.decode())  # :)

        r.recv()
        r.sendline(result.encode())
        count += 1
        if count == 1000:
            print(r.recv())
            exit(0)
    

If we read the code then we can understand that we need to decrypt 4 types of encryption which are:

  1. Bacon
  2. ROT13
  3. Atbash
  4. Base64

And we will get the flag ater 1000 times correct decryption.

so we just need to implement python decryption codes to the template.

After getting ready the python program, codes looks like this:

# You can install these packages to help w/ solving unless you have others in mind
# i.e. python3 -m pip install {name of package}
from pwn import *
import codecs
from base64 import b64decode
from string import ascii_lowercase

HOST = '104.197.187.199'
PORT = 2008

r = remote(HOST,PORT)

lookup = {'a':'AAAAA', 'b':'AAAAB', 'c':'AAABA', 'd':'AAABB', 'e':'AABAA', 
        'f':'AABAB', 'g':'AABBA', 'h':'AABBB', 'i':'ABAAA', 'j':'ABAAB', 
        'k':'ABABA', 'l':'ABABB', 'm':'ABBAA', 'n':'ABBAB', 'o':'ABBBA', 
        'p':'ABBBB', 'q':'BAAAA', 'r':'BAAAB', 's':'BAABA', 't':'BAABB', 
        'u':'BABAA', 'v':'BABAB', 'w':'BABBA', 'x':'BABBB', 'y':'BBAAA', 'z':'BBAAB'} 

# Function to encrypt the string according to the cipher provided 
def bacon(s): 
    decipher = '' 
    i = 0

    # emulating a do-while loop 
    while True : 
        # condition to run decryption till 
        # the last set of ciphertext 
        if(i < len(s)-4): 
            # extracting a set of ciphertext 
            # from the message 
            substr = s[i:i + 5] 
            # checking for space as the first 
            # character of the substring 
            if(substr[0] != ' '): 
                ''' 
                This statement gets us the key(plaintext) using the values(ciphertext) 
                Just the reverse of what we were doing in encrypt function 
                '''
                decipher += list(lookup.keys())[list(lookup.values()).index(substr)] 
                i += 5 # to get the next set of ciphertext 

            else: 
                # adds space 
                decipher += ' '
                i += 1 # index next to the space 
        else: 
            break # emulating a do-while loop 

    return decipher

def rot13(s):
    chars = "abcdefghijklmnopqrstuvwxyz"
    trans = chars[13:]+chars[:13]
    rot_char = lambda c: trans[chars.find(c)] if chars.find(c)>-1 else c
    return ''.join( rot_char(c) for c in s ) 

lookup_table = {'a' : 'z', 'b' : 'y', 'c' : 'x', 'd' : 'w', 'e' : 'v', 
        'f' : 'u', 'g' : 't', 'h' : 's', 'i' : 'r', 'j' : 'q', 
        'k' : 'p', 'l' : 'o', 'm' : 'n', 'n' : 'm', 'o' : 'l', 
        'p' : 'k', 'q' : 'j', 'r' : 'i', 's' : 'h', 't' : 'g', 
        'u' : 'f', 'v' : 'e', 'w' : 'd', 'x' : 'c', 'y' : 'b', 'z' : 'a'} 

def atbash(s): 
    cipher = '' 
    for letter in s: 
        # checks for space 
        if(letter != ' '): 
            #adds the corresponding letter from the lookup_table 
            cipher += lookup_table[letter] 
        else: 
            # adds space 
            cipher += ' '

    return cipher

def Base64(s):
    decodedBytes = base64.b64decode(s)
    decodedStr = str(decodedBytes)
    return (decodedStr)

if __name__ == '__main__':
    count = 0
    while True:     
        r.recvuntil('Method: ')
        method = r.recvuntil('\n').strip()
        r.recvuntil('Ciphertext: ')
        argument = r.recvuntil('\n').strip()

        result = globals()[method.decode()](argument.decode())  # :)

        r.recv()
        r.sendline(result.encode())
        count += 1
        if count == 1000:
            print(r.recv())
            exit(0)
    

After run this program we got the Flag:

We must be dreaming, here's your flag: ctf{4n_313g4nt_s01ut10n_f0r_tr4cking_r341ity}

Original writeup (https://abbishal.me/).