├── README.md └── deobfuscate.py /README.md: -------------------------------------------------------------------------------- 1 | # deobfuscate 2 | usage: deobfuscate.py [-h] [-m {replace,decompress,split,ascii}] file 3 | 4 | Deobfuscates Emotet's powershell payload 5 | 6 | positional arguments: 7 | file file with obfuscated code 8 | 9 | optional arguments: 10 | -h, --help show this help message and exit 11 | -m {replace,decompress,split,ascii}, --method {replace,decompress,split,ascii} 12 | Specify obfuscation method 13 | 14 | Written by Lasq / malfind.com 15 | -------------------------------------------------------------------------------- /deobfuscate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import re,sys,zlib,base64,argparse 4 | 5 | obfuscation_methods = [ 6 | ('replace','Replace String','replace\s?\('), 7 | ('decompress','Compress string','::decompress'), 8 | ('split','ASCII table with split','-split'), 9 | ('ascii','ASCII table','\((?:\s?[0-9]{2,3}\s?,?){5,}\)') 10 | ] 11 | 12 | def FindString(str,regx): 13 | match = re.compile(regx,flags=re.I) 14 | search = re.findall(match,str) 15 | return search 16 | 17 | def StrChar(matchobj): 18 | return "'"+chr(int(matchobj.group(1)))+"'" 19 | 20 | def FindReplaces(text,replacements): 21 | match = re.compile("replace\s*(\(|\(\(|)\\\\?'([a-zA-Z0-9]{2,4})\\\\?'(\)|),\\\\?'(.{1})\\\\?'(\)|)",flags=re.I) 22 | search = re.findall(match,text) 23 | if (search == []): 24 | return 0 25 | else: 26 | for i in search: 27 | replacements.add((i[1],i[3])) 28 | return replacements 29 | 30 | def DeobfReplace(text): 31 | replacements = set() 32 | while True: 33 | text = re.sub("'\+'|''\+|\+''","",text) 34 | text = re.sub('\[char\]([0-9]{2,3})',StrChar,text,flags=re.I) 35 | text = re.sub("'\+'|''\+|\+''","",text) 36 | text = re.sub('\[string\]','',text,flags=re.I) 37 | if(FindReplaces(text, replacements) == 0): 38 | return text 39 | else: 40 | replacements = FindReplaces(text, replacements) 41 | for i in replacements: 42 | text = re.sub("'\+'|''\+|\+''","",text) 43 | text = text.replace(i[0],i[1]) 44 | 45 | 46 | def Detect(text): 47 | for (_, method, regx) in obfuscation_methods: 48 | match = re.compile(regx,flags=re.I) 49 | search = re.findall(match,text) 50 | if (search != []): 51 | return method 52 | if (search == []): 53 | return -1 54 | 55 | def Deobfuscate(text,method): 56 | try: 57 | if (method == "Replace String"): 58 | return DeobfReplace(text) 59 | elif (method == "Compress string"): 60 | compressed = FindString(text,"frombase64string\(\s?'(\S*)'")[0] 61 | return zlib.decompress(base64.b64decode(compressed),-zlib.MAX_WBITS) 62 | elif (method == "ASCII table with split"): 63 | split_by = '|'.join(FindString(text,"split\s?'(\S)'")) 64 | ascii_table = re.split(split_by,FindString(text,"\('(\S*)'")[0]) 65 | return ''.join(chr(int(i)) for i in ascii_table) 66 | elif (method == "ASCII table"): 67 | ascii_table = re.split(',',FindString(text,'\(((?:\s?[0-9]{2,3}\s?,?){5,})\)')[0]) 68 | return ''.join(chr(int(i)) for i in ascii_table) 69 | except: 70 | print "Unfortunately deobfuscation failed. Maybe you provided wrong method or there is no method to deobfuscate this code." 71 | return -1 72 | 73 | def main(): 74 | parser = argparse.ArgumentParser(description='Deobfuscates Emotet\'s powershell payload') 75 | parser.add_argument("file", type=argparse.FileType('r'), help="file with obfuscated code") 76 | parser.add_argument("-m", "--method",type=str, choices=['replace', 'decompress', 'split', 'ascii'], help="Specify obfuscation method") 77 | args = parser.parse_args() 78 | text = args.file.readlines() 79 | for line in text: 80 | if (args.method != None): 81 | for i in obfuscation_methods: 82 | if (i[0] == args.method): 83 | detected = i[1] 84 | print "Provided obfuscation method: " + detected 85 | deobfuscated_text = Deobfuscate(line,detected) 86 | else: 87 | detected = Detect(line) 88 | if (detected != -1): 89 | print "Detected obfuscation method: " + detected 90 | deobfuscated_text = Deobfuscate(line,detected) 91 | else: 92 | print "Obfuscation method could not be detected automatically. Try to specify deobfuscation method by using --method" 93 | return -1 94 | if (deobfuscated_text != -1): 95 | urls = FindString(deobfuscated_text,'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[/\-\w]+') 96 | print '' 97 | print 'Deobfuscated text: ' 98 | print deobfuscated_text 99 | print '' 100 | print 'IoC Found: ' 101 | for url in urls: 102 | print url 103 | 104 | if __name__ == "__main__": 105 | main() --------------------------------------------------------------------------------