in reversing/matryoshka/generate.py [0:0]
def main():
parser = argparse.ArgumentParser(description='This script generates the final binary and png. \
All source files are placed in src directory. \
Final macho and png are placed in the dist directory. ')
parser.add_argument('--build', '-b', dest='build', action='store_true',
help='build the distributed binary and png')
parser.add_argument('--clean', '-c', dest='clean', action='store_true',
help='remove all generated files')
args = parser.parse_args()
if args.build and not args.clean:
global VERIFYA
global VERIFYB
global VERIFYC
global FLAG_INTEGER
# ----------------------------------
# Generate FLAG_INTEGER
# ----------------------------------
pflag = create_string_buffer(FLAG) # null terminated
# split flag into uint64 numbers
A = cast(pflag, POINTER(c_ulong))
B = cast(byref(pflag, 8), POINTER(c_ulong))
C = cast(byref(pflag, 16), POINTER(c_ulong))
D = cast(byref(pflag, 24), POINTER(c_uint))
FLAG_INTEGER = D[0] ^ SEED
VERIFYC = C[0] ^ D[0]
VERIFYB = B[0] ^ C[0]
VERIFYA = A[0] ^ B[0]
print hex(FLAG_INTEGER)
# ----------------------------------
# RC4 ENCRYPTION
# ----------------------------------
# Combine FLAG_INTEGER with RC4_PRINT
size_of_buffer = len(RC4_PRINT) + 8
rc4_plaintext = ctypes.create_string_buffer(size_of_buffer)
ctypes.memmove(rc4_plaintext, byref(c_ulong(swap64(FLAG_INTEGER))), 8)
ctypes.memmove(byref(rc4_plaintext, 8), RC4_PRINT, len(RC4_PRINT))
rc4_encrypt(rc4_plaintext, rc4_plaintext, RC4_KEY)
#print(ctypes.sizeof(rc4_plaintext), repr(rc4_plaintext.raw))
rc4_encrypted = [ord(num[0]) for num in rc4_plaintext.raw]
generate_rc4_assembly(rc4_encrypted, RC4_ASSEMBLY_FILE)
generate_macho(RC4_ASSEMBLY_FILE)
rc4_shellcode = extract_shellcode(RC4_ASSEMBLY_FILE)
# ----------------------------------
# STREAM XOR ENCRYPTION
# ----------------------------------
xor_encrypted = list(rc4_shellcode)
xor_encrypt(xor_encrypted, XOR_KEY)
generate_xor_assembly(xor_encrypted, XOR_ASSEMBLY_FILE)
generate_macho(XOR_ASSEMBLY_FILE)
xor_shellcode = extract_shellcode(XOR_ASSEMBLY_FILE)
# ----------------------------------
# VIGENERE CIPHER ENCRYPTION
# ----------------------------------
cipher_encrypted = list(xor_shellcode)
cipher_encrypt(cipher_encrypted, CIPHER_KEY)
generate_cipher_assembly(cipher_encrypted, CIPHER_ASSEMBLY_FILE)
generate_macho(CIPHER_ASSEMBLY_FILE)
extract_shellcode(CIPHER_ASSEMBLY_FILE)
# ----------------------------------
# ROT13 ENCRYPTION
# ----------------------------------
rot13_encrypted = ro13_encrypt(ROT13_KEY)
generate_rot13_assembly(rot13_encrypted, ROT13_ASSEMBLY_FILE)
generate_macho(ROT13_ASSEMBLY_FILE)
extract_shellcode(ROT13_ASSEMBLY_FILE)
# ----------------------------------
# BUILD IMAGE
# ----------------------------------
copyfile(os.path.join(SRC_DIR,PNG_FILE), os.path.join(DIST_DIR,PNG_NAME))
b = os.path.splitext(ROT13_ASSEMBLY_FILE)[0]
rot13_shellcode_filename = os.path.join(SRC_DIR,"%s_shellcode.bin" % (b))
with open(rot13_shellcode_filename, 'rb') as sc:
shellcode_bytes = sc.read()
with open(os.path.join(DIST_DIR,PNG_NAME), 'r+b') as png:
s=png.read()
png.seek(0)
png.write(s[:CODE_PNG_OFFSET]
+shellcode_bytes
+s[CODE_PNG_OFFSET+len(shellcode_bytes):])
png.close()
sc.close()
b = os.path.splitext(CIPHER_ASSEMBLY_FILE)[0]
cipher_shellcode_filename = os.path.join(SRC_DIR,"%s_shellcode.bin" % (b))
with open(cipher_shellcode_filename, 'rb') as sc:
shellcode_bytes2 = sc.read()
with open(os.path.join(DIST_DIR,PNG_NAME), 'r+b') as png:
s=png.read()
png.seek(0)
png.write(s[:CODE_PNG_OFFSET+CODE_PNG_OFFSET_2]
+shellcode_bytes2
+s[CODE_PNG_OFFSET+CODE_PNG_OFFSET_2+len(shellcode_bytes2):])
png.close()
sc.close()
# ----------------------------------
# GENERATE DOWNLOADER
# ----------------------------------
generate_downloader(DOWNLOADER_FILE)
generate_downloader_macho(DOWNLOADER_FILE)
elif args.clean and not args.build:
rmfile(RC4_ASSEMBLY_FILE)
rmfile(XOR_ASSEMBLY_FILE)
rmfile(CIPHER_ASSEMBLY_FILE)
rmfile(ROT13_ASSEMBLY_FILE)
if os.path.exists(os.path.join(DIST_DIR,PNG_NAME)):
os.remove(os.path.join(DIST_DIR,PNG_NAME))
if os.path.exists(os.path.join(DIST_DIR,"%s.macho" % DOWNLOADER_FILE)):
os.remove(os.path.join(DIST_DIR,"%s.macho" % DOWNLOADER_FILE))
if os.path.exists(os.path.join(SRC_DIR,"gen_%s.c" % DOWNLOADER_FILE)):
os.remove(os.path.join(SRC_DIR,"gen_%s.c" % DOWNLOADER_FILE))