#!/usr/bin/env python
"""
Script to convert a string to a valid set of sub domain names and reverse.

The objective is to allow exfiltration via DNS of the string.

"H+G3cyBBn(^p[>pY2D4?-Y]?rx^d[yeUn]fY?B(pX|NSb]:2?K4tTGH}Dk!6H[M,(4ji#sF>11/QHVE&n\R[le}|"
Become
"x482b4733637942426e285e705b3e70593244343f2d595d3f72785e645b79x.x65556e5d66593f422870587c4e53625d3a323f4b34745447487d446b2136x.x485b4d2c28346a692373463e31312f51485645266e5c525b6c657d7cx"

Source:
- https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DomainNameFormat.html

Dependency: None
"""
import argparse


def string_to_subdomain_names(value):
    hex_encoded = value.encode("utf-8").hex()
    chunk_size = 60
    chunk_count = round(len(hex_encoded) / chunk_size)
    subdomain_names = []
    for i in range(chunk_count):
        position = i * chunk_size
        chunk = hex_encoded[position:position+chunk_size]
        # x character is used as chunk identifier for the reverse operation
        subdomain_names.append(f"x{chunk}x")
    return ".".join(subdomain_names)


def subdomain_names_to_string(value):
    chunks = value.split(".")
    hex_encoded = ""
    for chunk in chunks:
        if chunk.startswith("x") and chunk.endswith("x"):
            hex_encoded += chunk[1:-1]
    return bytes.fromhex(hex_encoded).decode("utf-8")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Script to convert a string to a valid set of sub domain names and reverse.")
    parser.add_argument("-e", action="store", dest="string_to_encode", help="String to encode", required=False, default=None)
    parser.add_argument("-d", action="store", dest="string_to_decode", help="String to decode", required=False, default=None)
    args = parser.parse_args()
    if args.string_to_encode is not None and args.string_to_decode is not None:
        print("Only one mode is usable at the time!")
    elif args.string_to_encode is None and args.string_to_decode is None:
        print("One mode must be specified!")
    elif args.string_to_encode is not None:
        value = args.string_to_encode
        print(string_to_subdomain_names(value))
    else:
        value = args.string_to_decode
        print(subdomain_names_to_string(value))
