mirror of
https://github.com/CyberMonitor/APT_CyberCriminal_Campagin_Collections
synced 2024-06-16 12:00:04 +00:00
2017.02.15.deep-dive-dragonok-rambo-backdoor
This commit is contained in:
parent
57de801d5b
commit
cfa2a3322d
BIN
2017/2017.02.15.deep-dive-dragonok-rambo-backdoor/Deep Dive on the DragonOK Rambo Backdoor _ Morphick Cyber Security.pdf
Normal file
BIN
2017/2017.02.15.deep-dive-dragonok-rambo-backdoor/Deep Dive on the DragonOK Rambo Backdoor _ Morphick Cyber Security.pdf
Normal file
Binary file not shown.
@ -0,0 +1,404 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#################################################################################
|
||||
|
||||
# Python implementation of the Tiny Encryption Algorithm (TEA)
|
||||
|
||||
# By Moloch
|
||||
|
||||
#
|
||||
|
||||
# About: TEA has a few weaknesses. Most notably, it suffers from
|
||||
|
||||
# equivalent keys each key is equivalent to three others,
|
||||
|
||||
# which means that the effective key size is only 126 bits.
|
||||
|
||||
# As a result, TEA is especially bad as a cryptographic hash
|
||||
|
||||
# function. This weakness led to a method for hacking Microsoft's
|
||||
|
||||
# Xbox game console (where I first encountered it), where the
|
||||
|
||||
# cipher was used as a hash function. TEA is also susceptible
|
||||
|
||||
# to a related-key attack which requires 2^23 chosen plaintexts
|
||||
|
||||
# under a related-key pair, with 2^32 time complexity.
|
||||
|
||||
#
|
||||
|
||||
# Block size: 64bits
|
||||
|
||||
# Key size: 128bits
|
||||
|
||||
#
|
||||
|
||||
##################################################################################
|
||||
|
||||
|
||||
|
||||
import os
|
||||
|
||||
import getpass
|
||||
|
||||
import platform
|
||||
|
||||
import struct
|
||||
|
||||
|
||||
from random import choice
|
||||
|
||||
from hashlib import sha256
|
||||
|
||||
from ctypes import c_uint32
|
||||
|
||||
from string import ascii_letters, digits
|
||||
|
||||
|
||||
if platform.system().lower() in ['linux', 'darwin']:
|
||||
|
||||
INFO = "\033[1m\033[36m[*]\033[0m "
|
||||
|
||||
WARN = "\033[1m\033[31m[!]\033[0m "
|
||||
|
||||
else:
|
||||
|
||||
INFO = "[*] "
|
||||
|
||||
WARN = "[!] "
|
||||
|
||||
|
||||
### Magical Constants
|
||||
|
||||
DELTA = 0x9e3779b9
|
||||
|
||||
SUMATION = 0xc6ef3720
|
||||
|
||||
ROUNDS = 32
|
||||
|
||||
BLOCK_SIZE = 2 # number of 32-bit ints
|
||||
|
||||
KEY_SIZE = 4
|
||||
|
||||
|
||||
|
||||
### Functions ###
|
||||
|
||||
def encrypt_block(block, key, verbose=False):
|
||||
|
||||
'''
|
||||
|
||||
Encrypt a single 64-bit block using a given key
|
||||
|
||||
@param block: list of two c_uint32s
|
||||
|
||||
@param key: list of four c_uint32s
|
||||
|
||||
'''
|
||||
|
||||
assert len(block) == BLOCK_SIZE
|
||||
|
||||
assert len(key) == KEY_SIZE
|
||||
|
||||
sumation = c_uint32(0)
|
||||
|
||||
delta = c_uint32(DELTA)
|
||||
|
||||
for index in range(0, ROUNDS):
|
||||
|
||||
sumation.value += delta.value
|
||||
|
||||
block[0].value += ((block[1].value << 4) + key[0].value) ^ (block[1].value + sumation.value) ^ ((block[1].value >> 5) + key[1].value)
|
||||
|
||||
block[1].value += ((block[0].value << 4) + key[2].value) ^ (block[0].value + sumation.value) ^ ((block[0].value >> 5) + key[3].value)
|
||||
|
||||
if verbose: print("\t--> Encrypting block round %d of %d" % (index + 1, ROUNDS))
|
||||
|
||||
return block
|
||||
|
||||
|
||||
def decrypt_block(block, key, verbose=False):
|
||||
|
||||
'''
|
||||
|
||||
Decrypt a single 64-bit block using a given key
|
||||
|
||||
@param block: list of two c_uint32s
|
||||
|
||||
@param key: list of four c_uint32s
|
||||
|
||||
'''
|
||||
|
||||
assert len(block) == BLOCK_SIZE
|
||||
|
||||
assert len(key) == KEY_SIZE
|
||||
|
||||
sumation = c_uint32(SUMATION)
|
||||
|
||||
delta = c_uint32(DELTA)
|
||||
|
||||
for index in range(0, ROUNDS):
|
||||
|
||||
block[1].value -= ((block[0].value << 4) + key[2].value) ^ (block[0].value + sumation.value) ^ ((block[0].value >> 5) + key[3].value);
|
||||
|
||||
block[0].value -= ((block[1].value << 4) + key[0].value) ^ (block[1].value + sumation.value) ^ ((block[1].value >> 5) + key[1].value);
|
||||
|
||||
sumation.value -= delta.value
|
||||
|
||||
if verbose: print("\t<-- Decrypting block round %d of %d" % (index + 1, ROUNDS))
|
||||
|
||||
return block
|
||||
|
||||
|
||||
def to_c_array(data):
|
||||
|
||||
''' Converts a string to a list of c_uint32s '''
|
||||
|
||||
c_array = []
|
||||
|
||||
for index in range(0, len(data)/4):
|
||||
|
||||
chunk = data[index*4:index*4+4]
|
||||
|
||||
packed = struct.unpack(">L", chunk)[0]
|
||||
|
||||
c_array.append(c_uint32(packed))
|
||||
|
||||
return c_array
|
||||
|
||||
|
||||
def to_string(c_array):
|
||||
|
||||
''' Converts a list of c_uint32s to a Python (ascii) string '''
|
||||
|
||||
output = ''
|
||||
|
||||
for block in c_array:
|
||||
|
||||
output += struct.pack(">L", block.value)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def random_chars(nchars):
|
||||
|
||||
chars = ''
|
||||
|
||||
for n in range(0, nchars):
|
||||
|
||||
chars += choice(ascii_letters + digits)
|
||||
|
||||
return chars
|
||||
|
||||
|
||||
def add_padding(data, verbose=False):
|
||||
|
||||
pad_delta = 4 - (len(data) % 4)
|
||||
|
||||
if verbose:
|
||||
|
||||
print(INFO + "Padding delta: %d" % pad_delta)
|
||||
|
||||
data += random_chars(pad_delta)
|
||||
|
||||
data += "%s%d" % (random_chars(3), pad_delta)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def encrypt(data, key, verbose=False):
|
||||
|
||||
'''
|
||||
|
||||
Encrypt string using TEA algorithm with a given key
|
||||
|
||||
'''
|
||||
|
||||
data = add_padding(data, verbose)
|
||||
|
||||
data = to_c_array(data)
|
||||
|
||||
key = to_c_array(key.encode('ascii', 'ignore'))
|
||||
|
||||
cipher_text = []
|
||||
|
||||
for index in range(0, len(data), 2):
|
||||
|
||||
if verbose:
|
||||
|
||||
print(INFO + "Encrypting block %d" % index)
|
||||
|
||||
block = data[index:index + 2]
|
||||
|
||||
block = encrypt_block(block, key, verbose)
|
||||
|
||||
for uint in block:
|
||||
|
||||
cipher_text.append(uint)
|
||||
|
||||
if verbose:
|
||||
|
||||
print(INFO + "Encryption completed successfully")
|
||||
|
||||
return to_string(cipher_text)
|
||||
|
||||
|
||||
def decrypt(data, key, verbose=False):
|
||||
|
||||
data = to_c_array(data)
|
||||
|
||||
key = to_c_array(key.encode('ascii', 'ignore'))
|
||||
|
||||
plain_text = []
|
||||
|
||||
for index in range(0, len(data), 2):
|
||||
|
||||
if verbose:
|
||||
|
||||
print(INFO + "Encrypting block %d" % index)
|
||||
|
||||
block = data[index:index + 2]
|
||||
|
||||
decrypted_block = decrypt_block(block, key, verbose)
|
||||
|
||||
for uint in decrypted_block:
|
||||
|
||||
plain_text.append(uint)
|
||||
|
||||
data = to_string(plain_text)
|
||||
|
||||
if verbose:
|
||||
|
||||
print(INFO + "Decryption compelted successfully")
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def get_key(password=''):
|
||||
|
||||
''' Generate a key based on user password '''
|
||||
|
||||
if 0 == len(password):
|
||||
|
||||
password = getpass.getpass(INFO + "Password: ")
|
||||
|
||||
sha = sha256()
|
||||
|
||||
sha.update(password + "Magic Static Salt")
|
||||
|
||||
sha.update(sha.hexdigest())
|
||||
|
||||
return ''.join([char for char in sha.hexdigest()[::4]])
|
||||
|
||||
|
||||
def encrypt_file(fpath, key, verbose=False):
|
||||
|
||||
with open(fpath, 'rb+') as fp:
|
||||
|
||||
data = fp.read()
|
||||
|
||||
cipher_text = encrypt(data, key, verbose)
|
||||
|
||||
fp.seek(0)
|
||||
|
||||
fp.write(cipher_text)
|
||||
|
||||
fp.close()
|
||||
|
||||
|
||||
def decrypt_file(fpath, key, verbose=False):
|
||||
|
||||
with open(fpath, 'rb+') as fp:
|
||||
|
||||
data = fp.read()
|
||||
|
||||
plain_text = decrypt(data, key, verbose)
|
||||
|
||||
fp.close()
|
||||
|
||||
fp = open(fpath, 'w')
|
||||
|
||||
fp.write(plain_text)
|
||||
|
||||
fp.close()
|
||||
|
||||
|
||||
|
||||
### UI Code ###
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(
|
||||
|
||||
description='Python implementation of the TEA cipher',
|
||||
|
||||
)
|
||||
|
||||
parser.add_argument('-e', '--encrypt',
|
||||
|
||||
help='encrypt a file',
|
||||
|
||||
dest='epath',
|
||||
|
||||
default=None
|
||||
|
||||
)
|
||||
|
||||
parser.add_argument('-d', '--decrypt',
|
||||
|
||||
help='decrypt a file',
|
||||
|
||||
dest='dpath',
|
||||
|
||||
default=None
|
||||
|
||||
)
|
||||
|
||||
parser.add_argument('--verbose',
|
||||
|
||||
help='display verbose output',
|
||||
|
||||
default=False,
|
||||
|
||||
action='store_true',
|
||||
|
||||
dest='verbose'
|
||||
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.epath is None and args.dpath is None:
|
||||
|
||||
print('Error: Must use --encrypt or --decrypt')
|
||||
|
||||
elif args.epath is not None:
|
||||
|
||||
print(WARN + 'Encrypt Mode: The file will be overwritten')
|
||||
|
||||
if os.path.exists(args.epath) and os.path.isfile(args.epath):
|
||||
|
||||
key = get_key()
|
||||
|
||||
encrypt_file(args.epath, key, args.verbose)
|
||||
|
||||
else:
|
||||
|
||||
print(WARN + 'Error: target does not exist, or is not a file')
|
||||
|
||||
elif args.dpath is not None:
|
||||
|
||||
print(WARN + 'Decrypt Mode: The file will be overwritten')
|
||||
|
||||
if os.path.exists(args.dpath) and os.path.isfile(args.dpath):
|
||||
|
||||
key = get_key()
|
||||
|
||||
decrypt_file(args.dpath, key, args.verbose)
|
||||
|
||||
else:
|
||||
|
||||
print(WARN + 'Error: target does not exist, or is not a file')
|
@ -0,0 +1,31 @@
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=000 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Err_Errno2String
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=001 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Log
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=002 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Log_CfgInterface
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=003 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Log_InitWithFileSimpleInt
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=004 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Log_SetProductInfo
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=005 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Preference_Init
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=006 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_ProductState_GetBuildNumberString
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=007 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_ProductState_GetCompilationOption
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=008 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_ProductState_GetName
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=009 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_ProductState_GetVersion
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=010 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_W32Util_AsciiStrToWideStr
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=011 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_W32Util_GetInstalledFilePath
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=012 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Warning
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=013 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Win32U_LoadLibrary
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=014 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Win32U_RegCreateKeyEx
|
||||
|
||||
vaddr=0x10001431 paddr=0x00000831 ord=015 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=FirstBlood.tmp_Win32U_RegOpenKeyEx
|
Loading…
Reference in New Issue
Block a user