├── README.rst ├── install-peframe-termux.sh ├── install.sh ├── peframe ├── __init__.py ├── config │ └── config-peframe.json ├── modules │ ├── __init__.py │ ├── apialert.py │ ├── autocomplete.py │ ├── directories.py │ ├── features.py │ ├── fileurl.py │ ├── functions.py │ ├── macro.py │ ├── meta.py │ ├── sections.py │ ├── stringstat.py │ ├── virustotal.py │ └── yara_check.py ├── peframe.py ├── peframecli.py └── signatures │ ├── stringsmatch.json │ ├── userdb.txt │ └── yara_plugins │ ├── doc │ ├── JJencode.yar │ ├── Javascript_exploit_and_obfuscation.yar │ ├── Maldoc_APT10_MenuPass.yar │ ├── Maldoc_APT19_CVE-2017-1099.yar │ ├── Maldoc_APT_OLE_JSRat.yar │ ├── Maldoc_CVE-2017-0199.yar │ ├── Maldoc_CVE_2017_11882.yar │ ├── Maldoc_CVE_2017_8759.yar │ ├── Maldoc_Contains_VBE_File.yar │ ├── Maldoc_DDE.yar │ ├── Maldoc_Dridex.yar │ ├── Maldoc_Hidden_PE_file.yar │ ├── Maldoc_MIME_ActiveMime_b64.yar │ ├── Maldoc_PowerPointMouse.yar │ ├── Maldoc_Suspicious_OLE_target.yar │ ├── Maldoc_UserForm.yar │ ├── Maldoc_VBA_macro_code.yar │ ├── Maldoc_Word_2007_XML_Flat_OPC.yar │ ├── Maldoc_hancitor_dropper │ ├── Maldoc_malrtf_ole2link.yar │ ├── maldoc_somerules.yar │ └── pdf │ │ └── Maldoc_PDF.yar │ └── pe │ ├── antidebug_antivm.yar │ ├── crypto_signatures.yar │ ├── packer.yar │ ├── packer_compiler_signatures.yar │ ├── peid.yara │ └── peid_to_remove.yara ├── requirements.txt └── setup.py /README.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | peframe 3 | ======= 4 | 5 | peframe is a open source tool to perform static analysis on `Portable Executable `_ malware and generic suspicious file. It can help malware researchers to detect packer, xor, digital signature, mutex, anti debug, anti virtual machine, suspicious sections and functions, macro and much more information about the suspicious files. 6 | 7 | 8 | Install 9 | ------- 10 | 11 | **Download** 12 | 13 | .. code-block:: 14 | 15 | sudo apt install git 16 | git clone https://github.com/guelfoweb/peframe.git 17 | cd peframe 18 | 19 | **Installation script for Ubuntu** 20 | 21 | .. code-block:: 22 | 23 | sudo bash install.sh 24 | 25 | **Installation (prerequisites required)** 26 | 27 | .. code-block:: 28 | 29 | sudo python3 setup.py install 30 | 31 | 32 | **Prerequisites** 33 | 34 | The following prerequisites are required to be installed on your system before you can install and use peframe. 35 | 36 | .. code-block:: 37 | 38 | python >= 3.6.6 39 | pyton3-pip 40 | libssl-dev 41 | swig 42 | 43 | 44 | Usage 45 | ----- 46 | 47 | peframe -h 48 | 49 | .. code-block:: 50 | 51 | peframe filename Short output analysis 52 | peframe -i filename Interactive mode 53 | peframe -j filename Full output analysis JSON format 54 | peframe -x STRING filename Search xored string 55 | peframe -s filename Strings output 56 | 57 | 58 | **Note** 59 | 60 | You can edit "config-peframe.json" file in "config" folder to configure virustotal API key. After installation you can use "peframe -h" to find api_config path. 61 | 62 | 63 | How to work 64 | ----------- 65 | 66 | **MS Office (macro) document analysis with peframe 6.0.1** 67 | 68 | .. image:: https://asciinema.org/a/mbLd5dChz9iI8eOY15fC2423X.svg 69 | :target: https://asciinema.org/a/mbLd5dChz9iI8eOY15fC2423X?autoplay=1 70 | 71 | 72 | **PE file analysis with peframe 6.0.1** 73 | 74 | .. image:: https://asciinema.org/a/P6ANqp0bHV0nFsuJDuqD7WQD7.svg 75 | :target: https://asciinema.org/a/P6ANqp0bHV0nFsuJDuqD7WQD7?autoplay=1 76 | 77 | 78 | Talk about... 79 | ------------- 80 | * `A Longitudinal Analysis of Brazilian Financial Malware `_ *(Federal University of Paraná, Marcus Botacin, Hojjat Aghakhani, Stefano Ortolani, Christopher Kruegel, Giovanni Vigna, Daniela Oliveira, Paulo Lício de Geus, André Grégio 2020)* 81 | * `Building a smart and automated tool for packed malware detections using machine learning `_ *(Ecole polytechnique de Louvain, Université catholique de Louvain, Minet, Jeremy; Roussieau, Julian 2020)* 82 | * `Revealing Packed Malware `_ *(Department of Electrical and Computer Engineering, Nirwan Ansari, New Jersey Institute of Technology - NJIT)* 83 | * `Critical Infrastructures Security: Improving Defense Against Novel Malware and Advanced Persistent Threats (PDF) `_ *(Department of Computer, Control, and Management Engineering Antonio Ruberti, Sapienza – University of Rome)* 84 | * `Anatomy on Malware Distribution Networks (PDF) `_ *(Department of Intelligent Systems Engineering, Cheju Halla University, Jeju 63092, South Korea)* 85 | * `Intel Owl 0.4.0 `_ *(certego platform - threat intelligence data about a file, an IP or a domain)* 86 | * `Integration of Static and Dynamic Analysis for Malware Family Classification with Composite Neural Network `_ *(Yao Saint, Yen Institute of Information Science, Academia Sinica, Taiwan)* 87 | * `Machine Learning Aided Static Malware Analysis: A Survey and Tutorial `_ *(Sergii Banin, Andrii Shalaginov, Ali Dehghantanha, Katrin Franke, Norway)* 88 | * `Multinomial malware classification, research of the Department of Information Security and Communication Technology (NTNU) `_ *(Sergii Banin and Geir Olav Dyrkolbotn, Norway)* 89 | * `SANS DFIR Poster 2016 `_ *(PEframe was listed in the REMnux toolkits)* 90 | * `Tools for Analyzing Static Properties of Suspicious Files on Windows `_ *(SANS Digital Forensics and Incident Response, Lenny Zeltser).* 91 | * `Automated Static and Dynamic Analysis of Malware `_ *(Cyber Defence Magazine, Andrew Browne, Director Malware Lab Lavasoft).* 92 | * `Suspicious File Analysis with PEframe `_ *(eForensics Magazine, Chintan Gurjar)* 93 | * `CERT FR Security Bulletin `_ *(PEframe was mentioned in the security bulletin CERTFR-2014-ACT-030)* 94 | * `Infosec CERT-PA Malware Analysis `_ *(PEframe is used in the malware analysis engine of Infosec project)* 95 | 96 | Other 97 | ----- 98 | 99 | This tool is currently maintained by `Gianni 'guelfoweb' Amato `_, who can be contacted at guelfoweb@gmail.com or twitter `@guelfoweb `_. Suggestions and criticism are welcome. 100 | -------------------------------------------------------------------------------- /install-peframe-termux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ---------------------------------------------------------------------- 4 | # This file is part of peframe https://github.com/guelfoweb/peframe/ 5 | # ---------------------------------------------------------------------- 6 | 7 | peframe_version="6.0.3" 8 | environment_test="Termux Android" 9 | 10 | echo "Installation script peframe $peframe_version" 11 | echo -e "Tested on $environment_test\n" 12 | 13 | read -rsp $'Press enter to continue...\n' 14 | 15 | pkg update -y 16 | pkg upgrade -y 17 | 18 | pkg install -y git 19 | pkg install -y python 20 | pkg install -y python-dev 21 | pkg install -y clang 22 | pkg install -y swig 23 | pkg install -y openssl-dev 24 | pkg install -y libffi-dev 25 | pkg install -y sox 26 | 27 | python3 setup.py install 28 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ---------------------------------------------------------------------- 4 | # This file is part of peframe https://github.com/guelfoweb/peframe/ 5 | # ---------------------------------------------------------------------- 6 | 7 | if [[ $(id -u) -ne 0 ]]; then 8 | echo "Please run as root" 9 | exit 1 10 | fi 11 | 12 | peframe_version="6.0.3" 13 | environment_test="Ubuntu Desktop 18.04.2 64bit" 14 | 15 | echo "Installation script peframe $peframe_version" 16 | echo -e "Tested on $environment_test\n" 17 | 18 | read -rsp $'Press enter to continue...\n' 19 | 20 | apt -y install python3 21 | apt -y install python3-dev 22 | apt -y install python3-pip 23 | apt -y install libssl-dev 24 | apt -y install swig 25 | 26 | echo -e "\nInstalling requirements via setup.py...\n" 27 | python3 setup.py install 28 | -------------------------------------------------------------------------------- /peframe/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guelfoweb/peframe/70683b6db71c7a1c44c2d8f817822a0815fc6137/peframe/__init__.py -------------------------------------------------------------------------------- /peframe/config/config-peframe.json: -------------------------------------------------------------------------------- 1 | { 2 | "virustotal": "" 3 | } -------------------------------------------------------------------------------- /peframe/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guelfoweb/peframe/70683b6db71c7a1c44c2d8f817822a0815fc6137/peframe/modules/__init__.py -------------------------------------------------------------------------------- /peframe/modules/apialert.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | def get_result(pe, strings_match): 5 | alerts = [] 6 | if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'): 7 | for lib in pe.DIRECTORY_ENTRY_IMPORT: 8 | for imp in lib.imports: 9 | for alert in strings_match: 10 | if alert and imp.name != None: # remove 'null' 11 | if imp.name.decode('ascii').startswith(alert): 12 | alerts.append(imp.name.decode('ascii')) 13 | 14 | return sorted(set(alerts)) 15 | -------------------------------------------------------------------------------- /peframe/modules/autocomplete.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # https://stackoverflow.com/questions/7821661/how-to-code-autocompletion-in-python 5 | 6 | import readline 7 | 8 | class MyCompleter(object): # Custom completer 9 | 10 | def __init__(self, cmd_list): 11 | self.cmd_list = sorted(cmd_list) 12 | 13 | def complete(self, text, state): 14 | if state == 0: # on first trigger, build possible matches 15 | if text: # cache matches (entries that start with entered text) 16 | self.matches = [s for s in self.cmd_list 17 | if s and s.startswith(text)] 18 | else: # no text entered, all matches possible 19 | self.matches = self.cmd_list[:] 20 | 21 | # return match indexed by state 22 | try: 23 | return self.matches[state] 24 | except IndexError: 25 | return None 26 | 27 | 28 | def get_result(cmd_list, prompt_text): 29 | completer = MyCompleter(cmd_list) 30 | readline.set_completer(completer.complete) 31 | readline.set_completer_delims(' \t\n;') 32 | readline.parse_and_bind('tab: complete') 33 | 34 | for cmd in cmd_list: 35 | readline.add_history(cmd) 36 | 37 | raw = input(prompt_text+' ') 38 | 39 | return raw -------------------------------------------------------------------------------- /peframe/modules/directories.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import pefile 5 | 6 | def get_import(pe): 7 | array = [] 8 | library = [] 9 | libdict = {} 10 | 11 | for entry in pe.DIRECTORY_ENTRY_IMPORT: 12 | dll = entry.dll.decode('ascii') 13 | for imp in entry.imports: 14 | address = imp.address 15 | try: 16 | function = imp.name.decode('ascii') 17 | except: 18 | function = str(imp.name) #.decode('ascii') 19 | else: 20 | pass 21 | 22 | if dll not in library: 23 | library.append(dll) 24 | array.append({ 25 | "library": dll, 26 | "offset": address, 27 | "function": function 28 | }) 29 | 30 | for key in library: 31 | libdict[key] = [] 32 | 33 | for lib in library: 34 | for item in array: 35 | if lib == item['library']: 36 | libdict[lib].append({"offset": item['offset'], "function": item['function']}) 37 | return libdict 38 | 39 | def get_export(pe): 40 | array = [] 41 | try: 42 | for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols: 43 | # No dll 44 | address = pe.OPTIONAL_HEADER.ImageBase + exp.address 45 | function = exp.name.decode('ascii') 46 | array.append({"offset": address, "function": function}) 47 | except: 48 | pass 49 | return array 50 | 51 | def get_debug(pe): 52 | DEBUG_TYPE = { 53 | "IMAGE_DEBUG_TYPE_UNKNOWN" : 0, 54 | "IMAGE_DEBUG_TYPE_COFF" : 1, 55 | "IMAGE_DEBUG_TYPE_CODEVIEW" : 2, 56 | "IMAGE_DEBUG_TYPE_FPO" : 3, 57 | "IMAGE_DEBUG_TYPE_MISC" : 4, 58 | "IMAGE_DEBUG_TYPE_EXCEPTION" : 5, 59 | "IMAGE_DEBUG_TYPE_FIXUP" : 6, 60 | "IMAGE_DEBUG_TYPE_BORLAND" : 9, 61 | } 62 | 63 | result = {} 64 | # https://github.com/mnemonic-no/dnscache/blob/master/tools/pdbinfo.py 65 | for d in pe.OPTIONAL_HEADER.DATA_DIRECTORY: 66 | if d.name == "IMAGE_DIRECTORY_ENTRY_DEBUG": break 67 | 68 | if not d or d.name != "IMAGE_DIRECTORY_ENTRY_DEBUG": 69 | return result 70 | 71 | debug_directories = pe.parse_debug_directory(d.VirtualAddress, d.Size) 72 | for debug_directory in debug_directories: 73 | if debug_directory.struct.Type == DEBUG_TYPE["IMAGE_DEBUG_TYPE_CODEVIEW"]: 74 | result.update({ 75 | "PointerToRawData": debug_directory.struct.PointerToRawData, 76 | "size": debug_directory.struct.SizeOfData 77 | }) 78 | return result 79 | return result 80 | 81 | def get_relocations(pe): 82 | result = {} 83 | for d in pe.OPTIONAL_HEADER.DATA_DIRECTORY: 84 | if d.name == "IMAGE_DIRECTORY_ENTRY_BASERELOC": break 85 | 86 | if not d or d.name != "IMAGE_DIRECTORY_ENTRY_BASERELOC": 87 | return result 88 | 89 | result.update({"VirtualAddress": d.VirtualAddress, "Size": d.Size}) 90 | reloc_directories = pe.parse_relocations_directory(d.VirtualAddress, d.Size) 91 | result.update({"count": len(reloc_directories)}) 92 | i = 0 93 | my_items = {} 94 | for items in reloc_directories: 95 | i = i+1 96 | for item in items.entries: 97 | my_items.update({"reloc_"+str(i): len(items.entries)}) 98 | result.update({"details": my_items}) 99 | return result 100 | 101 | def get_tls(pe): 102 | result = {} 103 | for d in pe.OPTIONAL_HEADER.DATA_DIRECTORY: 104 | if d.name == "IMAGE_DIRECTORY_ENTRY_TLS": break 105 | 106 | if not d or d.name != "IMAGE_DIRECTORY_ENTRY_TLS": 107 | return result 108 | 109 | tls_directories = pe.parse_directory_tls(d.VirtualAddress, d.Size).struct 110 | """ 111 | [IMAGE_TLS_DIRECTORY] 112 | 0x0 0x0 StartAddressOfRawData: 0x905A4D 113 | 0x4 0x4 EndAddressOfRawData: 0x3 114 | 0x8 0x8 AddressOfIndex: 0x4 115 | 0xC 0xC AddressOfCallBacks: 0xFFFF 116 | 0x10 0x10 SizeOfZeroFill: 0xB8 117 | 0x14 0x14 Characteristics: 0x0 118 | """ 119 | result.update({ 120 | "StartAddressOfRawData": tls_directories.StartAddressOfRawData, 121 | "EndAddressOfRawData": tls_directories.EndAddressOfRawData, 122 | "AddressOfIndex": tls_directories.AddressOfIndex, 123 | "AddressOfCallBacks": tls_directories.AddressOfCallBacks, 124 | "SizeOfZeroFill": tls_directories.SizeOfZeroFill, 125 | "Characteristics": tls_directories.Characteristics, 126 | }) 127 | 128 | return result 129 | 130 | import re 131 | import binascii 132 | def get_resources(pe): 133 | res_array = [] 134 | try: 135 | ''' 136 | # resource types # description 137 | RT_CURSOR = 1 # Hardware-dependent cursor resource. 138 | RT_BITMAP = 2 # Bitmap resource. 139 | RT_ICON = 3 # Hardware-dependent icon resource. 140 | RT_MENU = 4 # Menu resource. 141 | RT_DIALOG = 5 # Dialog box. 142 | RT_STRING = 6 # String-table entry. 143 | RT_FONTDIR = 7 # Font directory resource. 144 | RT_FONT = 8 # Font resource. 145 | RT_ACCELERATOR = 9 # Accelerator table. 146 | RT_RCDATA = 10 # Application-defined resource (raw data.) 147 | RT_MESSAGETABLE = 11 # Message-table entry. 148 | RT_VERSION = 16 # Version resource. 149 | RT_DLGINCLUDE = 17 # Allows a resource editing tool to associate a string with an .rc file. 150 | RT_PLUGPLAY = 19 # Plug and Play resource. 151 | RT_VXD = 20 # VXD. 152 | RT_ANICURSOR = 21 # Animated cursor. 153 | RT_ANIICON = 22 # Animated icon. 154 | RT_HTML = 23 # HTML resource. 155 | RT_MANIFEST = 24 # Side-by-Side Assembly Manifest. 156 | 157 | RT_GROUP_CURSOR = RT_CURSOR + 11 # Hardware-independent cursor resource. 158 | RT_GROUP_ICON = RT_ICON + 11 # Hardware-independent icon resource. 159 | ''' 160 | for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries: 161 | if resource_type.name is not None: 162 | name = "%s" % resource_type.name 163 | else: 164 | name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id) 165 | if name == None: 166 | name = "%d" % resource_type.struct.Id 167 | 168 | if hasattr(resource_type, 'directory'): 169 | i = 0 170 | for resource_id in resource_type.directory.entries: 171 | if len(resource_type.directory.entries) > 1: 172 | i = i+1 173 | newname = name+'_'+str(i) 174 | else: 175 | newname = name 176 | 177 | for resource_lang in resource_id.directory.entries: 178 | data_byte = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)[:50] 179 | is_pe = False 180 | if magic_check(data_byte)[:8]: 181 | is_pe = True 182 | lang = pefile.LANG.get(resource_lang.data.lang, '*unknown*') 183 | sublang = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang) 184 | 185 | res_array.append({ 186 | "name": newname, 187 | "data": str(data_byte), 188 | "executable": is_pe, 189 | "offset": resource_lang.data.struct.OffsetToData, 190 | "size": resource_lang.data.struct.Size, 191 | "language": lang, 192 | "sublanguage": sublang 193 | }) 194 | except: 195 | pass 196 | 197 | return res_array 198 | 199 | def magic_check(data): 200 | return re.findall(r'4d5a90', str(binascii.b2a_hex(data))) 201 | 202 | 203 | import M2Crypto 204 | def get_sign(pe): 205 | result = {} 206 | 207 | cert_address = pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress 208 | cert_size = pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].Size 209 | 210 | if cert_address != 0 and cert_size !=0: 211 | signature = pe.write()[cert_address+8:] 212 | details = {} 213 | 214 | bio = M2Crypto.BIO.MemoryBuffer(bytes(signature)) 215 | if bio: 216 | pkcs7_obj = M2Crypto.m2.pkcs7_read_bio_der(bio.bio_ptr()) 217 | if pkcs7_obj: 218 | p7 = M2Crypto.SMIME.PKCS7(pkcs7_obj) 219 | for cert in p7.get0_signers(M2Crypto.X509.X509_Stack()) or []: 220 | subject = cert.get_subject() 221 | 222 | try: 223 | serial_number = "%032x" % cert.get_serial_number() 224 | except: 225 | serial_number = '' 226 | try: 227 | common_name = subject.CN 228 | except: 229 | common_name = '' 230 | try: 231 | country = subject.C 232 | except: 233 | country = '' 234 | try: 235 | locality = subject.L 236 | except: 237 | locality = '' 238 | try: 239 | organization = subject.O 240 | except: 241 | organization = '' 242 | try: 243 | email = subject.Email 244 | except: 245 | email = '' 246 | try: 247 | valid_from = cert.get_not_before() 248 | except: 249 | valid_from = '' 250 | try: 251 | valid_to = cert.get_not_after() 252 | except: 253 | valid_to = '' 254 | details.update({ 255 | "serial_number": str(serial_number), 256 | "common_name": str(common_name), 257 | "country": str(country), 258 | "locality": str(locality), 259 | "organization": str(organization), 260 | "email": str(email), 261 | "valid_from": str(valid_from), 262 | "valid_to": str(valid_to), 263 | "hash": { 264 | "sha1": "%040x" % int(cert.get_fingerprint("sha1"), 16), 265 | "md5": "%032x" % int(cert.get_fingerprint("md5"), 16), 266 | "sha256": "%064x" % int(cert.get_fingerprint("sha256"), 16) 267 | } 268 | }) 269 | 270 | result.update({ 271 | "virtual_address": cert_address, 272 | "block_size": cert_size, 273 | "details": details 274 | }) 275 | 276 | return result 277 | 278 | def get(pe): 279 | result = {} 280 | # The directory of imported symbols 281 | try: 282 | result.update({"import": get_import(pe)}) # dict 283 | except: 284 | result.update({"import": {}}) 285 | 286 | # The directory of exported symbols; mostly used for DLLs. 287 | try: 288 | result.update({"export": get_export(pe)}) # list 289 | except: 290 | result.update({"export": []}) 291 | # Debug directory - contents is compiler dependent. 292 | try: 293 | result.update({"debug": get_debug(pe)}) # dict 294 | except: 295 | result.update({"debug": {}}) 296 | # Thread local storage directory - structure unknown; contains variables that are declared 297 | try: 298 | result.update({"tls": get_tls(pe)}) # dict 299 | except: 300 | result.update({"tls": {}}) 301 | # The resources, such as dialog boxes, menus, icons and so on, are stored in the data directory 302 | try: 303 | result.update({"resources": get_resources(pe)}) # list 304 | except: 305 | result.update({"resources": []}) 306 | # PointerToRelocations, NumberOfRelocations, NumberOfLinenumbers 307 | try: 308 | result.update({"relocations": get_relocations(pe)}) # dict 309 | except: 310 | result.update({"relocations": {}}) 311 | # Certificate 312 | try: 313 | result.update({"sign": get_sign(pe)}) # dict 314 | except: 315 | result.update({"sign": {}}) 316 | 317 | return result 318 | -------------------------------------------------------------------------------- /peframe/modules/features.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import json 6 | import pefile 7 | 8 | import array 9 | import binascii 10 | 11 | from . import apialert 12 | from . import yara_check 13 | 14 | def xor_delta(s, key_len = 1): 15 | delta = array.array('B', s) 16 | 17 | for x in range(key_len, len(s)): 18 | delta[x - key_len] ^= delta[x] 19 | 20 | """ return the delta as a string """ 21 | return delta.tostring()[:-key_len] 22 | 23 | def get_xor(filename, search_string=False): 24 | xorsearch_custom = False 25 | check = {} 26 | offset_list = [] 27 | search_file = open(filename, "rb").read() 28 | key_lengths=[1,2,4,8] 29 | if not search_string: 30 | search_string = b"This program cannot be run in DOS mode." 31 | else: 32 | str(search_string) 33 | xorsearch_custom = True 34 | is_xored = False 35 | 36 | for l in key_lengths: 37 | key_delta = xor_delta(search_string, l) 38 | doc_delta = xor_delta(search_file, l) 39 | 40 | offset = -1 41 | while(True): 42 | offset += 1 43 | offset = doc_delta.find(key_delta, offset) 44 | 45 | if(offset > 0) and offset not in offset_list: 46 | offset_list.append(offset) 47 | f = open(filename, 'rb') 48 | f.seek(offset, 0) 49 | data = f.read(39) 50 | if search_string not in data: 51 | is_xored = True 52 | 53 | try: 54 | data = str(data.decode("utf-8")) 55 | except: 56 | data = str(data) 57 | 58 | check.update({hex(offset): data}) 59 | else: 60 | break 61 | 62 | if is_xored or xorsearch_custom: 63 | return check 64 | else: 65 | return {} 66 | 67 | import re 68 | def get_antivm(filename): 69 | 70 | result = {} 71 | 72 | # Credit: Joxean Koret 73 | VM_Sign = { 74 | "VMware trick": b"VMXh", 75 | "Xen": b"XenVMM", 76 | "Red Pill": b"\x0f\x01\x0d\x00\x00\x00\x00\xc3", 77 | "VirtualPc trick": b"\x0f\x3f\x07\x0b", 78 | "VMCheck.dll": b"\x45\xC7\x00\x01", 79 | "VMCheck.dll for VirtualPC": b"\x0f\x3f\x07\x0b\xc7\x45\xfc\xff\xff\xff\xff", 80 | "Bochs & QEmu CPUID Trick": b"\x44\x4d\x41\x63", 81 | "Torpig VMM Trick": b"\xE8\xED\xFF\xFF\xFF\x25\x00\x00\x00\xFF\x33\xC9\x3D\x00\x00\x00\x80\x0F\x95\xC1\x8B\xC1\xC3", 82 | "Torpig (UPX) VMM Trick": b"\x51\x51\x0F\x01\x27\x00\xC1\xFB\xB5\xD5\x35\x02\xE2\xC3\xD1\x66\x25\x32\xBD\x83\x7F\xB7\x4E\x3D\x06\x80\x0F\x95\xC1\x8B\xC1\xC3" 83 | } 84 | 85 | with open(filename, "rb") as f: 86 | buf = f.read() 87 | 88 | for trick in VM_Sign: 89 | pos = buf.find(VM_Sign[trick]) 90 | if pos > -1: 91 | result.update({"trick": trick, "offset": hex(pos)}) 92 | 93 | return result 94 | 95 | def path_to_file(filename, folder): 96 | _ROOT = os.path.abspath(os.path.dirname(__file__)) 97 | return os.path.join(_ROOT, folder, filename) 98 | 99 | def load_config(config_file): 100 | with open(config_file) as conf: 101 | data = json.load(conf) 102 | return data 103 | 104 | def get_result(pe, filename): 105 | features = {} 106 | features.update({ 107 | "mutex": apialert.get_result(pe, load_config(path_to_file('stringsmatch.json', '../signatures'))['mutex']), 108 | "antidbg": apialert.get_result(pe, load_config(path_to_file('stringsmatch.json', '../signatures'))['antidbg']), 109 | "antivm": get_antivm(filename), 110 | "xor": get_xor(filename), 111 | "packer": yara_check.yara_match_from_file(path_to_file('peid.yara', '../signatures/yara_plugins/pe'), filename), 112 | "crypto": yara_check.yara_match_from_file(path_to_file('crypto_signatures.yar', '../signatures/yara_plugins/pe'), filename), 113 | }) 114 | return features 115 | 116 | -------------------------------------------------------------------------------- /peframe/modules/fileurl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import re 5 | import json 6 | import string 7 | import unicodedata 8 | from . import stringstat 9 | 10 | def valid_ip(address): 11 | try: 12 | host_bytes = address.split('.') 13 | valid = [int(b) for b in host_bytes] 14 | valid = [b for b in valid if b >= 0 and b<=255] 15 | return len(host_bytes) == 4 and len(valid) == 4 16 | except: 17 | return False 18 | 19 | def get_result(filename, strings_match): 20 | strings_list = [] 21 | ip_list = [] 22 | file_list = [] 23 | filetype_dict = {} 24 | url_list = [] 25 | fuzzing_dict = {} 26 | 27 | strings_list = list(stringstat.get_result(filename)) 28 | 29 | # Get filetype and fuzzing 30 | file_type = strings_match['filetype'].items() 31 | fuzzing_list = strings_match['fuzzing'].items() 32 | 33 | # Strings analysis 34 | for string in strings_list: 35 | 36 | if len(string) < 2000: 37 | # URL list 38 | urllist = re.findall(r'((smb|srm|ssh|ftps?|file|https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)', string, re.MULTILINE) 39 | if urllist: 40 | for url in urllist: 41 | url_list.append(re.sub(r'\(|\)|;|,|\$', '', url[0])) 42 | 43 | # IP list 44 | iplist = re.findall(r'[0-9]+(?:\.[0-9]+){3}', string, re.MULTILINE) 45 | if iplist: 46 | for ip in iplist: 47 | if valid_ip(str(ip)) and not re.findall(r'[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}\.0', str(ip)): 48 | ip_list.append(str(ip)) 49 | 50 | # FILE list 51 | fname = re.findall("(.+(\.([a-z]{2,3}$)|\/.+\/|\\\.+\\\))+", string, re.IGNORECASE | re.MULTILINE) 52 | if fname: 53 | #print (fname) 54 | for word in fname: 55 | file_list.append(word[0]) 56 | 57 | # Purge list 58 | ip_list = list(set([item for item in ip_list])) 59 | url_list = list(set([item for item in url_list])) 60 | 61 | # Search for valid filename 62 | filetype_dict = {} 63 | array_tmp = [] 64 | for file in file_list: 65 | for key, value in file_type: 66 | for ext in value: 67 | match = re.findall("\\"+ext+"$", str(file), re.IGNORECASE | re.MULTILINE) 68 | if match and file.lower() not in array_tmp and len(file) > 4: 69 | #print(match) 70 | filetype_dict.update({file: key}) 71 | array_tmp.append(file.lower()) 72 | 73 | # Initialize fuzzing 74 | for key, value in fuzzing_list: 75 | fuzzing_dict[key] = [] 76 | 77 | # Strings analysis for fuzzing 78 | array_tmp = [] 79 | for string in strings_list: 80 | if len(string) < 256: 81 | for key, value in fuzzing_list: 82 | fuzz_match = re.findall(value, string, re.IGNORECASE | re.MULTILINE) 83 | if fuzz_match and string.lower() not in array_tmp: 84 | fuzzing_dict[key].append(string) 85 | array_tmp.append(string.lower()) 86 | 87 | # Remove empty key fuzzing 88 | for key, value in fuzzing_list: 89 | if not fuzzing_dict[key]: 90 | del fuzzing_dict[key] 91 | 92 | return {"file": filetype_dict, "url": url_list, "ip": ip_list, "fuzzing": fuzzing_dict, "dump": strings_list} 93 | -------------------------------------------------------------------------------- /peframe/modules/functions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import json 6 | 7 | def path_to_file(filename, folder): 8 | _ROOT = os.path.abspath(os.path.dirname(__file__)) 9 | return os.path.join(_ROOT, folder, filename).replace('modules/', '') 10 | 11 | def load_config(config_file): 12 | with open(config_file) as conf: 13 | data = json.load(conf) 14 | return data 15 | 16 | def files_to_edit(): 17 | path = { 18 | "api_config": path_to_file('config-peframe.json', 'config'), 19 | "string_match": path_to_file('stringsmatch.json', 'signatures'), 20 | "yara_plugins": path_to_file('yara_plugins', 'signatures') 21 | } 22 | return path -------------------------------------------------------------------------------- /peframe/modules/macro.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import re 5 | import sys 6 | from oletools.olevba3 import VBA_Parser, TYPE_OLE, TYPE_OpenXML, TYPE_Word2003_XML, TYPE_MHTML 7 | 8 | def get_result(filename): 9 | try: 10 | behavior = {} 11 | 12 | vbaparser = VBA_Parser(filename) 13 | 14 | if vbaparser.detect_vba_macros(): 15 | results = vbaparser.analyze_macros() 16 | for item in results: 17 | details = re.sub(r'\(.*\)', '', str(item[2])) 18 | details = details.replace('strings', 'str') 19 | details = re.sub(r' $', '', details) 20 | if item[0] == 'AutoExec': 21 | behavior.update({item[1]: details}) 22 | if item[0] == 'Suspicious': 23 | behavior.update({item[1]: details}) 24 | 25 | macro = vbaparser.reveal() 26 | attributes = re.findall(r'Attribute VB.*', macro, flags=re.MULTILINE) 27 | macro = re.sub(r'Attribute VB.*', '', macro) 28 | 29 | return {"behavior": behavior, "macro": macro, "attributes": attributes} 30 | vbaparser.close() 31 | except: 32 | return {} 33 | -------------------------------------------------------------------------------- /peframe/modules/meta.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import string 5 | 6 | def convert_char(char): 7 | if char in string.ascii_letters or \ 8 | char in string.digits or \ 9 | char in string.punctuation or \ 10 | char in string.whitespace: 11 | return char 12 | else: 13 | return r'\x%02x' % ord(char) 14 | 15 | def convert_to_printable(s): 16 | return ''.join([convert_char(c) for c in s]) 17 | 18 | def get(pe): 19 | ret = {} 20 | if hasattr(pe, 'VS_VERSIONINFO'): 21 | if hasattr(pe, 'FileInfo'): 22 | for finfo in pe.FileInfo: 23 | for entry in finfo: 24 | if hasattr(entry, 'StringTable'): 25 | for st_entry in entry.StringTable: 26 | for key, entry in list(st_entry.entries.items()): 27 | ret.update({key.decode(): entry.decode()}) 28 | 29 | return ret 30 | -------------------------------------------------------------------------------- /peframe/modules/sections.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # https://gist.github.com/rjzak/47c28bf3421241c03653f1619e0d8d92 5 | def isSectionExecutable(section): 6 | characteristics = getattr(section, 'Characteristics') 7 | if characteristics & 0x00000020 > 0 or characteristics & 0x20000000 > 0: 8 | return True 9 | return False 10 | 11 | def get_result(pe): 12 | array = [] 13 | for section in pe.sections: 14 | try: 15 | section_name = str(section.Name, 'utf-8').encode('ascii', errors='ignore').strip().decode('ascii') 16 | except: 17 | section_name = str(section.Name, 'ISO-8859-1').encode('ascii', errors='ignore').strip().decode('ascii') 18 | 19 | section_name = section_name.replace('\u0000', '') 20 | 21 | if section_name == '': 22 | section_name = '.noname' 23 | 24 | array.append({ 25 | "section_name": section_name, 26 | "executable": isSectionExecutable(section), 27 | "characteristics": section.Characteristics, 28 | "virtual_address": section.VirtualAddress, 29 | "virtual_size": section.Misc_VirtualSize, 30 | "size_of_raw_data": section.SizeOfRawData, 31 | "hash": { 32 | "md5": section.get_hash_md5(), 33 | "sha1": section.get_hash_sha1(), 34 | "sha256": section.get_hash_sha256(), 35 | }, 36 | "entropy": section.get_entropy(), 37 | "data": str(section.get_data())[:50] #.rstrip(b'\x00')) 38 | }) 39 | 40 | return {"count": pe.FILE_HEADER.NumberOfSections, "details": array} 41 | -------------------------------------------------------------------------------- /peframe/modules/stringstat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import re 5 | import sys 6 | 7 | def get_wanted_chars(): 8 | wanted_chars = ["\0"]*256 9 | 10 | for i in range(32, 127): 11 | wanted_chars[i] = chr(i) 12 | 13 | wanted_chars[ord("\t")] = "\t" 14 | return "".join(wanted_chars) 15 | 16 | def get_wanted_chars_unicode(): 17 | wanted_chars = ["\0"]*256 18 | 19 | for i in range(32, 127): 20 | wanted_chars[i] = chr(i) 21 | 22 | wanted_chars[ord("\t")] = "\t" 23 | return "".join(wanted_chars) 24 | 25 | def get_result(filename): 26 | results = [] 27 | 28 | THRESHOLD = 4 29 | 30 | for s in open(filename, errors="ignore").read().translate(get_wanted_chars()).split("\0"): 31 | if len(s) >= THRESHOLD: 32 | results.append(s) 33 | 34 | return results 35 | -------------------------------------------------------------------------------- /peframe/modules/virustotal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import json 5 | from virus_total_apis import PublicApi as VirusTotalPublicApi 6 | 7 | def get_result(API_KEY, HASH, full=False): 8 | vt = VirusTotalPublicApi(API_KEY) 9 | response = vt.get_file_report(HASH) 10 | if full: 11 | return response 12 | try: 13 | return { 14 | "positives": response['results']['positives'], 15 | "total": response['results']['total'] 16 | } 17 | except: 18 | return { 19 | "positives": "", 20 | "total": "" 21 | } 22 | -------------------------------------------------------------------------------- /peframe/modules/yara_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | from os import walk 6 | import yara 7 | 8 | def yara_match_from_file(fileyara, filename): 9 | matches = [] 10 | rules = yara.compile(fileyara) 11 | 12 | # serialize matches 13 | try: 14 | for match in rules.match(filename): 15 | matches.append(str(match)) 16 | except: # fix yara.Error: internal error: 30 17 | pass 18 | 19 | return matches 20 | 21 | def yara_match_from_folder(folder_yara, filename, exclude=[]): 22 | matches = [] 23 | #for fileyara in yara_files: 24 | for (dirpath, dirnames, filenames) in walk(folder_yara): 25 | for f in filenames: 26 | if str(f).endswith('.yar') and str(f) not in exclude: 27 | path_to_file_yara = str(dirpath)+os.sep+str(f) 28 | 29 | try: 30 | rules = yara.compile(path_to_file_yara) 31 | 32 | # serialize matches 33 | for match in rules.match(filename, timeout=60): 34 | matches.append({f: str(match)}) 35 | except: 36 | pass 37 | 38 | 39 | return matches 40 | -------------------------------------------------------------------------------- /peframe/peframe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # by Gianni 'guelfoweb' Amato 5 | 6 | import os 7 | import re 8 | import sys 9 | import json 10 | import magic 11 | import pefile 12 | import hashlib 13 | from datetime import datetime 14 | 15 | portable = False 16 | for path in sys.path: 17 | if os.sep+'peframe'+os.sep+'peframe' in path: 18 | portable = True 19 | if portable: 20 | from modules import directories 21 | from modules import features 22 | from modules import apialert 23 | from modules import yara_check 24 | from modules import meta 25 | from modules import virustotal 26 | from modules import sections 27 | from modules import fileurl 28 | from modules import macro 29 | else: 30 | from peframe.modules import directories 31 | from peframe.modules import features 32 | from peframe.modules import apialert 33 | from peframe.modules import yara_check 34 | from peframe.modules import meta 35 | from peframe.modules import virustotal 36 | from peframe.modules import sections 37 | from peframe.modules import fileurl 38 | from peframe.modules import macro 39 | 40 | 41 | 42 | def version(): 43 | return "6.0.3" 44 | 45 | def get_datetime_now(): 46 | return datetime.now() 47 | 48 | def isfile(filename): 49 | if os.path.isfile(filename): 50 | return True 51 | return False 52 | 53 | def ispe(filename): 54 | if re.match(r'^PE[0-9]{2}|^MS-DOS', filetype(filename)): 55 | return True 56 | return False 57 | 58 | def filetype(filename): 59 | return magic.from_file(filename) 60 | 61 | def filesize(filename): 62 | return os.path.getsize(filename) 63 | 64 | def get_imphash(filename): 65 | pe = pefile.PE(filename) 66 | return pe.get_imphash() 67 | 68 | def gethash(filename): 69 | hashinfo = {} 70 | 71 | fh = open(filename, 'rb') 72 | m = hashlib.md5() 73 | s = hashlib.sha1() 74 | s256 = hashlib.sha256() 75 | 76 | while True: 77 | data = fh.read(8192) 78 | if not data: 79 | break 80 | 81 | m.update(data) 82 | s.update(data) 83 | s256.update(data) 84 | 85 | hashinfo.update({"md5": m.hexdigest(), "sha1": s.hexdigest(), "sha256": s256.hexdigest()}) 86 | 87 | return hashinfo 88 | 89 | def path_to_file(filename, folder): 90 | _ROOT = os.path.abspath(os.path.dirname(__file__)) 91 | return os.path.join(_ROOT, folder, filename) 92 | 93 | def load_config(config_file): 94 | with open(config_file) as conf: 95 | data = json.load(conf) 96 | return data 97 | 98 | def files_to_edit(): 99 | path = { 100 | "api_config": path_to_file('config-peframe.json', 'config'), 101 | "string_match": path_to_file('stringsmatch.json', 'signatures'), 102 | "yara_plugins": path_to_file('yara_plugins', 'signatures') 103 | } 104 | return path 105 | 106 | def analyze(filename): 107 | if not isfile(filename): 108 | exit("File not found") 109 | 110 | dt_start = get_datetime_now() 111 | 112 | fileinfo = { 113 | "version": version(), 114 | "filename": filename, 115 | "filetype": filetype(filename), 116 | "filesize": filesize(filename), 117 | "hashes": gethash(filename), 118 | "virustotal": virustotal.get_result( 119 | load_config( 120 | path_to_file('config-peframe.json', 'config'))['virustotal'], 121 | gethash(filename)['md5']), 122 | "strings": fileurl.get_result(filename, load_config(path_to_file('stringsmatch.json', 'signatures'))), 123 | } 124 | 125 | 126 | peinfo = {} 127 | docinfo = {} 128 | 129 | fileinfo.update({"docinfo": docinfo}) 130 | fileinfo.update({"peinfo": peinfo}) 131 | 132 | if ispe(filename): 133 | pe = pefile.PE(filename) 134 | peinfo.update({ 135 | "imphash": pe.get_imphash(), 136 | "timestamp": datetime.utcfromtimestamp(pe.FILE_HEADER.TimeDateStamp).strftime('%Y-%m-%d %H:%M:%S'), 137 | "dll": pe.FILE_HEADER.IMAGE_FILE_DLL, 138 | "imagebase": pe.OPTIONAL_HEADER.ImageBase, 139 | "entrypoint": pe.OPTIONAL_HEADER.AddressOfEntryPoint, 140 | "behavior": yara_check.yara_match_from_file(path_to_file('antidebug_antivm.yar', 'signatures/yara_plugins/pe'), filename), 141 | "breakpoint": apialert.get_result(pe, load_config(path_to_file('stringsmatch.json', 'signatures'))['breakpoint']), 142 | "directories": directories.get(pe), 143 | "features": features.get_result(pe, filename), 144 | "sections": sections.get_result(pe), 145 | "metadata": meta.get(pe) 146 | }) 147 | fileinfo.update({"peinfo": peinfo}) 148 | fileinfo.update({"yara_plugins": yara_check.yara_match_from_folder(path_to_file('pe', 'signatures/yara_plugins'), filename, ['antidebug_antivm.yar'])}) 149 | else: 150 | fileinfo.update({"docinfo": macro.get_result(filename)}) 151 | fileinfo.update({"yara_plugins": yara_check.yara_match_from_folder(path_to_file('doc', 'signatures/yara_plugins'), filename)}) 152 | 153 | dt_end = get_datetime_now() 154 | 155 | fileinfo.update({"time": str(dt_end - dt_start)}) 156 | 157 | return fileinfo 158 | -------------------------------------------------------------------------------- /peframe/peframecli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # by Gianni 'guelfoweb' Amato 5 | 6 | import os 7 | import sys 8 | import json 9 | import readline 10 | import argparse 11 | from argparse import RawTextHelpFormatter 12 | 13 | portable = False 14 | for path in sys.path: 15 | if os.sep+'peframe'+os.sep+'peframe' in path: 16 | portable = True 17 | if portable: 18 | import peframe 19 | from modules import autocomplete 20 | from modules import virustotal 21 | from modules import features 22 | else: 23 | from peframe import peframe 24 | from peframe.modules import autocomplete 25 | from peframe.modules import virustotal 26 | from peframe.modules import features 27 | 28 | # TODO 29 | # [ ] get_data_by_offset 30 | 31 | __version__ = peframe.version() 32 | 33 | def header(title): 34 | print ('\n') 35 | print (''.ljust(80, '-')) 36 | print (title) 37 | print (''.ljust(80, '-')) 38 | 39 | def interactive_mode(): 40 | header('Interactive mode (press TAB to show commands)') 41 | help_list = ['?', 'h', 'help', 'ls', 'dir'] 42 | drop_list = ['q!', 'exit', 'quit', 'bye'] 43 | while 1: 44 | user_input = autocomplete.get_result(cmd_list, "[peframe]>") #input ("[peframe]> ") 45 | 46 | if user_input in help_list: 47 | print (json.dumps(cmd_list, sort_keys=True, indent=4)) 48 | elif user_input in drop_list: 49 | print ('goodbye!\n') 50 | break 51 | 52 | # info 53 | elif user_input == 'info': 54 | get_info() 55 | print ('\n') 56 | elif user_input == 'yara_plugins': 57 | yara_plugins_list = [] 58 | for items in result['yara_plugins']: 59 | for item in items.values(): 60 | yara_plugins_list.append(item) 61 | print (json.dumps(yara_plugins_list, sort_keys=True, indent=4)) 62 | elif user_input == 'behavior': 63 | if result['peinfo']: 64 | print (json.dumps(result['peinfo']['behavior'], sort_keys=True, indent=4)) 65 | if result['docinfo']: 66 | print (json.dumps(result['docinfo']['behavior'], sort_keys=True, indent=4)) 67 | elif user_input == 'virustotal': 68 | try: 69 | vt = virustotal.get_result(peframe.load_config(peframe.path_to_file('config-peframe.json', 'config'))['virustotal'], 70 | result['hashes']['md5'], full=True) 71 | if vt['response_code'] == 200: 72 | print (json.dumps(cmd_list_select['virustotal'], sort_keys=True, indent=4)) 73 | print ('\nUse \'back\' to return') 74 | while 1: 75 | user_input_virustotal = autocomplete.get_result(cmd_list_select['virustotal'], "[peframe/virustotal]>") 76 | if user_input_virustotal == 'back': 77 | break 78 | elif user_input_virustotal == 'permalink': 79 | print (vt['results']['permalink']) 80 | elif user_input_virustotal == 'antivirus': 81 | print (json.dumps(vt['results']['scans'], sort_keys=True, indent=4)) 82 | elif user_input_virustotal == 'scan_date': 83 | print (vt['results']['scan_date']) 84 | except: 85 | print ('VT Query error') 86 | 87 | # directories 88 | elif user_input == 'directories': 89 | print (json.dumps(cmd_list_select['directories'], sort_keys=True, indent=4)) 90 | print ('\nUse \'back\' to return') 91 | while 1: 92 | user_input_directories = autocomplete.get_result(cmd_list_select['directories'], "[peframe/directories]>") 93 | if user_input_directories == 'back': 94 | break 95 | elif user_input_directories == 'list': 96 | for item in user_input_directories['directories']: 97 | print (item) 98 | elif user_input_directories == 'import': 99 | print (json.dumps(result['peinfo']['directories']['import'], sort_keys=True, indent=4)) 100 | elif user_input_directories == 'export': 101 | print (json.dumps(result['peinfo']['directories']['export'], sort_keys=True, indent=4)) 102 | elif user_input_directories == 'debug': 103 | print (json.dumps(result['peinfo']['directories']['debug'], sort_keys=True, indent=4)) 104 | elif user_input_directories == 'tls': 105 | print (json.dumps(result['peinfo']['directories']['tls'], sort_keys=True, indent=4)) 106 | elif user_input_directories == 'resources': 107 | print (json.dumps(result['peinfo']['directories']['resources'], sort_keys=True, indent=4)) 108 | elif user_input_directories == 'relocations': 109 | print (json.dumps(result['peinfo']['directories']['relocations'], sort_keys=True, indent=4)) 110 | elif user_input_directories == 'sign': 111 | print (json.dumps(result['peinfo']['directories']['sign'], sort_keys=True, indent=4)) 112 | 113 | # sections 114 | elif user_input == 'sections': 115 | print (json.dumps(cmd_list_select['sections'], sort_keys=True, indent=4)) 116 | print ('\nUse \'back\' to return') 117 | while 1: 118 | user_input_sections = autocomplete.get_result(cmd_list_select['sections'], "[peframe/sections]>") 119 | if user_input_sections == 'back': 120 | break 121 | elif user_input_sections in cmd_list_select['sections']: 122 | for item in result['peinfo']['sections']['details']: 123 | if item['section_name'] == user_input_sections: 124 | print (json.dumps(item, sort_keys=True, indent=4)) 125 | 126 | # features 127 | elif user_input == 'features': 128 | print (json.dumps(cmd_list_select['features'], sort_keys=True, indent=4)) 129 | print ('\nUse \'back\' to return') 130 | while 1: 131 | user_input_features = autocomplete.get_result(cmd_list_select['features'], "[peframe/features]>") 132 | if user_input_features == 'back': 133 | break 134 | elif user_input_features == 'antidbg': 135 | print (json.dumps(result['peinfo']['features']['antidbg'], sort_keys=True, indent=4)) 136 | elif user_input_features == 'antivm': 137 | print (json.dumps(result['peinfo']['features']['antivm'], sort_keys=True, indent=4)) 138 | elif user_input_features == 'mutex': 139 | print (json.dumps(result['peinfo']['features']['mutex'], sort_keys=True, indent=4)) 140 | elif user_input_features == 'packer': 141 | print (json.dumps(result['peinfo']['features']['packer'], sort_keys=True, indent=4)) 142 | elif user_input_features == 'xor': 143 | print (json.dumps(result['peinfo']['features']['xor'], sort_keys=True, indent=4)) 144 | elif user_input_features == 'crypto': 145 | print (json.dumps(result['peinfo']['features']['crypto'], sort_keys=True, indent=4)) 146 | 147 | elif user_input == 'breakpoint': 148 | print (json.dumps(result['peinfo']['breakpoint'], sort_keys=True, indent=4)) 149 | elif user_input == 'hashes': 150 | print (json.dumps(result['hashes'], sort_keys=True, indent=4)) 151 | elif user_input == 'macro': 152 | print (result['docinfo']['macro']) 153 | elif user_input == 'attributes': 154 | print (json.dumps(result['docinfo']['attributes'], sort_keys=True, indent=4)) 155 | elif user_input == 'metadata': 156 | print (json.dumps(result['peinfo']['metadata'], sort_keys=True, indent=4)) 157 | 158 | # Strings 159 | elif user_input == 'strings': 160 | print (json.dumps(cmd_list_select['strings'], sort_keys=True, indent=4)) 161 | print ('\nUse \'back\' to return') 162 | while 1: 163 | user_input_strings = autocomplete.get_result(cmd_list_select['strings'], "[peframe/strings]>") 164 | if user_input_strings == 'back': 165 | break 166 | elif user_input_strings == 'list': 167 | for item in cmd_list_select['strings']: 168 | print (item) 169 | elif user_input_strings in cmd_list_select['strings']: 170 | print (json.dumps(result['strings'][user_input_strings], sort_keys=True, indent=4)) 171 | 172 | def show_config(): 173 | api_config = peframe.files_to_edit()['api_config'] 174 | string_match = peframe.files_to_edit()['string_match'] 175 | yara_plugins = peframe.files_to_edit()['yara_plugins'] 176 | intro = 'Path(s) to configuration file(s):' 177 | message = '\napi_config: '+api_config+'\nstring_match: '+string_match+'\nyara_plugins: '+yara_plugins 178 | return message 179 | 180 | def get_info(): 181 | header('File Information (time: ' + str(result['time']) + ')') 182 | print ("filename".ljust(align, ' '), os.path.basename(result['filename'])) 183 | print ("filetype".ljust(align, ' '), result['filetype'][0:63]) 184 | print ("filesize".ljust(align, ' '), result['filesize']) 185 | print ("hash sha256".ljust(align, ' '), result['hashes']['sha256']) 186 | cmd_list.append('hashes') 187 | 188 | print ("virustotal".ljust(align, ' '), str(result['virustotal']['positives']) +'/'+ str(result['virustotal']['total'])) 189 | cmd_list_select.update({"virustotal": ['permalink', 'antivirus', 'scan_date']}) 190 | 191 | # peinfo 192 | if result['peinfo']: 193 | if hex(result['peinfo']['imagebase']) == '0x400000': 194 | imagebase = hex(result['peinfo']['imagebase']) 195 | else: 196 | imagebase = hex(result['peinfo']['imagebase'])+" *" 197 | print ("imagebase".ljust(align, ' '), imagebase) 198 | print ("entrypoint".ljust(align, ' '), hex(result['peinfo']['entrypoint'])) 199 | print ("imphash".ljust(align, ' '), result['peinfo']['imphash']) 200 | print ("datetime".ljust(align, ' '), result['peinfo']['timestamp']) 201 | print ("dll".ljust(align, ' '), result['peinfo']['dll']) 202 | 203 | # directories 204 | if result['peinfo']['directories']: 205 | directories_list = [k for k,v in result['peinfo']['directories'].items() if v] 206 | directories_list_temp = list(directories_list) 207 | if result['peinfo']['directories']['resources']: 208 | for item in result['peinfo']['directories']['resources']: 209 | if item['executable'] == True: 210 | try: 211 | directories_list_temp.remove('resources') 212 | directories_list_temp.append('resources *') 213 | except: 214 | pass 215 | if directories_list: 216 | print ("directories".ljust(align, ' '), ', '.join(directories_list_temp)) 217 | cmd_list.append('directories') 218 | cmd_list_select.update({"directories": directories_list}) 219 | 220 | # sections 221 | if result['peinfo']['sections']: 222 | section_list = [items['section_name'] for items in result['peinfo']['sections']['details']] 223 | section_list_temp = list(section_list) 224 | for items in result['peinfo']['sections']['details']: 225 | if items['entropy'] > 6: 226 | section_list_temp.remove(items['section_name']) 227 | section_list_temp.append(items['section_name'] + ' *') 228 | if section_list: 229 | print ("sections".ljust(align, ' '), ', '.join(section_list_temp)) 230 | cmd_list.append('sections') 231 | cmd_list_select.update({"sections": section_list}) 232 | 233 | # features 234 | if result['peinfo']['features']: 235 | features_list = [k for k,v in result['peinfo']['features'].items() if v] 236 | if features_list: 237 | print ("features".ljust(align, ' '), ', '.join(features_list)) 238 | cmd_list.append('features') 239 | cmd_list_select.update({"features": features_list}) 240 | 241 | # behavior 242 | if result['peinfo']['behavior']: 243 | cmd_list.append('behavior') 244 | 245 | # metadata 246 | if result['peinfo']['metadata']: 247 | cmd_list.append('metadata') 248 | 249 | # breakpoint 250 | if result['peinfo']['breakpoint']: 251 | cmd_list.append('breakpoint') 252 | 253 | # strings 254 | if result['strings']: 255 | strings_list = [k for k,v in result['strings'].items() if v] 256 | cmd_list.append('strings') 257 | cmd_list_select.update({"strings": strings_list}) 258 | 259 | # docinfo 260 | if result['docinfo']: 261 | if result['docinfo']['macro']: 262 | print ("macro".ljust(align, ' '), True) 263 | cmd_list.append('macro') 264 | if result['docinfo']['behavior']: 265 | cmd_list.append('behavior') 266 | if result['docinfo']['attributes']: 267 | cmd_list.append('attributes') 268 | 269 | if result['yara_plugins']: 270 | cmd_list.append('yara_plugins') 271 | 272 | parser = argparse.ArgumentParser( 273 | prog='peframe', 274 | description='Tool for static malware analysis.', 275 | epilog=show_config(), 276 | formatter_class=RawTextHelpFormatter 277 | ) 278 | 279 | parser.add_argument("file", help="sample to analyze") 280 | parser.add_argument("-v", "--version", action='version', version='%(prog)s '+str(__version__)) 281 | parser.add_argument("-i", "--interactive", help="join in interactive mode", action='store_true', required=False) 282 | parser.add_argument("-x", "--xorsearch", help="search xored string", required=False) 283 | parser.add_argument("-j", "--json", help="export short report in JSON", action='store_true', required=False) 284 | parser.add_argument("-s", "--strings", help="export all strings", action='store_true', required=False) 285 | 286 | args = parser.parse_args() 287 | 288 | filename = args.file 289 | result = peframe.analyze(filename) 290 | 291 | if args.xorsearch: 292 | print (json.dumps(features.get_xor(filename, search_string=str.encode(args.xorsearch)), sort_keys=True, indent=4)) 293 | sys.exit() 294 | 295 | if args.json: 296 | print (json.dumps(result, sort_keys=True, indent=4)) 297 | sys.exit() 298 | 299 | if args.strings: 300 | print ('\n'.join(result['strings']['dump'])) 301 | sys.exit() 302 | 303 | align = 16 304 | cmd_list = ['info', 'strings', 'exit', 'virustotal'] 305 | cmd_list_select = {} 306 | 307 | if args.interactive: 308 | json.dumps(get_info(), sort_keys=True, indent=4) 309 | interactive_mode() 310 | sys.exit() 311 | 312 | 313 | get_info() 314 | 315 | if result['yara_plugins']: 316 | header('Yara Plugins') 317 | for item in result['yara_plugins']: 318 | for k,v in item.items(): 319 | print (v.replace('_', ' ')) 320 | 321 | 322 | if result['docinfo']: 323 | if result['docinfo']['behavior']: 324 | header('Behavior') 325 | for k, v in result['docinfo']['behavior'].items(): 326 | print (k.ljust(align, ' '), v) 327 | 328 | if result['docinfo']['attributes']: 329 | header('Attributes') 330 | for item in result['docinfo']['attributes']: 331 | print (item) 332 | 333 | if result['peinfo']: 334 | if result['peinfo']['behavior']: 335 | header('Behavior') 336 | for item in result['peinfo']['behavior']: 337 | print (item.replace('_', ' ')) 338 | 339 | if result['peinfo']['features']['crypto']: 340 | header('Crypto') 341 | for item in result['peinfo']['features']['crypto']: 342 | print (item.replace('_', ' ')) 343 | 344 | if result['peinfo']['features']['packer']: 345 | header('Packer') 346 | for item in result['peinfo']['features']['packer']: 347 | print (item.replace('_', ' ')) 348 | 349 | if result['peinfo']['features']['xor']: 350 | header('Xor') 351 | for k, v in result['peinfo']['features']['xor'].items(): 352 | print (str(k).ljust(align, ' '), v) 353 | 354 | if result['peinfo']['features']['mutex']: 355 | header('Mutex Api') 356 | for item in result['peinfo']['features']['mutex']: 357 | print (item) 358 | 359 | if result['peinfo']['features']['antidbg']: 360 | header('Anti Debug') 361 | for item in result['peinfo']['features']['antidbg']: 362 | print (item) 363 | 364 | if result['peinfo']['features']['antivm']: 365 | header('Anti VM') 366 | for item in result['peinfo']['features']['antivm']: 367 | print (item) 368 | 369 | if result['peinfo']['sections']: 370 | header('Sections Suspicious') 371 | found = False 372 | for item in result['peinfo']['sections']['details']: 373 | if item['entropy'] > 6: 374 | print (item['section_name'].ljust(align, ' '), str(item['entropy'])[:4]) 375 | found = True 376 | if not found: 377 | print ('For each section the value of entropy is less than 6') 378 | 379 | if result['peinfo']['metadata']: 380 | header('Metadata') 381 | for k, v in result['peinfo']['metadata'].items(): 382 | print (k.ljust(align, ' '), v[0:63]) 383 | 384 | if result['peinfo']['directories']['import']: 385 | header('Import function') 386 | for k, v in result['peinfo']['directories']['import'].items(): 387 | print (k.ljust(align, ' '), len(v)) 388 | 389 | if result['peinfo']['directories']['export']: 390 | header('Export function') 391 | detect = [] 392 | for item in result['peinfo']['directories']['export']: 393 | detect.append(item) 394 | print ("export".ljust(align, ' '), detect) 395 | 396 | if result['peinfo']['directories']['sign']: 397 | header('Signature') 398 | for k, v in result['peinfo']['directories']['sign']['details'].items(): 399 | if k != 'hash': 400 | print (k.ljust(align, ' '), v) 401 | 402 | 403 | if result['peinfo']['breakpoint']: 404 | header('Possibile Breakpoint') 405 | for item in result['peinfo']['breakpoint']: 406 | print (item) 407 | 408 | if result['strings']: 409 | if result['strings']['ip']: 410 | header('Ip Address') 411 | for item in result['strings']['ip']: 412 | print (item) 413 | 414 | if result['strings']['url']: 415 | header('Url') 416 | for item in result['strings']['url']: 417 | print (item) 418 | 419 | if result['strings']['file']: 420 | header('File') 421 | for k, v in result['strings']['file'].items(): 422 | print (k.ljust(align, ' '), v) 423 | 424 | if result['strings']['fuzzing']: 425 | header('Fuzzing') 426 | for k, v in result['strings']['fuzzing'].items(): 427 | print (k) 428 | 429 | sys.exit() -------------------------------------------------------------------------------- /peframe/signatures/stringsmatch.json: -------------------------------------------------------------------------------- 1 | { 2 | "fuzzing": { 3 | "String too long": "[A-Za-z0-9+/]{80,}", 4 | "Possible encoded string": "(\\\\x[abcdef][abcdef|0-9]){3,}", 5 | "Possible connections": ".*(curl|wget).*" 6 | }, 7 | "mutex": [ 8 | "CreateMutexA", 9 | "OpenMutex", 10 | "ReleaseMutex", 11 | "WaitForSingleObject" 12 | ], 13 | "antidbg": [ 14 | "CheckRemoteDebugger", 15 | "DebugActiveProcess", 16 | "FindWindow", 17 | "GetLastError", 18 | "GetWindowThreadProcessId", 19 | "IsDebugged", 20 | "IsDebuggerPresent", 21 | "IsProcessorFeaturePresent", 22 | "NtCreateThreadEx", 23 | "NtGlobalFlags", 24 | "NtSetInformationThread", 25 | "OutputDebugString", 26 | "pbIsPresent", 27 | "Process32First", 28 | "Process32Next", 29 | "RaiseException", 30 | "TerminateProcess", 31 | "ThreadHideFromDebugger", 32 | "UnhandledExceptionFilter", 33 | "ZwQueryInformation" 34 | ], 35 | "breakpoint": [ 36 | "accept", 37 | "AddCredentials", 38 | "bind", 39 | "CertDeleteCertificateFromStore", 40 | "CheckRemoteDebuggerPresent", 41 | "CloseHandle", 42 | "closesocket", 43 | "connect", 44 | "ConnectNamedPipe", 45 | "CopyFile", 46 | "CreateFile", 47 | "CreateMutex", 48 | "CreateProcess", 49 | "CreateToolhelp32Snapshot", 50 | "CreateFileMapping", 51 | "CreateRemoteThread", 52 | "CreateDirectory", 53 | "CreateService", 54 | "CreateThread", 55 | "CryptEncrypt", 56 | "DeleteCriticalSection", 57 | "DeleteFile", 58 | "DeviceIoControl", 59 | "DisconnectNamedPipe", 60 | "DNSQuery", 61 | "EnumProcesses", 62 | "ExitProcess", 63 | "ExitThread", 64 | "FindWindow", 65 | "FindResource", 66 | "FindFirstFile", 67 | "FindNextFile", 68 | "FltRegisterFilter", 69 | "FtpGetFile", 70 | "FtpOpenFile", 71 | "GetCommandLine", 72 | "GetComputerName", 73 | "GetCommandLineA", 74 | "GetCurrentProcess", 75 | "GetThreadContext", 76 | "GetDriveType", 77 | "GetFileSize", 78 | "GetFileAttributes", 79 | "GetHostByAddr", 80 | "GetHostByName", 81 | "GetHostName", 82 | "GetModuleHandle", 83 | "GetModuleFileName", 84 | "GetProcAddress", 85 | "GetStartupInfo", 86 | "GetSystemDirectory", 87 | "GetTempFileName", 88 | "GetTempPath", 89 | "GetTickCount", 90 | "GetUpdateRect", 91 | "GetUpdateRgn", 92 | "GetUserNameA", 93 | "GetUrlCacheEntryInfo", 94 | "GetVersionEx", 95 | "GetWindowsDirectory", 96 | "GetWindowThreadProcessId", 97 | "HeapAlloc", 98 | "HttpSendRequest", 99 | "HttpQueryInfo", 100 | "IcmpSendEcho", 101 | "IsBadReadPtr", 102 | "IsBadWritePtr", 103 | "IsDebuggerPresent", 104 | "InitializeCriticalSectionAndSpinCount", 105 | "InternetCloseHandle", 106 | "InternetConnect", 107 | "InternetCrackUrl", 108 | "InternetQueryDataAvailable", 109 | "InternetGetConnectedState", 110 | "InternetOpen", 111 | "InternetQueryDataAvailable", 112 | "InternetQueryOption", 113 | "InternetReadFile", 114 | "InternetWriteFile", 115 | "LdrLoadDll", 116 | "LoadLibrary", 117 | "LoadLibraryA", 118 | "LockResource", 119 | "listen", 120 | "lstrcmp", 121 | "MapViewOfFile", 122 | "MessageBox", 123 | "OutputDebugString", 124 | "OpenFileMapping", 125 | "OpenMutex", 126 | "OpenProcess", 127 | "Process32First", 128 | "Process32Next", 129 | "recv", 130 | "ReadFile", 131 | "ReadProcessMemory", 132 | "RegCloseKey", 133 | "RegCreateKey", 134 | "RegDeleteKey", 135 | "RegDeleteValue", 136 | "RegEnumKey", 137 | "RegOpenKey", 138 | "ReleaseMutex", 139 | "RemoveDirectory", 140 | "send", 141 | "sendto", 142 | "SetFilePointer", 143 | "SetKeyboardState", 144 | "SetWindowsHook", 145 | "ShellExecute", 146 | "Sleep", 147 | "socket", 148 | "StartService", 149 | "TerminateProcess", 150 | "UnhandledExceptionFilter", 151 | "URLDownload", 152 | "VirtualAlloc", 153 | "VirtualFree", 154 | "VirtualProtect", 155 | "WaitForSingleObject", 156 | "WinExec", 157 | "WriteProcessMemory", 158 | "WriteFile", 159 | "WSASend", 160 | "WSASocket", 161 | "WSAStartup", 162 | "ZwQueryInformation" 163 | ], 164 | "filetype": { 165 | "Video":[".3gp", ".asf", ".asx", ".avi", ".flv", ".mp4", ".mpg", ".mpeg", ".mov", ".wmv"], 166 | "Compressed":[".7z"], 167 | "Package":[".apk"], 168 | "Web Page":[".asp", ".aspx", ".htm", ".html", ".php", ".jsp"], 169 | "Backup":[".bak", ".old"], 170 | "Binary":[".bin"], 171 | "Image":[".bmp", ".gif", ".jpg", ".jepg", ".png", ".psd", ".tif"], 172 | "Cabinet":[".cab"], 173 | "Data":[".dat"], 174 | "Database":[".db", ".sqlite"], 175 | "Word":[".doc", ".docx"], 176 | "Library":[".dll"], 177 | "Autocad":[".dwg"], 178 | "Executable": [".exe", ".src", ".so"], 179 | "Email":[".eml", ".pst", ".msg"], 180 | "FTP Config":[".ftp"], 181 | "Compressed":[".gz", ".rar", ".tgz", ".zip"], 182 | "Disc Image":[".iso"], 183 | "Log":[".log"], 184 | "Archive Java":[".jar"], 185 | "Linker File":[".lnk"], 186 | "Audio":[".mp3", ".wav", ".wma"], 187 | "Installer":[".msi"], 188 | "Object":[".oca", ".ocx"], 189 | "Autogen":[".olb"], 190 | "Registry":[".reg"], 191 | "Portable":[".pdf"], 192 | "Presentation":[".ppt", ".pptx", ".pps"], 193 | "Document":[".pub"], 194 | "Text":[".txt", ".rtf"], 195 | "Query DB":[".sql"], 196 | "Adobe Flash":[".swf"], 197 | "Temporary":[".tmp"], 198 | "Excel":[".xls", ".xlsx"], 199 | "XML":[".xml"] 200 | } 201 | } 202 | 203 | -------------------------------------------------------------------------------- /peframe/signatures/userdb.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guelfoweb/peframe/70683b6db71c7a1c44c2d8f817822a0815fc6137/peframe/signatures/userdb.txt -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/JJencode.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | */ 4 | rule jjEncode 5 | { 6 | meta: 7 | description = "jjencode detection" 8 | ref = "http://blog.xanda.org/2015/06/10/yara-rule-for-jjencode/" 9 | author = "adnan.shukor@gmail.com" 10 | date = "10-June-2015" 11 | version = "1" 12 | impact = 3 13 | hide = false 14 | strings: 15 | $jjencode = /(\$|[\S]+)=~\[\]\;(\$|[\S]+)\=\{[\_]{3}\:[\+]{2}(\$|[\S]+)\,[\$]{4}\:\(\!\[\]\+["]{2}\)[\S]+/ fullword 16 | condition: 17 | $jjencode 18 | } 19 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Javascript_exploit_and_obfuscation.yar: -------------------------------------------------------------------------------- 1 | rule generic_javascript_obfuscation 2 | { 3 | meta: 4 | author = "Josh Berry" 5 | date = "2016-06-26" 6 | description = "JavaScript Obfuscation Detection" 7 | sample_filetype = "js-html" 8 | strings: 9 | $string0 = /eval\(([\s]+)?(unescape|atob)\(/ nocase 10 | $string1 = /var([\s]+)?([a-zA-Z_$])+([a-zA-Z0-9_$]+)?([\s]+)?=([\s]+)?\[([\s]+)?\"\\x[0-9a-fA-F]+/ nocase 11 | $string2 = /var([\s]+)?([a-zA-Z_$])+([a-zA-Z0-9_$]+)?([\s]+)?=([\s]+)?eval;/ 12 | condition: 13 | any of them 14 | } 15 | 16 | rule possible_includes_base64_packed_functions 17 | { 18 | meta: 19 | impact = 5 20 | hide = true 21 | desc = "Detects possible includes and packed functions" 22 | strings: 23 | $f = /(atob|btoa|;base64|base64,)/ nocase 24 | //$ff = /(?:[A-Za-z0-9]{4}){2,}(?:[A-Za-z0-9]{2}[AEIMQUYcgkosw048]=|[A-Za-z0-9][AQgw]==)/ nocase 25 | $fff = /([A-Za-z0-9]{4})*([A-Za-z0-9]{2}==|[A-Za-z0-9]{3}=|[A-Za-z0-9]{4})/ 26 | condition: 27 | $f and $fff 28 | } 29 | 30 | 31 | rule src_ptheft_command { 32 | meta: 33 | description = "Auto-generated rule - file command.js" 34 | author = "Pasquale Stirparo" 35 | reference = "not set" 36 | date = "2015-10-08" 37 | hash = "49c0e5400068924ff87729d9e1fece19acbfbd628d085f8df47b21519051b7f3" 38 | strings: 39 | $s0 = "var lilogo = 'http://content.linkedin.com/etc/designs/linkedin/katy/global/clientlibs/img/logo.png';" fullword wide ascii /* score: '38.00' */ 40 | $s1 = "dark=document.getElementById('darkenScreenObject'); " fullword wide ascii /* score: '21.00' */ 41 | $s2 = "beef.execute(function() {" fullword wide ascii /* score: '21.00' */ 42 | $s3 = "var logo = 'http://www.youtube.com/yt/brand/media/image/yt-brand-standard-logo-630px.png';" fullword wide ascii /* score: '32.42' */ 43 | $s4 = "description.text('Enter your Apple ID e-mail address and password');" fullword wide ascii /* score: '28.00' */ 44 | $s5 = "sneakydiv.innerHTML= '
';" fullword wide ascii /* score: '24.00' */ 48 | $s9 = "var title = 'Session Timed Out \"YouTube\"';" fullword wide ascii /* score: '24.00' */ 49 | $s10 = "var title = 'Session Timed Out \"Yammer\"';" fullword wide ascii /* score: '24.00' */ 50 | $s11 = "var logobox = 'style=\"border:4px #84ACDD solid;border-radius:7px;height:45px;width:45px;background:#ffffff\"';" fullword wide ascii /* score: '21.00' */ 51 | $s12 = "sneakydiv.innerHTML= '

Your session has timed out!

For" wide ascii /* score: '23.00' */ 52 | $s13 = "inner.append(title, description, user,password);" fullword wide ascii /* score: '23.00' */ 53 | $s14 = "sneakydiv.innerHTML= '

" 23 | $c_macro = "w:macrosPresent=\"yes\"" 24 | $c_binary = "0" 26 | $c_1_line = "1" 27 | condition: 28 | all of ($c*) 29 | } 30 | /* 31 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 32 | 33 | */ 34 | /* 35 | Yara Rule Set 36 | Author: Florian Roth 37 | Date: 2015-12-02 38 | Identifier: Phishing Gina Harrowell Dez 2015 39 | */ 40 | 41 | rule PHISH_02Dez2015_dropped_p0o6543f { 42 | meta: 43 | description = "Phishing Wave - file p0o6543f.exe" 44 | author = "Florian Roth" 45 | reference = "http://myonlinesecurity.co.uk/purchase-order-124658-gina-harrowell-clinimed-limited-word-doc-or-excel-xls-spreadsheet-malware/" 46 | date = "2015-12-02" 47 | hash = "db788d6d3a8ed1a6dc9626852587f475e7671e12fa9c9faa73b7277886f1e210" 48 | strings: 49 | $s1 = "netsh.exe" fullword wide 50 | $s2 = "routemon.exe" fullword wide 51 | $s3 = "script=" fullword wide /* Goodware String - occured 4 times */ 52 | $s4 = "disconnect" fullword wide /* Goodware String - occured 14 times */ 53 | $s5 = "GetClusterResourceTypeKey" fullword ascii /* Goodware String - occured 17 times */ 54 | $s6 = "QueryInformationJobObject" fullword ascii /* Goodware String - occured 34 times */ 55 | $s7 = "interface" fullword wide /* Goodware String - occured 52 times */ 56 | $s8 = "connect" fullword wide /* Goodware String - occured 61 times */ 57 | $s9 = "FreeConsole" fullword ascii /* Goodware String - occured 91 times */ 58 | condition: 59 | uint16(0) == 0x5a4d and filesize < 250KB and all of them 60 | } 61 | 62 | rule PHISH_02Dez2015_attach_P_ORD_C_10156_124658 { 63 | meta: 64 | description = "Phishing Wave - file P-ORD-C-10156-124658.xls" 65 | author = "Florian Roth" 66 | reference = "http://myonlinesecurity.co.uk/purchase-order-124658-gina-harrowell-clinimed-limited-word-doc-or-excel-xls-spreadsheet-malware/" 67 | date = "2015-12-02" 68 | hash = "bc252ede5302240c2fef8bc0291ad5a227906b4e70929a737792e935a5fee209" 69 | strings: 70 | $s1 = "Execute" ascii 71 | $s2 = "Process WriteParameterFiles" fullword ascii 72 | $s3 = "WScript.Shell" fullword ascii 73 | $s4 = "STOCKMASTER" fullword ascii 74 | $s5 = "InsertEmailFax" ascii 75 | condition: 76 | uint16(0) == 0xcfd0 and filesize < 200KB and all of them 77 | } 78 | 79 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_Hidden_PE_file.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | 6 | rule Contains_hidden_PE_File_inside_a_sequence_of_numbers : maldoc 7 | { 8 | meta: 9 | author = "Martin Willing (https://evild3ad.com)" 10 | description = "Detect a hidden PE file inside a sequence of numbers (comma separated)" 11 | reference = "http://blog.didierstevens.com/2016/01/07/blackenergy-xls-dropper/" 12 | reference = "http://www.welivesecurity.com/2016/01/04/blackenergy-trojan-strikes-again-attacks-ukrainian-electric-power-industry/" 13 | date = "2016-01-09" 14 | filetype = "decompressed VBA macro code" 15 | 16 | strings: 17 | $a = "= Array(" // Array of bytes 18 | $b = "77, 90," // MZ 19 | $c = "33, 84, 104, 105, 115, 32, 112, 114, 111, 103, 114, 97, 109, 32, 99, 97, 110, 110, 111, 116, 32, 98, 101, 32, 114, 117, 110, 32, 105, 110, 32, 68, 79, 83, 32, 109, 111, 100, 101, 46," // !This program cannot be run in DOS mode. 20 | 21 | condition: 22 | all of them 23 | } 24 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_MIME_ActiveMime_b64.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | 6 | rule MIME_MSO_ActiveMime_base64 : maldoc 7 | { 8 | meta: 9 | author = "Martin Willing (https://evild3ad.com)" 10 | description = "Detect MIME MSO Base64 encoded ActiveMime file" 11 | date = "2016-02-28" 12 | filetype = "Office documents" 13 | 14 | strings: 15 | $mime = "MIME-Version:" 16 | $base64 = "Content-Transfer-Encoding: base64" 17 | $mso = "Content-Type: application/x-mso" 18 | $activemime = /Q(\x0D\x0A|)W(\x0D\x0A|)N(\x0D\x0A|)0(\x0D\x0A|)a(\x0D\x0A|)X(\x0D\x0A|)Z(\x0D\x0A|)l(\x0D\x0A|)T(\x0D\x0A|)W/ 19 | 20 | condition: 21 | $mime at 0 and $base64 and $mso and $activemime 22 | } 23 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_PowerPointMouse.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | rule ppaction { 6 | 7 | meta: 8 | ref = "https://blog.nviso.be/2017/06/07/malicious-powerpoint-documents-abusing-mouse-over-actions/amp/" 9 | Description = "Malicious PowerPoint Documents Abusing Mouse Over Actions" 10 | hash = "68fa24c0e00ff5bc1e90c96e1643d620d0c4cda80d9e3ebeb5455d734dc29e7" 11 | 12 | strings: 13 | $a = "ppaction" nocase 14 | condition: 15 | $a 16 | } 17 | 18 | rule powershell { 19 | strings: 20 | $a = "powershell" nocase 21 | condition: 22 | $a 23 | } 24 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_Suspicious_OLE_target.yar: -------------------------------------------------------------------------------- 1 | rule Maldoc_Suspicious_OLE_target { 2 | meta: 3 | description = "Detects maldoc With Tartgeting Suspicuios OLE" 4 | author = "Donguk Seo" 5 | reference = "https://blog.malwarebytes.com/threat-analysis/2017/10/decoy-microsoft-word-document-delivers-malware-through-rat/" 6 | filetype = "Office documents" 7 | date = "2018-06-13" 8 | strings: 9 | $env1 = /oleObject".*Target=.*.http.*.doc"/ 10 | $env2 = /oleObject".*Target=.*.http.*.ppt"/ 11 | $env3 = /oleObject".*Target=.*.http.*.xlx"/ 12 | condition: 13 | any of them 14 | } 15 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_UserForm.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | 6 | 7 | rule Contains_UserForm_Object 8 | { 9 | meta: 10 | author = "Martin Willing (https://evild3ad.com)" 11 | description = "Detect UserForm object in MS Office document" 12 | reference = "https://msdn.microsoft.com/en-us/library/office/gg264663.aspx" 13 | date = "2016-03-05" 14 | filetype = "Office documents" 15 | 16 | strings: 17 | $a = "UserForm1" 18 | $b = "TextBox1" 19 | $c = "Microsoft Forms 2.0" 20 | 21 | condition: 22 | all of them 23 | } 24 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_VBA_macro_code.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | 6 | 7 | rule Contains_VBA_macro_code 8 | { 9 | meta: 10 | author = "evild3ad" 11 | description = "Detect a MS Office document with embedded VBA macro code" 12 | date = "2016-01-09" 13 | filetype = "Office documents" 14 | 15 | strings: 16 | $officemagic = { D0 CF 11 E0 A1 B1 1A E1 } 17 | $zipmagic = "PK" 18 | 19 | $97str1 = "_VBA_PROJECT_CUR" wide 20 | $97str2 = "VBAProject" 21 | $97str3 = { 41 74 74 72 69 62 75 74 00 65 20 56 42 5F } // Attribute VB_ 22 | 23 | $xmlstr1 = "vbaProject.bin" 24 | $xmlstr2 = "vbaData.xml" 25 | 26 | condition: 27 | ($officemagic at 0 and any of ($97str*)) or ($zipmagic at 0 and any of ($xmlstr*)) 28 | } 29 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_Word_2007_XML_Flat_OPC.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | */ 4 | 5 | rule Word_2007_XML_Flat_OPC : maldoc 6 | { 7 | meta: 8 | author = "Martin Willing (https://evild3ad.com)" 9 | description = "Detect Word 2007 XML Document in the Flat OPC format w/ embedded Microsoft Office 2007+ document" 10 | date = "2018-04-29" 11 | reference = "https://blogs.msdn.microsoft.com/ericwhite/2008/09/29/the-flat-opc-format/" 12 | hash1 = "060c036ce059b465a05c42420efa07bf" 13 | hash2 = "2af21d35bb909a0ac081c2399d0939b1" 14 | hash3 = "72ffa688c228b0b833e69547885650fe" 15 | filetype = "Office documents" 16 | 17 | strings: 18 | $xml = "" // XML processing instruction => A Windows OS with Microsoft Office installed will recognize the file as a MS Word document. 20 | $OPC = " Microsoft Office 2007 XML Schema Reference 22 | $binaryData = "0M8R4KGxGuE" // Binary Part (Microsoft Office 2007+ document encoded in a Base64 string, broken into lines of 76 characters) => D0 CF 11 E0 A1 B1 1A E1 (vbaProject.bin / DOCM) 23 | $docm = "pkg:name=\"/word/vbaProject.bin\"" // Binary Object 24 | 25 | condition: 26 | $xml at 0 and $WordML and $OPC and $xmlns and $binaryData and $docm 27 | } -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_hancitor_dropper: -------------------------------------------------------------------------------- 1 | rule hancitor_dropper : vb_win32api 2 | { 3 | meta: 4 | author = "Jeff White - jwhite@paloaltonetworks @noottrak" 5 | date = "18AUG2016" 6 | hash1 = "03aef51be133425a0e5978ab2529890854ecf1b98a7cf8289c142a62de7acd1a" 7 | hash2 = "4b3912077ef47515b2b74bc1f39de44ddd683a3a79f45c93777e49245f0e9848" 8 | hash3 = "a78972ac6dee8c7292ae06783cfa1f918bacfe956595d30a0a8d99858ce94b5a" 9 | 10 | strings: 11 | $api_01 = { 00 56 69 72 74 75 61 6C 41 6C 6C 6F 63 00 } // VirtualAlloc 12 | $api_02 = { 00 52 74 6C 4D 6F 76 65 4D 65 6D 6F 72 79 00 } // RtlMoveMemory 13 | $api_04 = { 00 43 61 6C 6C 57 69 6E 64 6F 77 50 72 6F 63 41 00 } // CallWindowProcAi 14 | $magic = { 50 4F 4C 41 } // POLA 15 | 16 | condition: 17 | uint32be(0) == 0xD0CF11E0 and all of ($api_*) and $magic 18 | } 19 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/Maldoc_malrtf_ole2link.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | rule malrtf_ole2link : exploit 6 | { 7 | meta: 8 | author = "@h3x2b " 9 | description = "Detect weaponized RTF documents with OLE2Link exploit" 10 | 11 | strings: 12 | //normal rtf beginning 13 | $rtf_format_00 = "{\\rtf1" 14 | //malformed rtf can have for example {\\rtA1 15 | $rtf_format_01 = "{\\rt" 16 | 17 | //having objdata structure 18 | $rtf_olelink_01 = "\\objdata" nocase 19 | 20 | //hex encoded OLE2Link 21 | $rtf_olelink_02 = "4f4c45324c696e6b" nocase 22 | 23 | //hex encoded docfile magic - doc file albilae 24 | $rtf_olelink_03 = "d0cf11e0a1b11ae1" nocase 25 | 26 | //hex encoded "http://" 27 | $rtf_payload_01 = "68007400740070003a002f002f00" nocase 28 | 29 | //hex encoded "https://" 30 | $rtf_payload_02 = "680074007400700073003a002f002f00" nocase 31 | 32 | //hex encoded "ftp://" 33 | $rtf_payload_03 = "6600740070003a002f002f00" nocase 34 | 35 | 36 | condition: 37 | //new_file and 38 | any of ($rtf_format_*) 39 | and all of ($rtf_olelink_*) 40 | and any of ($rtf_payload_*) 41 | } 42 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/maldoc_somerules.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | 6 | rule maldoc_API_hashing : maldoc 7 | { 8 | meta: 9 | author = "Didier Stevens (https://DidierStevens.com)" 10 | strings: 11 | $a1 = {AC 84 C0 74 07 C1 CF 0D 01 C7 EB F4 81 FF} 12 | $a2 = {AC 84 C0 74 07 C1 CF 07 01 C7 EB F4 81 FF} 13 | condition: 14 | any of them 15 | } 16 | 17 | // 20150909 - Issue #39 - Commented because of High FP rate 18 | /* 19 | rule maldoc_function_prolog_signature : maldoc 20 | { 21 | meta: 22 | author = "Didier Stevens (https://DidierStevens.com)" 23 | strings: 24 | $a1 = {55 8B EC 81 EC} 25 | $a2 = {55 8B EC 83 C4} 26 | $a3 = {55 8B EC E8} 27 | $a4 = {55 8B EC E9} 28 | $a5 = {55 8B EC EB} 29 | condition: 30 | any of them 31 | } 32 | */ 33 | 34 | // 20150909 - Issue #39 - Commented because of High FP rate 35 | /* 36 | rule maldoc_structured_exception_handling : maldoc 37 | { 38 | meta: 39 | author = "Didier Stevens (https://DidierStevens.com)" 40 | strings: 41 | $a1 = {64 8B (05|0D|15|1D|25|2D|35|3D) 00 00 00 00} 42 | $a2 = {64 A1 00 00 00 00} 43 | condition: 44 | any of them 45 | } 46 | */ 47 | 48 | rule maldoc_indirect_function_call_1 : maldoc 49 | { 50 | meta: 51 | author = "Didier Stevens (https://DidierStevens.com)" 52 | strings: 53 | $a = {FF 75 ?? FF 55 ??} 54 | condition: 55 | for any i in (1..#a): (uint8(@a[i] + 2) == uint8(@a[i] + 5)) 56 | } 57 | 58 | rule maldoc_indirect_function_call_2 : maldoc 59 | { 60 | meta: 61 | author = "Didier Stevens (https://DidierStevens.com)" 62 | strings: 63 | $a = {FF B5 ?? ?? ?? ?? FF 95 ?? ?? ?? ??} 64 | condition: 65 | for any i in (1..#a): ((uint8(@a[i] + 2) == uint8(@a[i] + 8)) and (uint8(@a[i] + 3) == uint8(@a[i] + 9)) and (uint8(@a[i] + 4) == uint8(@a[i] + 10)) and (uint8(@a[i] + 5) == uint8(@a[i] + 11))) 66 | } 67 | 68 | rule maldoc_indirect_function_call_3 : maldoc 69 | { 70 | meta: 71 | author = "Didier Stevens (https://DidierStevens.com)" 72 | strings: 73 | $a = {FF B7 ?? ?? ?? ?? FF 57 ??} 74 | condition: 75 | $a 76 | } 77 | 78 | rule maldoc_find_kernel32_base_method_1 : maldoc 79 | { 80 | meta: 81 | author = "Didier Stevens (https://DidierStevens.com)" 82 | strings: 83 | $a1 = {64 8B (05|0D|15|1D|25|2D|35|3D) 30 00 00 00} 84 | $a2 = {64 A1 30 00 00 00} 85 | condition: 86 | any of them 87 | } 88 | 89 | rule maldoc_find_kernel32_base_method_2 : maldoc 90 | { 91 | meta: 92 | author = "Didier Stevens (https://DidierStevens.com)" 93 | strings: 94 | $a = {31 ?? ?? 30 64 8B ??} 95 | condition: 96 | for any i in (1..#a): ((uint8(@a[i] + 1) >= 0xC0) and (((uint8(@a[i] + 1) & 0x38) >> 3) == (uint8(@a[i] + 1) & 0x07)) and ((uint8(@a[i] + 2) & 0xF8) == 0xA0) and (uint8(@a[i] + 6) <= 0x3F) and (((uint8(@a[i] + 6) & 0x38) >> 3) != (uint8(@a[i] + 6) & 0x07))) 97 | } 98 | 99 | rule maldoc_find_kernel32_base_method_3 : maldoc 100 | { 101 | meta: 102 | author = "Didier Stevens (https://DidierStevens.com)" 103 | strings: 104 | $a = {68 30 00 00 00 (58|59|5A|5B|5C|5D|5E|5F) 64 8B ??} 105 | condition: 106 | for any i in (1..#a): (((uint8(@a[i] + 5) & 0x07) == (uint8(@a[i] + 8) & 0x07)) and (uint8(@a[i] + 8) <= 0x3F) and (((uint8(@a[i] + 8) & 0x38) >> 3) != (uint8(@a[i] + 8) & 0x07))) 107 | } 108 | 109 | rule maldoc_getEIP_method_1 : maldoc 110 | { 111 | meta: 112 | author = "Didier Stevens (https://DidierStevens.com)" 113 | strings: 114 | $a = {E8 00 00 00 00 (58|59|5A|5B|5C|5D|5E|5F)} 115 | condition: 116 | $a 117 | } 118 | 119 | rule maldoc_getEIP_method_4 : maldoc 120 | { 121 | meta: 122 | author = "Didier Stevens (https://DidierStevens.com)" 123 | strings: 124 | $a1 = {D9 EE D9 74 24 F4 (58|59|5A|5B|5C|5D|5E|5F)} 125 | $a2 = {D9 EE 9B D9 74 24 F4 (58|59|5A|5B|5C|5D|5E|5F)} 126 | condition: 127 | any of them 128 | } 129 | 130 | // 20150909 - Issue #39 - Commented because of High FP rate 131 | /* 132 | rule maldoc_suspicious_strings : maldoc 133 | { 134 | meta: 135 | author = "Didier Stevens (https://DidierStevens.com)" 136 | strings: 137 | $a01 = "CloseHandle" 138 | $a02 = "CreateFile" 139 | $a03 = "GetProcAddr" 140 | $a04 = "GetSystemDirectory" 141 | $a05 = "GetTempPath" 142 | $a06 = "GetWindowsDirectory" 143 | $a07 = "IsBadReadPtr" 144 | $a08 = "IsBadWritePtr" 145 | $a09 = "LoadLibrary" 146 | $a10 = "ReadFile" 147 | $a11 = "SetFilePointer" 148 | $a12 = "ShellExecute" 149 | $a13 = "UrlDownloadToFile" 150 | $a14 = "VirtualAlloc" 151 | $a15 = "WinExec" 152 | $a16 = "WriteFile" 153 | condition: 154 | any of them 155 | } 156 | */ 157 | 158 | rule mwi_document: exploitdoc maldoc 159 | { 160 | meta: 161 | description = "MWI generated document" 162 | author = "@Ydklijnsma" 163 | source = "http://blog.0x3a.com/post/117760824504/analysis-of-a-microsoft-word-intruder-sample" 164 | 165 | strings: 166 | $field_creation_tag = "{\\field{\\*\\fldinst { INCLUDEPICTURE" 167 | $mwistat_url = ".php?id=" 168 | $field_closing_tag = "\\\\* MERGEFORMAT \\\\d}}{\\fldrslt}}" 169 | 170 | condition: 171 | all of them 172 | } 173 | 174 | rule macrocheck : maldoc 175 | { 176 | meta: 177 | Author = "Fireeye Labs" 178 | Date = "2014/11/30" 179 | Description = "Identify office documents with the MACROCHECK credential stealer in them. It can be run against .doc files or VBA macros extraced from .docx files (vbaProject.bin files)." 180 | Reference = "https://www.fireeye.com/blog/threat-research/2014/11/fin4_stealing_insid.html" 181 | 182 | strings: 183 | $PARAMpword = "pword=" ascii wide 184 | $PARAMmsg = "msg=" ascii wide 185 | $PARAMuname = "uname=" ascii 186 | $userform = "UserForm" ascii wide 187 | $userloginform = "UserLoginForm" ascii wide 188 | $invalid = "Invalid username or password" ascii wide 189 | $up1 = "uploadPOST" ascii wide 190 | $up2 = "postUpload" ascii wide 191 | 192 | condition: 193 | all of ($PARAM*) or (($invalid or $userloginform or $userform) and ($up1 or $up2)) 194 | } 195 | rule office_document_vba : maldoc 196 | { 197 | meta: 198 | description = "Office document with embedded VBA" 199 | author = "Jean-Philippe Teissier / @Jipe_" 200 | date = "2013-12-17" 201 | reference = "https://github.com/jipegit/" 202 | 203 | strings: 204 | $officemagic = { D0 CF 11 E0 A1 B1 1A E1 } 205 | $zipmagic = "PK" 206 | 207 | $97str1 = "_VBA_PROJECT_CUR" wide 208 | $97str2 = "VBAProject" 209 | $97str3 = { 41 74 74 72 69 62 75 74 00 65 20 56 42 5F } 210 | 211 | $xmlstr1 = "vbaProject.bin" 212 | $xmlstr2 = "vbaData.xml" 213 | 214 | condition: 215 | ($officemagic at 0 and any of ($97str*)) or ($zipmagic at 0 and any of ($xmlstr*)) 216 | } 217 | 218 | rule Office_AutoOpen_Macro : maldoc { 219 | meta: 220 | description = "Detects an Microsoft Office file that contains the AutoOpen Macro function" 221 | author = "Florian Roth" 222 | date = "2015-05-28" 223 | score = 60 224 | hash1 = "4d00695d5011427efc33c9722c61ced2" 225 | hash2 = "63f6b20cb39630b13c14823874bd3743" 226 | hash3 = "66e67c2d84af85a569a04042141164e6" 227 | hash4 = "a3035716fe9173703941876c2bde9d98" 228 | hash5 = "7c06cab49b9332962625b16f15708345" 229 | hash6 = "bfc30332b7b91572bfe712b656ea8a0c" 230 | hash7 = "25285b8fe2c41bd54079c92c1b761381" 231 | strings: 232 | $s1 = "AutoOpen" ascii fullword 233 | $s2 = "Macros" wide fullword 234 | condition: 235 | uint32be(0) == 0xd0cf11e0 and all of ($s*) and filesize < 300000 236 | } 237 | 238 | rule Embedded_EXE_Cloaking : maldoc { 239 | meta: 240 | description = "Detects an embedded executable in a non-executable file" 241 | author = "Florian Roth" 242 | date = "2015/02/27" 243 | score = 80 244 | strings: 245 | $noex_png = { 89 50 4E 47 } 246 | $noex_pdf = { 25 50 44 46 } 247 | $noex_rtf = { 7B 5C 72 74 66 31 } 248 | $noex_jpg = { FF D8 FF E0 } 249 | $noex_gif = { 47 49 46 38 } 250 | $mz = { 4D 5A } 251 | $a1 = "This program cannot be run in DOS mode" 252 | $a2 = "This program must be run under Win32" 253 | condition: 254 | ( 255 | ( $noex_png at 0 ) or 256 | ( $noex_pdf at 0 ) or 257 | ( $noex_rtf at 0 ) or 258 | ( $noex_jpg at 0 ) or 259 | ( $noex_gif at 0 ) 260 | ) 261 | and 262 | for any i in (1..#mz): ( @a1 < ( @mz[i] + 200 ) or @a2 < ( @mz[i] + 200 ) ) 263 | } 264 | 265 | // This rule have beed improved by Javier Rascon 266 | rule RTF_Shellcode : maldoc 267 | { 268 | meta: 269 | 270 | author = "RSA-IR – Jared Greenhill" 271 | date = "01/21/13" 272 | description = "identifies RTF's with potential shellcode" 273 | filetype = "RTF" 274 | 275 | strings: 276 | $rtfmagic={7B 5C 72 74 66} 277 | /* $scregex=/[39 30]{2,20}/ */ 278 | $scregex=/(90){2,20}/ 279 | 280 | condition: 281 | 282 | ($rtfmagic at 0) and ($scregex) 283 | } 284 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/doc/pdf/Maldoc_PDF.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | 4 | */ 5 | 6 | rule malicious_author : PDF raw 7 | { 8 | meta: 9 | author = "Glenn Edwards (@hiddenillusion)" 10 | version = "0.1" 11 | weight = 5 12 | 13 | strings: 14 | $magic = { 25 50 44 46 } 15 | 16 | $reg0 = /Creator.?\(yen vaw\)/ 17 | $reg1 = /Title.?\(who cis\)/ 18 | $reg2 = /Author.?\(ser pes\)/ 19 | condition: 20 | $magic in (0..1024) and all of ($reg*) 21 | } 22 | 23 | rule suspicious_version : PDF raw 24 | { 25 | meta: 26 | author = "Glenn Edwards (@hiddenillusion)" 27 | version = "0.1" 28 | weight = 3 29 | 30 | strings: 31 | $magic = { 25 50 44 46 } 32 | $ver = /%PDF-1.\d{1}/ 33 | condition: 34 | $magic in (0..1024) and not $ver 35 | } 36 | 37 | rule suspicious_creation : PDF raw 38 | { 39 | meta: 40 | author = "Glenn Edwards (@hiddenillusion)" 41 | version = "0.1" 42 | weight = 2 43 | 44 | strings: 45 | $magic = { 25 50 44 46 } 46 | $header = /%PDF-1\.(3|4|6)/ 47 | 48 | $create0 = /CreationDate \(D:20101015142358\)/ 49 | $create1 = /CreationDate \(2008312053854\)/ 50 | condition: 51 | $magic in (0..1024) and $header and 1 of ($create*) 52 | } 53 | 54 | rule multiple_filtering : PDF raw 55 | { 56 | meta: 57 | author = "Glenn Edwards (@hiddenillusion)" 58 | version = "0.2" 59 | weight = 3 60 | 61 | strings: 62 | $magic = { 25 50 44 46 } 63 | $attrib = /\/Filter.*(\/ASCIIHexDecode\W+|\/LZWDecode\W+|\/ASCII85Decode\W+|\/FlateDecode\W+|\/RunLengthDecode){2}/ 64 | // left out: /CCITTFaxDecode, JBIG2Decode, DCTDecode, JPXDecode, Crypt 65 | 66 | condition: 67 | $magic in (0..1024) and $attrib 68 | } 69 | 70 | rule suspicious_title : PDF raw 71 | { 72 | meta: 73 | author = "Glenn Edwards (@hiddenillusion)" 74 | version = "0.1" 75 | weight = 4 76 | 77 | strings: 78 | $magic = { 25 50 44 46 } 79 | $header = /%PDF-1\.(3|4|6)/ 80 | 81 | $title0 = "who cis" 82 | $title1 = "P66N7FF" 83 | $title2 = "Fohcirya" 84 | condition: 85 | $magic in (0..1024) and $header and 1 of ($title*) 86 | } 87 | 88 | rule suspicious_author : PDF raw 89 | { 90 | meta: 91 | author = "Glenn Edwards (@hiddenillusion)" 92 | version = "0.1" 93 | weight = 4 94 | 95 | strings: 96 | $magic = { 25 50 44 46 } 97 | $header = /%PDF-1\.(3|4|6)/ 98 | 99 | $author0 = "Ubzg1QUbzuzgUbRjvcUb14RjUb1" 100 | $author1 = "ser pes" 101 | $author2 = "Miekiemoes" 102 | $author3 = "Nsarkolke" 103 | condition: 104 | $magic in (0..1024) and $header and 1 of ($author*) 105 | } 106 | 107 | rule suspicious_producer : PDF raw 108 | { 109 | meta: 110 | author = "Glenn Edwards (@hiddenillusion)" 111 | version = "0.1" 112 | weight = 2 113 | 114 | strings: 115 | $magic = { 25 50 44 46 } 116 | $header = /%PDF-1\.(3|4|6)/ 117 | 118 | $producer0 = /Producer \(Scribus PDF Library/ 119 | $producer1 = "Notepad" 120 | condition: 121 | $magic in (0..1024) and $header and 1 of ($producer*) 122 | } 123 | 124 | rule suspicious_creator : PDF raw 125 | { 126 | meta: 127 | author = "Glenn Edwards (@hiddenillusion)" 128 | version = "0.1" 129 | weight = 3 130 | 131 | strings: 132 | $magic = { 25 50 44 46 } 133 | $header = /%PDF-1\.(3|4|6)/ 134 | 135 | $creator0 = "yen vaw" 136 | $creator1 = "Scribus" 137 | $creator2 = "Viraciregavi" 138 | condition: 139 | $magic in (0..1024) and $header and 1 of ($creator*) 140 | } 141 | 142 | rule possible_exploit : PDF raw 143 | { 144 | meta: 145 | author = "Glenn Edwards (@hiddenillusion)" 146 | version = "0.1" 147 | weight = 3 148 | 149 | strings: 150 | $magic = { 25 50 44 46 } 151 | 152 | $attrib0 = /\/JavaScript / 153 | $attrib3 = /\/ASCIIHexDecode/ 154 | $attrib4 = /\/ASCII85Decode/ 155 | 156 | $action0 = /\/Action/ 157 | $action1 = "Array" 158 | $shell = "A" 159 | $cond0 = "unescape" 160 | $cond1 = "String.fromCharCode" 161 | 162 | $nop = "%u9090%u9090" 163 | condition: 164 | $magic in (0..1024) and (2 of ($attrib*)) or ($action0 and #shell > 10 and 1 of ($cond*)) or ($action1 and $cond0 and $nop) 165 | } 166 | 167 | rule shellcode_blob_metadata : PDF raw 168 | { 169 | meta: 170 | author = "Glenn Edwards (@hiddenillusion)" 171 | version = "0.1" 172 | description = "When there's a large Base64 blob inserted into metadata fields it often indicates shellcode to later be decoded" 173 | weight = 4 174 | strings: 175 | $magic = { 25 50 44 46 } 176 | 177 | $reg_keyword = /\/Keywords.?\(([a-zA-Z0-9]{200,})/ //~6k was observed in BHEHv2 PDF exploits holding the shellcode 178 | $reg_author = /\/Author.?\(([a-zA-Z0-9]{200,})/ 179 | $reg_title = /\/Title.?\(([a-zA-Z0-9]{200,})/ 180 | $reg_producer = /\/Producer.?\(([a-zA-Z0-9]{200,})/ 181 | $reg_creator = /\/Creator.?\(([a-zA-Z0-9]{300,})/ 182 | $reg_create = /\/CreationDate.?\(([a-zA-Z0-9]{200,})/ 183 | 184 | condition: 185 | $magic in (0..1024) and 1 of ($reg*) 186 | } 187 | 188 | rule suspicious_js : PDF raw 189 | { 190 | meta: 191 | author = "Glenn Edwards (@hiddenillusion)" 192 | version = "0.1" 193 | weight = 3 194 | 195 | strings: 196 | $magic = { 25 50 44 46 } 197 | 198 | $attrib0 = /\/OpenAction / 199 | $attrib1 = /\/JavaScript / 200 | 201 | $js0 = "eval" 202 | $js1 = "Array" 203 | $js2 = "String.fromCharCode" 204 | 205 | condition: 206 | $magic in (0..1024) and all of ($attrib*) and 2 of ($js*) 207 | } 208 | 209 | rule suspicious_launch_action : PDF raw 210 | { 211 | meta: 212 | author = "Glenn Edwards (@hiddenillusion)" 213 | version = "0.1" 214 | weight = 2 215 | 216 | strings: 217 | $magic = { 25 50 44 46 } 218 | 219 | $attrib0 = /\/Launch/ 220 | $attrib1 = /\/URL / 221 | $attrib2 = /\/Action/ 222 | $attrib3 = /\/OpenAction/ 223 | $attrib4 = /\/F / 224 | 225 | condition: 226 | $magic in (0..1024) and 3 of ($attrib*) 227 | } 228 | 229 | rule suspicious_embed : PDF raw 230 | { 231 | meta: 232 | author = "Glenn Edwards (@hiddenillusion)" 233 | version = "0.1" 234 | ref = "https://feliam.wordpress.com/2010/01/13/generic-pdf-exploit-hider-embedpdf-py-and-goodbye-av-detection-012010/" 235 | weight = 2 236 | 237 | strings: 238 | $magic = { 25 50 44 46 } 239 | 240 | $meth0 = /\/Launch/ 241 | $meth1 = /\/GoTo(E|R)/ //means go to embedded or remote 242 | $attrib0 = /\/URL / 243 | $attrib1 = /\/Action/ 244 | $attrib2 = /\/Filespec/ 245 | 246 | condition: 247 | $magic in (0..1024) and 1 of ($meth*) and 2 of ($attrib*) 248 | } 249 | 250 | rule suspicious_obfuscation : PDF raw 251 | { 252 | meta: 253 | author = "Glenn Edwards (@hiddenillusion)" 254 | version = "0.1" 255 | weight = 2 256 | 257 | strings: 258 | $magic = { 25 50 44 46 } 259 | $reg = /\/\w#[a-zA-Z0-9]{2}#[a-zA-Z0-9]{2}/ 260 | 261 | condition: 262 | $magic in (0..1024) and #reg > 5 263 | } 264 | 265 | rule invalid_XObject_js : PDF raw 266 | { 267 | meta: 268 | author = "Glenn Edwards (@hiddenillusion)" 269 | description = "XObject's require v1.4+" 270 | ref = "https://blogs.adobe.com/ReferenceXObjects/" 271 | version = "0.1" 272 | weight = 2 273 | 274 | strings: 275 | $magic = { 25 50 44 46 } 276 | $ver = /%PDF-1\.[4-9]/ 277 | 278 | $attrib0 = /\/XObject/ 279 | $attrib1 = /\/JavaScript/ 280 | 281 | condition: 282 | $magic in (0..1024) and not $ver and all of ($attrib*) 283 | } 284 | 285 | rule invalid_trailer_structure : PDF raw 286 | { 287 | meta: 288 | author = "Glenn Edwards (@hiddenillusion)" 289 | version = "0.1" 290 | weight = 1 291 | 292 | strings: 293 | $magic = { 25 50 44 46 } 294 | // Required for a valid PDF 295 | $reg0 = /trailer\r?\n?.*\/Size.*\r?\n?\.*/ 296 | $reg1 = /\/Root.*\r?\n?.*startxref\r?\n?.*\r?\n?%%EOF/ 297 | 298 | condition: 299 | $magic in (0..1024) and not $reg0 and not $reg1 300 | } 301 | 302 | rule multiple_versions : PDF raw 303 | { 304 | meta: 305 | author = "Glenn Edwards (@hiddenillusion)" 306 | version = "0.1" 307 | description = "Written very generically and doesn't hold any weight - just something that might be useful to know about to help show incremental updates to the file being analyzed" 308 | weight = 1 309 | 310 | strings: 311 | $magic = { 25 50 44 46 } 312 | $s0 = "trailer" 313 | $s1 = "%%EOF" 314 | 315 | condition: 316 | $magic in (0..1024) and #s0 > 1 and #s1 > 1 317 | } 318 | 319 | rule js_wrong_version : PDF raw 320 | { 321 | meta: 322 | author = "Glenn Edwards (@hiddenillusion)" 323 | description = "JavaScript was introduced in v1.3" 324 | ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" 325 | version = "0.1" 326 | weight = 2 327 | 328 | strings: 329 | $magic = { 25 50 44 46 } 330 | $js = /\/JavaScript/ 331 | $ver = /%PDF-1\.[3-9]/ 332 | 333 | condition: 334 | $magic in (0..1024) and $js and not $ver 335 | } 336 | 337 | rule JBIG2_wrong_version : PDF raw 338 | { 339 | meta: 340 | author = "Glenn Edwards (@hiddenillusion)" 341 | description = "JBIG2 was introduced in v1.4" 342 | ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" 343 | version = "0.1" 344 | weight = 1 345 | 346 | strings: 347 | $magic = { 25 50 44 46 } 348 | $js = /\/JBIG2Decode/ 349 | $ver = /%PDF-1\.[4-9]/ 350 | 351 | condition: 352 | $magic in (0..1024) and $js and not $ver 353 | } 354 | 355 | rule FlateDecode_wrong_version : PDF raw 356 | { 357 | meta: 358 | author = "Glenn Edwards (@hiddenillusion)" 359 | description = "Flate was introduced in v1.2" 360 | ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" 361 | version = "0.1" 362 | weight = 1 363 | 364 | strings: 365 | $magic = { 25 50 44 46 } 366 | $js = /\/FlateDecode/ 367 | $ver = /%PDF-1\.[2-9]/ 368 | 369 | condition: 370 | $magic in (0..1024) and $js and not $ver 371 | } 372 | 373 | rule embed_wrong_version : PDF raw 374 | { 375 | meta: 376 | author = "Glenn Edwards (@hiddenillusion)" 377 | description = "EmbeddedFiles were introduced in v1.3" 378 | ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" 379 | version = "0.1" 380 | weight = 1 381 | 382 | strings: 383 | $magic = { 25 50 44 46 } 384 | $embed = /\/EmbeddedFiles/ 385 | $ver = /%PDF-1\.[3-9]/ 386 | 387 | condition: 388 | $magic in (0..1024) and $embed and not $ver 389 | } 390 | 391 | rule invalid_xref_numbers : PDF raw 392 | { 393 | meta: 394 | author = "Glenn Edwards (@hiddenillusion)" 395 | version = "0.1" 396 | description = "The first entry in a cross-reference table is always free and has a generation number of 65,535" 397 | notes = "This can be also be in a stream..." 398 | weight = 1 399 | 400 | strings: 401 | $magic = { 25 50 44 46 } 402 | $reg0 = /xref\r?\n?.*\r?\n?.*65535\sf/ 403 | $reg1 = /endstream.*\r?\n?endobj.*\r?\n?startxref/ 404 | condition: 405 | $magic in (0..1024) and not $reg0 and not $reg1 406 | } 407 | 408 | rule js_splitting : PDF raw 409 | { 410 | meta: 411 | author = "Glenn Edwards (@hiddenillusion)" 412 | version = "0.1" 413 | description = "These are commonly used to split up JS code" 414 | weight = 2 415 | 416 | strings: 417 | $magic = { 25 50 44 46 } 418 | $js = /\/JavaScript/ 419 | $s0 = "getAnnots" 420 | $s1 = "getPageNumWords" 421 | $s2 = "getPageNthWord" 422 | $s3 = "this.info" 423 | 424 | condition: 425 | $magic in (0..1024) and $js and 1 of ($s*) 426 | } 427 | 428 | rule header_evasion : PDF raw 429 | { 430 | meta: 431 | author = "Glenn Edwards (@hiddenillusion)" 432 | description = "3.4.1, 'File Header' of Appendix H states that ' Acrobat viewers require only that the header appear somewhere within the first 1024 bytes of the file.' Therefore, if you see this trigger then any other rule looking to match the magic at 0 won't be applicable" 433 | ref = "http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf" 434 | version = "0.1" 435 | weight = 3 436 | 437 | strings: 438 | $magic = { 25 50 44 46 } 439 | condition: 440 | $magic in (5..1024) and #magic == 1 441 | } 442 | 443 | rule BlackHole_v2 : PDF raw 444 | { 445 | meta: 446 | author = "Glenn Edwards (@hiddenillusion)" 447 | version = "0.1" 448 | ref = "http://fortknoxnetworks.blogspot.no/2012/10/blackhhole-exploit-kit-v-20-url-pattern.html" 449 | weight = 3 450 | 451 | strings: 452 | $magic = { 25 50 44 46 } 453 | $content = "Index[5 1 7 1 9 4 23 4 50" 454 | 455 | condition: 456 | $magic in (0..1024) and $content 457 | } 458 | 459 | 460 | rule XDP_embedded_PDF : PDF raw 461 | { 462 | meta: 463 | author = "Glenn Edwards (@hiddenillusion)" 464 | version = "0.1" 465 | ref = "http://blog.9bplus.com/av-bypass-for-malicious-pdfs-using-xdp" 466 | weight = 1 467 | 468 | strings: 469 | $s1 = "" 471 | $s3 = "" 472 | $header0 = "%PDF" 473 | $header1 = "JVBERi0" 474 | 475 | condition: 476 | all of ($s*) and 1 of ($header*) 477 | } 478 | 479 | rule PDF_Embedded_Exe : PDF 480 | { 481 | meta: 482 | ref = "https://github.com/jacobsoo/Yara-Rules/blob/master/PDF_Embedded_Exe.yar" 483 | strings: 484 | $header = {25 50 44 46} 485 | $Launch_Action = {3C 3C 2F 53 2F 4C 61 75 6E 63 68 2F 54 79 70 65 2F 41 63 74 69 6F 6E 2F 57 69 6E 3C 3C 2F 46} 486 | $exe = {3C 3C 2F 45 6D 62 65 64 64 65 64 46 69 6C 65 73} 487 | condition: 488 | $header at 0 and $Launch_Action and $exe 489 | } 490 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/pe/antidebug_antivm.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | */ 4 | 5 | import "pe" 6 | 7 | rule DebuggerCheck__PEB : AntiDebug DebuggerCheck { 8 | meta: 9 | weight = 1 10 | Author = "naxonez" 11 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 12 | strings: 13 | $ ="IsDebugged" 14 | condition: 15 | any of them 16 | } 17 | 18 | rule DebuggerCheck__GlobalFlags : AntiDebug DebuggerCheck { 19 | meta: 20 | weight = 1 21 | Author = "naxonez" 22 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 23 | strings: 24 | $ ="NtGlobalFlags" 25 | condition: 26 | any of them 27 | } 28 | 29 | rule DebuggerCheck__QueryInfo : AntiDebug DebuggerCheck { 30 | meta: 31 | weight = 1 32 | Author = "naxonez" 33 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 34 | strings: 35 | $ ="QueryInformationProcess" 36 | condition: 37 | any of them 38 | } 39 | 40 | rule DebuggerCheck__RemoteAPI : AntiDebug DebuggerCheck { 41 | meta: 42 | weight = 1 43 | Author = "naxonez" 44 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 45 | strings: 46 | $ ="CheckRemoteDebuggerPresent" 47 | condition: 48 | any of them 49 | } 50 | 51 | rule DebuggerHiding__Thread : AntiDebug DebuggerHiding { 52 | meta: 53 | Author = "naxonez" 54 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 55 | weight = 1 56 | strings: 57 | $ ="SetInformationThread" 58 | condition: 59 | any of them 60 | } 61 | 62 | rule DebuggerHiding__Active : AntiDebug DebuggerHiding { 63 | meta: 64 | weight = 1 65 | Author = "naxonez" 66 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 67 | strings: 68 | $ ="DebugActiveProcess" 69 | condition: 70 | any of them 71 | } 72 | 73 | // 20150909 - Issue #39 - Commented because of High FP rate 74 | /* 75 | rule DebuggerTiming__PerformanceCounter : AntiDebug DebuggerTiming { 76 | meta: 77 | weight = 1 78 | Author = "naxonez" 79 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 80 | strings: 81 | $ ="QueryPerformanceCounter" 82 | condition: 83 | any of them 84 | } 85 | */ 86 | 87 | // 20150909 - Issue #39 - Commented because of High FP rate 88 | /* 89 | rule DebuggerTiming__Ticks : AntiDebug DebuggerTiming { 90 | meta: 91 | weight = 1 92 | Author = "naxonez" 93 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 94 | strings: 95 | $ ="GetTickCount" 96 | condition: 97 | any of them 98 | } 99 | */ 100 | 101 | // 20150909 - Issue #39 - Commented because of High FP rate 102 | /* 103 | rule DebuggerOutput__String : AntiDebug DebuggerOutput { 104 | meta: 105 | weight = 1 106 | Author = "naxonez" 107 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 108 | strings: 109 | $ ="OutputDebugString" 110 | condition: 111 | any of them 112 | } 113 | */ 114 | 115 | // 20150909 - Issue #39 - Commented because of High FP rate 116 | /* 117 | rule DebuggerException__UnhandledFilter : AntiDebug DebuggerException { 118 | meta: 119 | weight = 1 120 | Author = "naxonez" 121 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 122 | strings: 123 | $ ="SetUnhandledExceptionFilter" 124 | condition: 125 | any of them 126 | } 127 | */ 128 | 129 | rule DebuggerException__ConsoleCtrl : AntiDebug DebuggerException { 130 | meta: 131 | weight = 1 132 | Author = "naxonez" 133 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 134 | strings: 135 | $ ="GenerateConsoleCtrlEvent" 136 | condition: 137 | any of them 138 | } 139 | 140 | rule DebuggerException__SetConsoleCtrl : AntiDebug DebuggerException { 141 | meta: 142 | weight = 1 143 | Author = "naxonez" 144 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 145 | strings: 146 | $ ="SetConsoleCtrlHandler" 147 | condition: 148 | any of them 149 | } 150 | 151 | rule ThreadControl__Context : AntiDebug ThreadControl { 152 | meta: 153 | weight = 1 154 | Author = "naxonez" 155 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 156 | strings: 157 | $ ="SetThreadContext" 158 | condition: 159 | any of them 160 | } 161 | 162 | rule DebuggerCheck__DrWatson : AntiDebug DebuggerCheck { 163 | meta: 164 | weight = 1 165 | Author = "naxonez" 166 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 167 | strings: 168 | $ ="__invoke__watson" 169 | condition: 170 | any of them 171 | } 172 | 173 | rule SEH__v3 : AntiDebug SEH { 174 | meta: 175 | weight = 1 176 | Author = "naxonez" 177 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 178 | strings: 179 | $ = "____except__handler3" 180 | $ = "____local__unwind3" 181 | condition: 182 | any of them 183 | } 184 | 185 | rule SEH__v4 : AntiDebug SEH { 186 | // VS 8.0+ 187 | meta: 188 | weight = 1 189 | Author = "naxonez" 190 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 191 | strings: 192 | $ = "____except__handler4" 193 | $ = "____local__unwind4" 194 | $ = "__XcptFilter" 195 | condition: 196 | any of them 197 | } 198 | 199 | rule SEH__vba : AntiDebug SEH { 200 | meta: 201 | weight = 1 202 | Author = "naxonez" 203 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 204 | strings: 205 | $ = "vbaExceptHandler" 206 | condition: 207 | any of them 208 | } 209 | 210 | rule SEH__vectored : AntiDebug SEH { 211 | meta: 212 | weight = 1 213 | Author = "naxonez" 214 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 215 | strings: 216 | $ = "AddVectoredExceptionHandler" 217 | $ = "RemoveVectoredExceptionHandler" 218 | condition: 219 | any of them 220 | } 221 | 222 | // 20150909 - Issue #39 - Commented because of High FP rate 223 | /* 224 | rule DebuggerPattern__RDTSC : AntiDebug DebuggerPattern { 225 | meta: 226 | weight = 1 227 | Author = "naxonez" 228 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 229 | strings: 230 | $ = {0F 31} 231 | condition: 232 | any of them 233 | } 234 | */ 235 | 236 | // 20150909 - Issue #39 - Commented because of High FP rate 237 | /* 238 | rule DebuggerPattern__CPUID : AntiDebug DebuggerPattern { 239 | meta: 240 | weight = 1 241 | Author = "naxonez" 242 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 243 | strings: 244 | $ = {0F A2} 245 | condition: 246 | any of them 247 | } 248 | */ 249 | 250 | // 20150909 - Issue #39 - Commented because of High FP rate 251 | /* 252 | rule DebuggerPattern__SEH_Saves : AntiDebug DebuggerPattern { 253 | meta: 254 | weight = 1 255 | Author = "naxonez" 256 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 257 | strings: 258 | $ = {64 ff 35 00 00 00 00} 259 | condition: 260 | any of them 261 | } 262 | */ 263 | 264 | // 20150909 - Issue #39 - Commented because of High FP rate 265 | /* 266 | rule DebuggerPattern__SEH_Inits : AntiDebug DebuggerPattern { 267 | meta: 268 | weight = 1 269 | Author = "naxonez" 270 | reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara" 271 | strings: 272 | $ = {64 89 25 00 00 00 00} 273 | condition: 274 | any of them 275 | } 276 | */ 277 | 278 | 279 | rule Check_Dlls 280 | { 281 | meta: 282 | Author = "Nick Hoffman" 283 | Description = "Checks for common sandbox dlls" 284 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 285 | strings: 286 | $dll1 = "sbiedll.dll" wide nocase ascii fullword 287 | $dll2 = "dbghelp.dll" wide nocase ascii fullword 288 | $dll3 = "api_log.dll" wide nocase ascii fullword 289 | $dll4 = "dir_watch.dll" wide nocase ascii fullword 290 | $dll5 = "pstorec.dll" wide nocase ascii fullword 291 | $dll6 = "vmcheck.dll" wide nocase ascii fullword 292 | $dll7 = "wpespy.dll" wide nocase ascii fullword 293 | condition: 294 | 2 of them 295 | } 296 | 297 | rule Check_Qemu_Description 298 | { 299 | meta: 300 | Author = "Nick Hoffman" 301 | Description = "Checks for QEMU systembiosversion key" 302 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 303 | strings: 304 | $key = "HARDWARE\\Description\\System" nocase wide ascii 305 | $value = "SystemBiosVersion" nocase wide ascii 306 | $data = "QEMU" wide nocase ascii 307 | condition: 308 | all of them 309 | } 310 | 311 | rule Check_Qemu_DeviceMap 312 | { 313 | meta: 314 | Author = "Nick Hoffman" 315 | Description = "Checks for Qemu reg keys" 316 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 317 | strings: 318 | $key = "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0" nocase wide ascii 319 | $value = "Identifier" nocase wide ascii 320 | $data = "QEMU" wide nocase ascii 321 | condition: 322 | all of them 323 | } 324 | 325 | rule Check_VBox_Description 326 | { 327 | meta: 328 | Author = "Nick Hoffman" 329 | Description = "Checks Vbox description reg key" 330 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 331 | strings: 332 | $key = "HARDWARE\\Description\\System" nocase wide ascii 333 | $value = "SystemBiosVersion" nocase wide ascii 334 | $data = "VBOX" nocase wide ascii 335 | condition: 336 | all of them 337 | } 338 | rule Check_VBox_DeviceMap 339 | { 340 | meta: 341 | Author = "Nick Hoffman" 342 | Description = "Checks Vbox registry keys" 343 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 344 | strings: 345 | $key = "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0" nocase wide ascii 346 | $value = "Identifier" nocase wide ascii 347 | $data = "VBOX" nocase wide ascii 348 | condition: 349 | all of them 350 | } 351 | rule Check_VBox_Guest_Additions 352 | { 353 | meta: 354 | Author = "Nick Hoffman" 355 | Description = "Checks for the existence of the guest additions registry key" 356 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 357 | strings: 358 | $key = "SOFTWARE\\Oracle\\VirtualBox Guest Additions" wide ascii nocase 359 | condition: 360 | any of them 361 | } 362 | rule Check_VBox_VideoDrivers 363 | { 364 | meta: 365 | Author = "Nick Hoffman" 366 | Description = "Checks for reg keys of Vbox video drivers" 367 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 368 | strings: 369 | $key = "HARDWARE\\Description\\System" nocase wide ascii 370 | $value = "VideoBiosVersion" wide nocase ascii 371 | $data = "VIRTUALBOX" nocase wide ascii 372 | condition: 373 | all of them 374 | } 375 | rule Check_VMWare_DeviceMap 376 | { 377 | meta: 378 | Author = "Nick Hoffman" 379 | Description = "Checks for the existence of VmWare Registry Keys" 380 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 381 | strings: 382 | $key = "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0" wide ascii nocase 383 | $value = "Identifier" wide nocase ascii 384 | $data = "VMware" wide nocase ascii 385 | condition: 386 | all of them 387 | } 388 | rule Check_VmTools 389 | { 390 | meta: 391 | Author = "Nick Hoffman" 392 | Description = "Checks for the existence of VmTools reg key" 393 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 394 | strings: 395 | $ ="SOFTWARE\\VMware, Inc.\\VMware Tools" nocase ascii wide 396 | condition: 397 | any of them 398 | } 399 | rule Check_Wine 400 | { 401 | meta: 402 | Author = "Nick Hoffman" 403 | Description = "Checks for the existence of Wine" 404 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 405 | strings: 406 | $ ="wine_get_unix_file_name" 407 | condition: 408 | any of them 409 | } 410 | 411 | rule vmdetect 412 | { 413 | meta: 414 | author = "nex" 415 | description = "Possibly employs anti-virtualization techniques" 416 | 417 | strings: 418 | // Binary tricks 419 | $vmware = {56 4D 58 68} 420 | $virtualpc = {0F 3F 07 0B} 421 | $ssexy = {66 0F 70 ?? ?? 66 0F DB ?? ?? ?? ?? ?? 66 0F DB ?? ?? ?? ?? ?? 66 0F EF} 422 | $vmcheckdll = {45 C7 00 01} 423 | $redpill = {0F 01 0D 00 00 00 00 C3} 424 | 425 | // Random strings 426 | $vmware1 = "VMXh" 427 | $vmware2 = "Ven_VMware_" nocase 428 | $vmware3 = "Prod_VMware_Virtual_" nocase 429 | $vmware4 = "hgfs.sys" nocase 430 | $vmware5 = "mhgfs.sys" nocase 431 | $vmware6 = "prleth.sys" nocase 432 | $vmware7 = "prlfs.sys" nocase 433 | $vmware8 = "prlmouse.sys" nocase 434 | $vmware9 = "prlvideo.sys" nocase 435 | $vmware10 = "prl_pv32.sys" nocase 436 | $vmware11 = "vpc-s3.sys" nocase 437 | $vmware12 = "vmsrvc.sys" nocase 438 | $vmware13 = "vmx86.sys" nocase 439 | $vmware14 = "vmnet.sys" nocase 440 | $vmware15 = "vmicheartbeat" nocase 441 | $vmware16 = "vmicvss" nocase 442 | $vmware17 = "vmicshutdown" nocase 443 | $vmware18 = "vmicexchange" nocase 444 | $vmware19 = "vmdebug" nocase 445 | $vmware20 = "vmmouse" nocase 446 | $vmware21 = "vmtools" nocase 447 | $vmware22 = "VMMEMCTL" nocase 448 | $vmware23 = "vmx86" nocase 449 | $vmware24 = "vmware" nocase 450 | $virtualpc1 = "vpcbus" nocase 451 | $virtualpc2 = "vpc-s3" nocase 452 | $virtualpc3 = "vpcuhub" nocase 453 | $virtualpc4 = "msvmmouf" nocase 454 | $xen1 = "xenevtchn" nocase 455 | $xen2 = "xennet" nocase 456 | $xen3 = "xennet6" nocase 457 | $xen4 = "xensvc" nocase 458 | $xen5 = "xenvdb" nocase 459 | $xen6 = "XenVMM" nocase 460 | $virtualbox1 = "VBoxHook.dll" nocase 461 | $virtualbox2 = "VBoxService" nocase 462 | $virtualbox3 = "VBoxTray" nocase 463 | $virtualbox4 = "VBoxMouse" nocase 464 | $virtualbox5 = "VBoxGuest" nocase 465 | $virtualbox6 = "VBoxSF" nocase 466 | $virtualbox7 = "VBoxGuestAdditions" nocase 467 | $virtualbox8 = "VBOX HARDDISK" nocase 468 | 469 | // MAC addresses 470 | $vmware_mac_1a = "00-05-69" 471 | $vmware_mac_1b = "00:05:69" 472 | $vmware_mac_1c = "000569" 473 | $vmware_mac_2a = "00-50-56" 474 | $vmware_mac_2b = "00:50:56" 475 | $vmware_mac_2c = "005056" 476 | $vmware_mac_3a = "00-0C-29" nocase 477 | $vmware_mac_3b = "00:0C:29" nocase 478 | $vmware_mac_3c = "000C29" nocase 479 | $vmware_mac_4a = "00-1C-14" nocase 480 | $vmware_mac_4b = "00:1C:14" nocase 481 | $vmware_mac_4c = "001C14" nocase 482 | $virtualbox_mac_1a = "08-00-27" 483 | $virtualbox_mac_1b = "08:00:27" 484 | $virtualbox_mac_1c = "080027" 485 | 486 | condition: 487 | any of them 488 | } 489 | 490 | rule Check_Debugger 491 | { 492 | meta: 493 | Author = "Nick Hoffman" 494 | Description = "Looks for both isDebuggerPresent and CheckRemoteDebuggerPresent" 495 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 496 | condition: 497 | pe.imports("kernel32.dll","CheckRemoteDebuggerPresent") and 498 | pe.imports("kernel32.dll","IsDebuggerPresent") 499 | } 500 | 501 | rule Check_DriveSize 502 | { 503 | meta: 504 | Author = "Nick Hoffman" 505 | Description = "Rule tries to catch uses of DeviceIOControl being used to get the drive size" 506 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 507 | 508 | strings: 509 | $physicaldrive = "\\\\.\\PhysicalDrive0" wide ascii nocase 510 | $dwIoControlCode = {68 5c 40 07 00 [0-5] FF 15} //push 7405ch ; push esi (handle) then call deviceoiocontrol IOCTL_DISK_GET_LENGTH_INFO 511 | condition: 512 | pe.imports("kernel32.dll","CreateFileA") and 513 | pe.imports("kernel32.dll","DeviceIoControl") and 514 | $dwIoControlCode and 515 | $physicaldrive 516 | } 517 | rule Check_FilePaths 518 | { 519 | meta: 520 | Author = "Nick Hoffman" 521 | Description = "Checks for filepaths containing popular sandbox names" 522 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 523 | strings: 524 | $path1 = "SANDBOX" wide ascii 525 | $path2 = "\\SAMPLE" wide ascii 526 | $path3 = "\\VIRUS" wide ascii 527 | condition: 528 | all of ($path*) and pe.imports("kernel32.dll","GetModuleFileNameA") 529 | } 530 | 531 | rule Check_UserNames 532 | { 533 | meta: 534 | Author = "Nick Hoffman" 535 | Description = "Looks for malware checking for common sandbox usernames" 536 | Sample = "de1af0e97e94859d372be7fcf3a5daa5" 537 | strings: 538 | $user1 = "MALTEST" wide ascii 539 | $user2 = "TEQUILABOOMBOOM" wide ascii 540 | $user3 = "SANDBOX" wide ascii 541 | $user4 = "VIRUS" wide ascii 542 | $user5 = "MALWARE" wide ascii 543 | condition: 544 | all of ($user*) and pe.imports("advapi32.dll","GetUserNameA") 545 | } 546 | 547 | 548 | rule Check_OutputDebugStringA_iat 549 | { 550 | 551 | meta: 552 | Author = "http://twitter.com/j0sm1" 553 | Description = "Detect in IAT OutputDebugstringA" 554 | Date = "20/04/2015" 555 | 556 | condition: 557 | pe.imports("kernel32.dll","OutputDebugStringA") 558 | } 559 | 560 | // 20150909 - Issue #39 - Commented because of High FP rate 561 | /* 562 | rule Check_unhandledExceptionFiler_iat { 563 | 564 | meta: 565 | Author = "http://twitter.com/j0sm1" 566 | Description = "it's checked if UnhandledExceptionFilter is imported" 567 | Date = "20/04/2015" 568 | Reference = "http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide#UnhandledExceptionFilter" 569 | 570 | condition: 571 | pe.imports("kernel32.dll","UnhandledExceptionFilter") 572 | } 573 | */ 574 | 575 | // 20150909 - Issue #39 - Commented because of High FP rate 576 | /* 577 | rule check_RaiseException_iat { 578 | 579 | meta: 580 | Author = "http://twitter.com/j0sm1" 581 | Description = "it's checked if RaiseException is imported" 582 | Date = "20/04/2015" 583 | Reference = "http://waleedassar.blogspot.com.es/2012/11/ollydbg-raiseexception-bug.html" 584 | 585 | condition: 586 | pe.imports("kernel32.dll","RaiseException") 587 | } 588 | */ 589 | 590 | rule Check_FindWindowA_iat { 591 | 592 | meta: 593 | Author = "http://twitter.com/j0sm1" 594 | Description = "it's checked if FindWindowA() is imported" 595 | Date = "20/04/2015" 596 | Reference = "http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide#OllyFindWindow" 597 | 598 | strings: 599 | $ollydbg = "OLLYDBG" 600 | $windbg = "WinDbgFrameClass" 601 | 602 | condition: 603 | pe.imports("user32.dll","FindWindowA") and ($ollydbg or $windbg) 604 | } 605 | 606 | rule DebuggerCheck__MemoryWorkingSet : AntiDebug DebuggerCheck { 607 | meta: 608 | author = "Fernando Mercês" 609 | date = "2015-06" 610 | description = "Anti-debug process memory working set size check" 611 | reference = "http://www.gironsec.com/blog/2015/06/anti-debugger-trick-quicky/" 612 | 613 | condition: 614 | pe.imports("kernel32.dll", "K32GetProcessMemoryInfo") and 615 | pe.imports("kernel32.dll", "GetCurrentProcess") 616 | } 617 | 618 | rule WMI_VM_Detect : WMI_VM_Detect 619 | { 620 | meta: 621 | 622 | version = 2 623 | threat = "Using WMI to detect virtual machines via querying video card information" 624 | behaviour_class = "Evasion" 625 | author = "Joe Giron" 626 | date = "2015-09-25" 627 | description = "Detection of Virtual Appliances through the use of WMI for use of evasion." 628 | 629 | strings: 630 | 631 | $selstr = "SELECT Description FROM Win32_VideoController" nocase ascii wide 632 | $selstr2 = "SELECT * FROM Win32_VideoController" nocase ascii wide 633 | $vm1 = "virtualbox graphics adapter" nocase ascii wide 634 | $vm2 = "vmware svga ii" nocase ascii wide 635 | $vm3 = "vm additions s3 trio32/64" nocase ascii wide 636 | $vm4 = "parallel" nocase ascii wide 637 | $vm5 = "remotefx" nocase ascii wide 638 | $vm6 = "cirrus logic" nocase ascii wide 639 | $vm7 = "matrox" nocase ascii wide 640 | 641 | condition: 642 | any of ($selstr*) and any of ($vm*) 643 | 644 | 645 | } 646 | 647 | rule anti_dbg { 648 | meta: 649 | author = "x0r" 650 | description = "Checks if being debugged" 651 | version = "0.2" 652 | strings: 653 | $d1 = "Kernel32.dll" nocase 654 | $c1 = "CheckRemoteDebuggerPresent" 655 | $c2 = "IsDebuggerPresent" 656 | $c3 = "OutputDebugString" 657 | $c4 = "ContinueDebugEvent" 658 | $c5 = "DebugActiveProcess" 659 | condition: 660 | $d1 and 1 of ($c*) 661 | } 662 | 663 | rule Xor { 664 | strings: 665 | $xor_string = "This program cannot" xor 666 | 667 | condition: 668 | $xor_string 669 | } 670 | 671 | rule anti_dbgtools { 672 | meta: 673 | author = "x0r" 674 | description = "Checks for the presence of known debug tools" 675 | version = "0.1" 676 | strings: 677 | $f1 = "procexp.exe" nocase 678 | $f2 = "procmon.exe" nocase 679 | $f3 = "processmonitor.exe" nocase 680 | $f4 = "wireshark.exe" nocase 681 | $f5 = "fiddler.exe" nocase 682 | $f6 = "windbg.exe" nocase 683 | $f7 = "ollydbg.exe" nocase 684 | $f8 = "winhex.exe" nocase 685 | $f9 = "processhacker.exe" nocase 686 | $f10 = "hiew32.exe" nocase 687 | $c11 = "\\\\.\\NTICE" 688 | $c12 = "\\\\.\\SICE" 689 | $c13 = "\\\\.\\Syser" 690 | $c14 = "\\\\.\\SyserBoot" 691 | $c15 = "\\\\.\\SyserDbgMsg" 692 | condition: 693 | any of them 694 | } 695 | 696 | rule antisb_joesanbox { 697 | meta: 698 | author = "x0r" 699 | description = "Anti-Sandbox checks for Joe Sandbox" 700 | version = "0.1" 701 | strings: 702 | $p1 = "Software\\Microsoft\\Windows\\CurrentVersion" nocase 703 | $c1 = "RegQueryValue" 704 | $s1 = "55274-640-2673064-23950" 705 | condition: 706 | all of them 707 | } 708 | 709 | rule antisb_anubis { 710 | meta: 711 | author = "x0r" 712 | description = "Anti-Sandbox checks for Anubis" 713 | version = "0.1" 714 | strings: 715 | $p1 = "Software\\Microsoft\\Windows\\CurrentVersion" nocase 716 | $c1 = "RegQueryValue" 717 | $s1 = "76487-337-8429955-22614" 718 | $s2 = "76487-640-1457236-23837" 719 | condition: 720 | $p1 and $c1 and 1 of ($s*) 721 | } 722 | 723 | rule antisb_threatExpert { 724 | meta: 725 | author = "x0r" 726 | description = "Anti-Sandbox checks for ThreatExpert" 727 | version = "0.1" 728 | strings: 729 | $f1 = "dbghelp.dll" nocase 730 | condition: 731 | all of them 732 | } 733 | 734 | rule antisb_sandboxie { 735 | meta: 736 | author = "x0r" 737 | description = "Anti-Sandbox checks for Sandboxie" 738 | version = "0.1" 739 | strings: 740 | $f1 = "SbieDLL.dll" nocase 741 | condition: 742 | all of them 743 | } 744 | 745 | rule antisb_cwsandbox { 746 | meta: 747 | author = "x0r" 748 | description = "Anti-Sandbox checks for CWSandbox" 749 | version = "0.1" 750 | strings: 751 | $p1 = "Software\\Microsoft\\Windows\\CurrentVersion" nocase 752 | $s1 = "76487-644-3177037-23510" 753 | condition: 754 | all of them 755 | } 756 | 757 | rule antivm_virtualbox { 758 | meta: 759 | author = "x0r" 760 | description = "AntiVM checks for VirtualBox" 761 | version = "0.1" 762 | strings: 763 | $s1 = "VBoxService.exe" nocase 764 | condition: 765 | any of them 766 | } 767 | 768 | rule antivm_vmware { 769 | meta: 770 | author = "x0r" 771 | description = "AntiVM checks for VMWare" 772 | version = "0.1" 773 | strings: 774 | $s1 = "vmware.exe" nocase 775 | $s2 = "vmware-authd.exe" nocase 776 | $s3 = "vmware-hostd.exe" nocase 777 | $s4 = "vmware-tray.exe" nocase 778 | $s5 = "vmware-vmx.exe" nocase 779 | $s6 = "vmnetdhcp.exe" nocase 780 | $s7 = "vpxclient.exe" nocase 781 | $s8 = { b868584d56bb00000000b90a000000ba58560000ed } 782 | condition: 783 | any of them 784 | } 785 | 786 | rule antivm_bios { 787 | meta: 788 | author = "x0r" 789 | description = "AntiVM checks for Bios version" 790 | version = "0.2" 791 | strings: 792 | $p1 = "HARDWARE\\DESCRIPTION\\System" nocase 793 | $p2 = "HARDWARE\\DESCRIPTION\\System\\BIOS" nocase 794 | $c1 = "RegQueryValue" 795 | $r1 = "SystemBiosVersion" 796 | $r2 = "VideoBiosVersion" 797 | $r3 = "SystemManufacturer" 798 | condition: 799 | 1 of ($p*) and 1 of ($c*) and 1 of ($r*) 800 | } 801 | 802 | rule disable_antivirus { 803 | meta: 804 | author = "x0r" 805 | description = "Disable AntiVirus" 806 | version = "0.2" 807 | strings: 808 | $p1 = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\DisallowRun" nocase 809 | $p2 = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" nocase 810 | $p3 = "SOFTWARE\\Policies\\Microsoft\\Windows Defender" nocase 811 | $c1 = "RegSetValue" 812 | $r1 = "AntiVirusDisableNotify" 813 | $r2 = "DontReportInfectionInformation" 814 | $r3 = "DisableAntiSpyware" 815 | $r4 = "RunInvalidSignatures" 816 | $r5 = "AntiVirusOverride" 817 | $r6 = "CheckExeSignatures" 818 | $f1 = "blackd.exe" nocase 819 | $f2 = "blackice.exe" nocase 820 | $f3 = "lockdown.exe" nocase 821 | $f4 = "lockdown2000.exe" nocase 822 | $f5 = "taskkill.exe" nocase 823 | $f6 = "tskill.exe" nocase 824 | $f7 = "smc.exe" nocase 825 | $f8 = "sniffem.exe" nocase 826 | $f9 = "zapro.exe" nocase 827 | $f10 = "zlclient.exe" nocase 828 | $f11 = "zonealarm.exe" nocase 829 | condition: 830 | ($c1 and $p1 and 1 of ($f*)) or ($c1 and $p2) or 1 of ($r*) or $p3 831 | } 832 | 833 | rule disable_uax { 834 | meta: 835 | author = "x0r" 836 | description = "Disable User Access Control" 837 | version = "0.1" 838 | strings: 839 | $p1 = "SOFTWARE\\Microsoft\\Security Center" nocase 840 | $r1 = "UACDisableNotify" 841 | condition: 842 | all of them 843 | } 844 | 845 | rule disable_firewall { 846 | meta: 847 | author = "x0r" 848 | description = "Disable Firewall" 849 | version = "0.1" 850 | strings: 851 | $p1 = "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy" nocase 852 | $c1 = "RegSetValue" 853 | $r1 = "FirewallPolicy" 854 | $r2 = "EnableFirewall" 855 | $r3 = "FirewallDisableNotify" 856 | $s1 = "netsh firewall add allowedprogram" 857 | condition: 858 | (1 of ($p*) and $c1 and 1 of ($r*)) or $s1 859 | } 860 | 861 | rule disable_registry { 862 | meta: 863 | author = "x0r" 864 | description = "Disable Registry editor" 865 | version = "0.1" 866 | strings: 867 | $p1 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System" nocase 868 | $c1 = "RegSetValue" 869 | $r1 = "DisableRegistryTools" 870 | $r2 = "DisableRegedit" 871 | condition: 872 | 1 of ($p*) and $c1 and 1 of ($r*) 873 | } 874 | 875 | rule disable_dep { 876 | meta: 877 | author = "x0r" 878 | description = "Bypass DEP" 879 | version = "0.1" 880 | strings: 881 | $c1 = "EnableExecuteProtectionSupport" 882 | $c2 = "NtSetInformationProcess" 883 | $c3 = "VirtualProctectEx" 884 | $c4 = "SetProcessDEPPolicy" 885 | $c5 = "ZwProtectVirtualMemory" 886 | condition: 887 | any of them 888 | } 889 | 890 | rule disable_taskmanager { 891 | meta: 892 | author = "x0r" 893 | description = "Disable Task Manager" 894 | version = "0.1" 895 | strings: 896 | $p1 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System" nocase 897 | $r1 = "DisableTaskMgr" 898 | condition: 899 | 1 of ($p*) and 1 of ($r*) 900 | } 901 | 902 | rule inject_thread { 903 | meta: 904 | author = "x0r" 905 | description = "Code injection with CreateRemoteThread in a remote process" 906 | version = "0.1" 907 | strings: 908 | $c1 = "OpenProcess" 909 | $c2 = "VirtualAllocEx" 910 | $c3 = "NtWriteVirtualMemory" 911 | $c4 = "WriteProcessMemory" 912 | $c5 = "CreateRemoteThread" 913 | $c6 = "CreateThread" 914 | $c7 = "OpenProcess" 915 | condition: 916 | $c1 and $c2 and ( $c3 or $c4 ) and ( $c5 or $c6 or $c7 ) 917 | } 918 | // Issue #101 - Commented because of High FP rate 919 | /* 920 | rule create_process { 921 | meta: 922 | author = "x0r" 923 | description = "Create a new process" 924 | version = "0.2" 925 | strings: 926 | $f1 = "Shell32.dll" nocase 927 | $f2 = "Kernel32.dll" nocase 928 | $c1 = "ShellExecute" 929 | $c2 = "WinExec" 930 | $c3 = "CreateProcess" 931 | $c4 = "CreateThread" 932 | condition: 933 | ($f1 and $c1 ) or $f2 and ($c2 or $c3 or $c4) 934 | } 935 | */ 936 | 937 | // Issue #101 - Commented because of High FP rate 938 | /* 939 | rule persistence { 940 | meta: 941 | author = "x0r" 942 | description = "Install itself for autorun at Windows startup" 943 | version = "0.1" 944 | strings: 945 | $p1 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" nocase 946 | $p2 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce" nocase 947 | $p3 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices" nocase 948 | $p4 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce" nocase 949 | $p5 = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon" nocase 950 | $p6 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run" nocase 951 | $p7 = "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\" nocase 952 | $p8 = "SOFTWARE\\Microsoft\\WindowsNT\\CurrentVersion\\Windows" nocase 953 | $p9 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SharedTaskScheduler" nocase 954 | $p10 = "comfile\\shell\\open\\command" nocase 955 | $p11 = "piffile\\shell\\open\\command" nocase 956 | $p12 = "exefile\\shell\\open\\command" nocase 957 | $p13 = "txtfile\\shell\\open\\command" nocase 958 | $p14 = "\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options" 959 | $f1 = "win.ini" nocase 960 | $f2 = "system.ini" nocase 961 | $f3 = "Start Menu\\Programs\\Startup" nocase 962 | condition: 963 | any of them 964 | } 965 | */ 966 | 967 | rule hijack_network { 968 | meta: 969 | author = "x0r" 970 | description = "Hijack network configuration" 971 | version = "0.1" 972 | strings: 973 | $p1 = "SOFTWARE\\Classes\\PROTOCOLS\\Handler" nocase 974 | $p2 = "SOFTWARE\\Classes\\PROTOCOLS\\Filter" nocase 975 | $p3 = "Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyServer" nocase 976 | $p4 = "software\\microsoft\\windows\\currentversion\\internet settings\\proxyenable" nocase 977 | $f1 = "drivers\\etc\\hosts" nocase 978 | condition: 979 | any of them 980 | } 981 | 982 | rule create_service { 983 | meta: 984 | author = "x0r" 985 | description = "Create a windows service" 986 | version = "0.2" 987 | strings: 988 | $f1 = "Advapi32.dll" nocase 989 | $c1 = "CreateService" 990 | $c2 = "ControlService" 991 | $c3 = "StartService" 992 | $c4 = "QueryServiceStatus" 993 | condition: 994 | all of them 995 | } 996 | 997 | rule create_com_service { 998 | meta: 999 | author = "x0r" 1000 | description = "Create a COM server" 1001 | version = "0.1" 1002 | strings: 1003 | $c1 = "DllCanUnloadNow" nocase 1004 | $c2 = "DllGetClassObject" 1005 | $c3 = "DllInstall" 1006 | $c4 = "DllRegisterServer" 1007 | $c5 = "DllUnregisterServer" 1008 | condition: 1009 | all of them 1010 | } 1011 | 1012 | rule network_udp_sock { 1013 | meta: 1014 | author = "x0r" 1015 | description = "Communications over UDP network" 1016 | version = "0.1" 1017 | strings: 1018 | $f1 = "Ws2_32.dll" nocase 1019 | $f2 = "System.Net" nocase 1020 | $f3 = "wsock32.dll" nocase 1021 | $c0 = "WSAStartup" 1022 | $c1 = "sendto" 1023 | $c2 = "recvfrom" 1024 | $c3 = "WSASendTo" 1025 | $c4 = "WSARecvFrom" 1026 | $c5 = "UdpClient" 1027 | condition: 1028 | (($f1 or $f3) and 2 of ($c*)) or ($f2 and $c5) 1029 | } 1030 | 1031 | rule network_tcp_listen { 1032 | meta: 1033 | author = "x0r" 1034 | description = "Listen for incoming communication" 1035 | version = "0.1" 1036 | strings: 1037 | $f1 = "Ws2_32.dll" nocase 1038 | $f2 = "Mswsock.dll" nocase 1039 | $f3 = "System.Net" nocase 1040 | $f4 = "wsock32.dll" nocase 1041 | $c1 = "bind" 1042 | $c2 = "accept" 1043 | $c3 = "GetAcceptExSockaddrs" 1044 | $c4 = "AcceptEx" 1045 | $c5 = "WSAStartup" 1046 | $c6 = "WSAAccept" 1047 | $c7 = "WSASocket" 1048 | $c8 = "TcpListener" 1049 | $c9 = "AcceptTcpClient" 1050 | $c10 = "listen" 1051 | condition: 1052 | 1 of ($f*) and 2 of ($c*) 1053 | } 1054 | 1055 | rule network_dyndns { 1056 | meta: 1057 | author = "x0r" 1058 | description = "Communications dyndns network" 1059 | version = "0.1" 1060 | strings: 1061 | $s1 =".no-ip.org" 1062 | $s2 =".publicvm.com" 1063 | $s3 =".linkpc.net" 1064 | $s4 =".dynu.com" 1065 | $s5 =".dynu.net" 1066 | $s6 =".afraid.org" 1067 | $s7 =".chickenkiller.com" 1068 | $s8 =".crabdance.com" 1069 | $s9 =".ignorelist.com" 1070 | $s10 =".jumpingcrab.com" 1071 | $s11 =".moo.com" 1072 | $s12 =".strangled.com" 1073 | $s13 =".twillightparadox.com" 1074 | $s14 =".us.to" 1075 | $s15 =".strangled.net" 1076 | $s16 =".info.tm" 1077 | $s17 =".homenet.org" 1078 | $s18 =".biz.tm" 1079 | $s19 =".continent.kz" 1080 | $s20 =".ax.lt" 1081 | $s21 =".system-ns.com" 1082 | $s22 =".adultdns.com" 1083 | $s23 =".craftx.biz" 1084 | $s24 =".ddns01.com" 1085 | $s25 =".dns53.biz" 1086 | $s26 =".dnsapi.info" 1087 | $s27 =".dnsd.info" 1088 | $s28 =".dnsdynamic.com" 1089 | $s29 =".dnsdynamic.net" 1090 | $s30 =".dnsget.org" 1091 | $s31 =".fe100.net" 1092 | $s32 =".flashserv.net" 1093 | $s33 =".ftp21.net" 1094 | condition: 1095 | any of them 1096 | } 1097 | 1098 | rule network_toredo { 1099 | meta: 1100 | author = "x0r" 1101 | description = "Communications over Toredo network" 1102 | version = "0.1" 1103 | strings: 1104 | $f1 = "FirewallAPI.dll" nocase 1105 | $p1 = "\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces\\" nocase 1106 | condition: 1107 | all of them 1108 | } 1109 | 1110 | rule network_smtp_dotNet { 1111 | meta: 1112 | author = "x0r" 1113 | description = "Communications smtp" 1114 | version = "0.1" 1115 | strings: 1116 | $f1 = "System.Net.Mail" nocase 1117 | $p1 = "SmtpClient" nocase 1118 | condition: 1119 | all of them 1120 | } 1121 | 1122 | rule network_smtp_raw { 1123 | meta: 1124 | author = "x0r" 1125 | description = "Communications smtp" 1126 | version = "0.1" 1127 | strings: 1128 | $s1 = "MAIL FROM:" nocase 1129 | $s2 = "RCPT TO:" nocase 1130 | condition: 1131 | all of them 1132 | } 1133 | 1134 | rule network_smtp_vb { 1135 | meta: 1136 | author = "x0r" 1137 | description = "Communications smtp" 1138 | version = "0.1" 1139 | strings: 1140 | $c1 = "CDO.Message" nocase 1141 | $c2 = "cdoSMTPServer" nocase 1142 | $c3 = "cdoSendUsingMethod" nocase 1143 | $c4 = "cdoex.dll" nocase 1144 | $c5 = "/cdo/configuration/smtpserver" nocase 1145 | condition: 1146 | any of them 1147 | } 1148 | 1149 | rule network_p2p_win { 1150 | meta: 1151 | author = "x0r" 1152 | description = "Communications over P2P network" 1153 | version = "0.1" 1154 | strings: 1155 | $c1 = "PeerCollabExportContact" 1156 | $c2 = "PeerCollabGetApplicationRegistrationInfo" 1157 | $c3 = "PeerCollabGetEndpointName" 1158 | $c4 = "PeerCollabGetEventData" 1159 | $c5 = "PeerCollabGetInvitationResponse" 1160 | $c6 = "PeerCollabGetPresenceInfo" 1161 | $c7 = "PeerCollabGetSigninOptions" 1162 | $c8 = "PeerCollabInviteContact" 1163 | $c9 = "PeerCollabInviteEndpoint" 1164 | $c10 = "PeerCollabParseContact" 1165 | $c11 = "PeerCollabQueryContactData" 1166 | $c12 = "PeerCollabRefreshEndpointData" 1167 | $c13 = "PeerCollabRegisterApplication" 1168 | $c14 = "PeerCollabRegisterEvent" 1169 | $c15 = "PeerCollabSetEndpointName" 1170 | $c16 = "PeerCollabSetObject" 1171 | $c17 = "PeerCollabSetPresenceInfo" 1172 | $c18 = "PeerCollabSignout" 1173 | $c19 = "PeerCollabUnregisterApplication" 1174 | $c20 = "PeerCollabUpdateContact" 1175 | condition: 1176 | 5 of them 1177 | } 1178 | 1179 | rule network_tor { 1180 | meta: 1181 | author = "x0r" 1182 | description = "Communications over TOR network" 1183 | version = "0.1" 1184 | strings: 1185 | $p1 = "tor\\hidden_service\\private_key" nocase 1186 | $p2 = "tor\\hidden_service\\hostname" nocase 1187 | $p3 = "tor\\lock" nocase 1188 | $p4 = "tor\\state" nocase 1189 | condition: 1190 | any of them 1191 | } 1192 | rule network_irc { 1193 | meta: 1194 | author = "x0r" 1195 | description = "Communications over IRC network" 1196 | version = "0.1" 1197 | strings: 1198 | $s1 = "NICK" 1199 | $s2 = "PING" 1200 | $s3 = "JOIN" 1201 | $s4 = "USER" 1202 | $s5 = "PRIVMSG" 1203 | condition: 1204 | all of them 1205 | } 1206 | 1207 | rule network_http { 1208 | meta: 1209 | author = "x0r" 1210 | description = "Communications over HTTP" 1211 | version = "0.1" 1212 | strings: 1213 | $f1 = "wininet.dll" nocase 1214 | $c1 = "InternetConnect" 1215 | $c2 = "InternetOpen" 1216 | $c3 = "InternetOpenUrl" 1217 | $c4 = "InternetReadFile" 1218 | $c5 = "InternetWriteFile" 1219 | $c6 = "HttpOpenRequest" 1220 | $c7 = "HttpSendRequest" 1221 | $c8 = "IdHTTPHeaderInfo" 1222 | condition: 1223 | $f1 and $c1 and ($c2 or $c3) and ($c4 or $c5 or $c6 or $c7 or $c8) 1224 | } 1225 | 1226 | rule network_dropper { 1227 | meta: 1228 | author = "x0r" 1229 | description = "File downloader/dropper" 1230 | version = "0.1" 1231 | strings: 1232 | $f1 = "urlmon.dll" nocase 1233 | $c1 = "URLDownloadToFile" 1234 | $c2 = "URLDownloadToCacheFile" 1235 | $c3 = "URLOpenStream" 1236 | $c4 = "URLOpenPullStream" 1237 | condition: 1238 | $f1 and 1 of ($c*) 1239 | } 1240 | 1241 | rule network_ftp { 1242 | meta: 1243 | author = "x0r" 1244 | description = "Communications over FTP" 1245 | version = "0.1" 1246 | strings: 1247 | $f1 = "Wininet.dll" nocase 1248 | $c1 = "FtpGetCurrentDirectory" 1249 | $c2 = "FtpGetFile" 1250 | $c3 = "FtpPutFile" 1251 | $c4 = "FtpSetCurrentDirectory" 1252 | $c5 = "FtpOpenFile" 1253 | $c6 = "FtpGetFileSize" 1254 | $c7 = "FtpDeleteFile" 1255 | $c8 = "FtpCreateDirectory" 1256 | $c9 = "FtpRemoveDirectory" 1257 | $c10 = "FtpRenameFile" 1258 | $c11 = "FtpDownload" 1259 | $c12 = "FtpUpload" 1260 | $c13 = "FtpGetDirectory" 1261 | condition: 1262 | $f1 and (4 of ($c*)) 1263 | } 1264 | 1265 | rule network_tcp_socket { 1266 | meta: 1267 | author = "x0r" 1268 | description = "Communications over RAW socket" 1269 | version = "0.1" 1270 | strings: 1271 | $f1 = "Ws2_32.dll" nocase 1272 | $f2 = "wsock32.dll" nocase 1273 | $c1 = "WSASocket" 1274 | $c2 = "socket" 1275 | $c3 = "send" 1276 | $c4 = "WSASend" 1277 | $c5 = "WSAConnect" 1278 | $c6 = "connect" 1279 | $c7 = "WSAStartup" 1280 | $c8 = "closesocket" 1281 | $c9 = "WSACleanup" 1282 | condition: 1283 | 1 of ($f*) and 2 of ($c*) 1284 | } 1285 | 1286 | rule network_dns { 1287 | meta: 1288 | author = "x0r" 1289 | description = "Communications use DNS" 1290 | version = "0.1" 1291 | strings: 1292 | $f1 = "System.Net" 1293 | $f2 = "Ws2_32.dll" nocase 1294 | $f3 = "Dnsapi.dll" nocase 1295 | $f4 = "wsock32.dll" nocase 1296 | $c2 = "GetHostEntry" 1297 | $c3 = "getaddrinfo" 1298 | $c4 = "gethostbyname" 1299 | $c5 = "WSAAsyncGetHostByName" 1300 | $c6 = "DnsQuery" 1301 | condition: 1302 | 1 of ($f*) and 1 of ($c*) 1303 | } 1304 | 1305 | rule network_ssl { 1306 | meta: 1307 | author = "x0r" 1308 | description = "Communications over SSL" 1309 | version = "0.1" 1310 | strings: 1311 | $f1 = "ssleay32.dll" nocase 1312 | $f2 = "libeay32.dll" nocase 1313 | $f3 = "libssl32.dll" nocase 1314 | $c1 = "IdSSLOpenSSL" nocase 1315 | condition: 1316 | any of them 1317 | } 1318 | 1319 | rule network_dga { 1320 | meta: 1321 | author = "x0r" 1322 | description = "Communication using dga" 1323 | version = "0.1" 1324 | strings: 1325 | $dll1 = "Advapi32.dll" nocase 1326 | $dll2 = "wininet.dll" nocase 1327 | $dll3 = "Crypt32.dll" nocase 1328 | $time1 = "SystemTimeToFileTime" 1329 | $time2 = "GetSystemTime" 1330 | $time3 = "GetSystemTimeAsFileTime" 1331 | $hash1 = "CryptCreateHash" 1332 | $hash2 = "CryptAcquireContext" 1333 | $hash3 = "CryptHashData" 1334 | $net1 = "InternetOpen" 1335 | $net2 = "InternetOpenUrl" 1336 | $net3 = "gethostbyname" 1337 | $net4 = "getaddrinfo" 1338 | condition: 1339 | all of ($dll*) and 1 of ($time*) and 1 of ($hash*) and 1 of ($net*) 1340 | } 1341 | 1342 | 1343 | rule bitcoin { 1344 | meta: 1345 | author = "x0r" 1346 | description = "Perform crypto currency mining" 1347 | version = "0.1" 1348 | strings: 1349 | $f1 = "OpenCL.dll" nocase 1350 | $f2 = "nvcuda.dll" nocase 1351 | $f3 = "opengl32.dll" nocase 1352 | $s1 = "cpuminer 2.2.2X-Mining-Extensions" 1353 | $s2 = "cpuminer 2.2.3X-Mining-Extensions" 1354 | $s3 = "Ufasoft bitcoin-miner/0.20" 1355 | $s4 = "bitcoin" nocase 1356 | $s5 = "stratum" nocase 1357 | condition: 1358 | 1 of ($f*) and 1 of ($s*) 1359 | } 1360 | 1361 | rule certificate { 1362 | meta: 1363 | author = "x0r" 1364 | description = "Inject certificate in store" 1365 | version = "0.1" 1366 | strings: 1367 | $f1 = "Crypt32.dll" nocase 1368 | $r1 = "software\\microsoft\\systemcertificates\\spc\\certificates" nocase 1369 | $c1 = "CertOpenSystemStore" 1370 | condition: 1371 | all of them 1372 | } 1373 | 1374 | rule escalate_priv { 1375 | meta: 1376 | author = "x0r" 1377 | description = "Escalade priviledges" 1378 | version = "0.1" 1379 | strings: 1380 | $d1 = "Advapi32.dll" nocase 1381 | $c1 = "SeDebugPrivilege" 1382 | $c2 = "AdjustTokenPrivileges" 1383 | condition: 1384 | 1 of ($d*) and 1 of ($c*) 1385 | } 1386 | 1387 | rule screenshot { 1388 | meta: 1389 | author = "x0r" 1390 | description = "Take screenshot" 1391 | version = "0.1" 1392 | strings: 1393 | $d1 = "Gdi32.dll" nocase 1394 | $d2 = "User32.dll" nocase 1395 | $c1 = "BitBlt" 1396 | $c2 = "GetDC" 1397 | condition: 1398 | 1 of ($d*) and 1 of ($c*) 1399 | } 1400 | 1401 | rule lookupip { 1402 | meta: 1403 | author = "x0r" 1404 | description = "Lookup external IP" 1405 | version = "0.1" 1406 | strings: 1407 | $n1 = "checkip.dyndns.org" nocase 1408 | $n2 = "whatismyip.org" nocase 1409 | $n3 = "whatsmyipaddress.com" nocase 1410 | $n4 = "getmyip.org" nocase 1411 | $n5 = "getmyip.co.uk" nocase 1412 | condition: 1413 | any of them 1414 | } 1415 | 1416 | rule dyndns { 1417 | meta: 1418 | author = "x0r" 1419 | description = "Dynamic DNS" 1420 | version = "0.1" 1421 | strings: 1422 | $s1 = "SOFTWARE\\Vitalwerks\\DUC" nocase 1423 | condition: 1424 | any of them 1425 | } 1426 | 1427 | rule lookupgeo { 1428 | meta: 1429 | author = "x0r" 1430 | description = "Lookup Geolocation" 1431 | version = "0.1" 1432 | strings: 1433 | $n1 = "j.maxmind.com" nocase 1434 | condition: 1435 | any of them 1436 | } 1437 | 1438 | rule keylogger { 1439 | meta: 1440 | author = "x0r" 1441 | description = "Run a keylogger" 1442 | version = "0.1" 1443 | strings: 1444 | $f1 = "User32.dll" nocase 1445 | $c1 = "GetAsyncKeyState" 1446 | $c2 = "GetKeyState" 1447 | $c3 = "MapVirtualKey" 1448 | $c4 = "GetKeyboardType" 1449 | condition: 1450 | $f1 and 1 of ($c*) 1451 | } 1452 | 1453 | rule cred_local { 1454 | meta: 1455 | author = "x0r" 1456 | description = "Steal credential" 1457 | version = "0.1" 1458 | strings: 1459 | $c1 = "LsaEnumerateLogonSessions" 1460 | $c2 = "SamIConnect" 1461 | $c3 = "SamIGetPrivateData" 1462 | $c4 = "SamQueryInformationUse" 1463 | $c5 = "CredEnumerateA" 1464 | $c6 = "CredEnumerateW" 1465 | $r1 = "software\\microsoft\\internet account manager" nocase 1466 | $r2 = "software\\microsoft\\identitycrl\\creds" nocase 1467 | $r3 = "Security\\Policy\\Secrets" 1468 | condition: 1469 | any of them 1470 | } 1471 | 1472 | 1473 | rule sniff_audio { 1474 | meta: 1475 | author = "x0r" 1476 | description = "Record Audio" 1477 | version = "0.1" 1478 | strings: 1479 | $f1 = "winmm.dll" nocase 1480 | $c1 = "waveInStart" 1481 | $c2 = "waveInReset" 1482 | $c3 = "waveInAddBuffer" 1483 | $c4 = "waveInOpen" 1484 | $c5 = "waveInClose" 1485 | condition: 1486 | $f1 and 2 of ($c*) 1487 | } 1488 | 1489 | rule cred_ff { 1490 | meta: 1491 | author = "x0r" 1492 | description = "Steal Firefox credential" 1493 | version = "0.1" 1494 | strings: 1495 | $f1 = "signons.sqlite" 1496 | $f2 = "signons3.txt" 1497 | $f3 = "secmod.db" 1498 | $f4 = "cert8.db" 1499 | $f5 = "key3.db" 1500 | condition: 1501 | any of them 1502 | } 1503 | 1504 | rule cred_vnc { 1505 | meta: 1506 | author = "x0r" 1507 | description = "Steal VNC credential" 1508 | version = "0.1" 1509 | strings: 1510 | $s1 = "VNCPassView" 1511 | condition: 1512 | all of them 1513 | } 1514 | 1515 | rule cred_ie7 { 1516 | meta: 1517 | author = "x0r" 1518 | description = "Steal IE 7 credential" 1519 | version = "0.1" 1520 | strings: 1521 | $f1 = "Crypt32.dll" nocase 1522 | $c1 = "CryptUnprotectData" 1523 | $s1 = "abe2869f-9b47-4cd9-a358-c22904dba7f7" nocase 1524 | condition: 1525 | all of them 1526 | } 1527 | 1528 | rule sniff_lan { 1529 | meta: 1530 | author = "x0r" 1531 | description = "Sniff Lan network traffic" 1532 | version = "0.1" 1533 | strings: 1534 | $f1 = "packet.dll" nocase 1535 | $f2 = "npf.sys" nocase 1536 | $f3 = "wpcap.dll" nocase 1537 | $f4 = "winpcap.dll" nocase 1538 | condition: 1539 | any of them 1540 | } 1541 | 1542 | rule migrate_apc { 1543 | meta: 1544 | author = "x0r" 1545 | description = "APC queue tasks migration" 1546 | version = "0.1" 1547 | strings: 1548 | $c1 = "OpenThread" 1549 | $c2 = "QueueUserAPC" 1550 | condition: 1551 | all of them 1552 | } 1553 | 1554 | rule spreading_file { 1555 | meta: 1556 | author = "x0r" 1557 | description = "Malware can spread east-west file" 1558 | version = "0.1" 1559 | strings: 1560 | $f1 = "autorun.inf" nocase 1561 | $f2 = "desktop.ini" nocase 1562 | $f3 = "desktop.lnk" nocase 1563 | condition: 1564 | any of them 1565 | } 1566 | 1567 | rule spreading_share { 1568 | meta: 1569 | author = "x0r" 1570 | description = "Malware can spread east-west using share drive" 1571 | version = "0.1" 1572 | strings: 1573 | $f1 = "netapi32.dll" nocase 1574 | $c1 = "NetShareGetInfo" 1575 | $c2 = "NetShareEnum" 1576 | condition: 1577 | $f1 and 1 of ($c*) 1578 | } 1579 | 1580 | rule rat_vnc { 1581 | meta: 1582 | author = "x0r" 1583 | description = "Remote Administration toolkit VNC" 1584 | version = "0.1" 1585 | strings: 1586 | $f1 = "ultravnc.ini" nocase 1587 | $c2 = "StartVNC" 1588 | $c3 = "StopVNC" 1589 | condition: 1590 | any of them 1591 | } 1592 | 1593 | rule rat_rdp { 1594 | meta: 1595 | author = "x0r" 1596 | description = "Remote Administration toolkit enable RDP" 1597 | version = "0.1" 1598 | strings: 1599 | $p1 = "SYSTEM\\CurrentControlSet\\Control\\Terminal Server" nocase 1600 | $p2 = "software\\microsoft\\windows nt\\currentversion\\terminal server" nocase 1601 | $p3 = "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp" nocase 1602 | $r1 = "EnableAdminTSRemote" 1603 | $c1 = "net start termservice" 1604 | $c2 = "sc config termservice start" 1605 | condition: 1606 | any of them 1607 | } 1608 | 1609 | rule rat_telnet { 1610 | meta: 1611 | author = "x0r" 1612 | description = "Remote Administration toolkit enable Telnet" 1613 | version = "0.1" 1614 | strings: 1615 | $r1 = "software\\microsoft\\telnetserver" nocase 1616 | condition: 1617 | any of them 1618 | } 1619 | 1620 | 1621 | rule rat_webcam { 1622 | meta: 1623 | author = "x0r" 1624 | description = "Remote Administration toolkit using webcam" 1625 | version = "0.1" 1626 | strings: 1627 | $f1 = "avicap32.dll" nocase 1628 | $c1 = "capCreateCaptureWindow" nocase 1629 | condition: 1630 | all of them 1631 | } 1632 | 1633 | rule check_patchlevel { 1634 | meta: 1635 | author = "x0r" 1636 | description = "Check if hotfix are applied" 1637 | version = "0.1" 1638 | strings: 1639 | $p1 = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix" nocase 1640 | condition: 1641 | any of them 1642 | } 1643 | 1644 | rule win_mutex { 1645 | meta: 1646 | author = "x0r" 1647 | description = "Create or check mutex" 1648 | version = "0.1" 1649 | strings: 1650 | $c1 = "CreateMutex" 1651 | condition: 1652 | 1 of ($c*) 1653 | } 1654 | 1655 | rule win_registry { 1656 | meta: 1657 | author = "x0r" 1658 | description = "Affect system registries" 1659 | version = "0.1" 1660 | strings: 1661 | $f1 = "advapi32.dll" nocase 1662 | $c1 = "RegQueryValueExA" 1663 | $c2 = "RegOpenKeyExA" 1664 | $c3 = "RegCloseKey" 1665 | $c4 = "RegSetValueExA" 1666 | $c5 = "RegCreateKeyA" 1667 | $c6 = "RegCloseKey" 1668 | condition: 1669 | $f1 and 1 of ($c*) 1670 | } 1671 | 1672 | rule win_token { 1673 | meta: 1674 | author = "x0r" 1675 | description = "Affect system token" 1676 | version = "0.1" 1677 | strings: 1678 | $f1 = "advapi32.dll" nocase 1679 | $c1 = "DuplicateTokenEx" 1680 | $c2 = "AdjustTokenPrivileges" 1681 | $c3 = "OpenProcessToken" 1682 | $c4 = "LookupPrivilegeValueA" 1683 | condition: 1684 | $f1 and 1 of ($c*) 1685 | } 1686 | 1687 | rule win_private_profile { 1688 | meta: 1689 | author = "x0r" 1690 | description = "Affect private profile" 1691 | version = "0.1" 1692 | strings: 1693 | $f1 = "kernel32.dll" nocase 1694 | $c1 = "GetPrivateProfileIntA" 1695 | $c2 = "GetPrivateProfileStringA" 1696 | $c3 = "WritePrivateProfileStringA" 1697 | condition: 1698 | $f1 and 1 of ($c*) 1699 | } 1700 | 1701 | rule win_files_operation { 1702 | meta: 1703 | author = "x0r" 1704 | description = "Affect private profile" 1705 | version = "0.1" 1706 | strings: 1707 | $f1 = "kernel32.dll" nocase 1708 | $c1 = "WriteFile" 1709 | $c2 = "SetFilePointer" 1710 | $c3 = "WriteFile" 1711 | $c4 = "ReadFile" 1712 | $c5 = "DeleteFileA" 1713 | $c6 = "CreateFileA" 1714 | $c7 = "FindFirstFileA" 1715 | $c8 = "MoveFileExA" 1716 | $c9 = "FindClose" 1717 | $c10 = "SetFileAttributesA" 1718 | $c11 = "CopyFile" 1719 | 1720 | condition: 1721 | $f1 and 3 of ($c*) 1722 | } 1723 | 1724 | 1725 | rule win_hook { 1726 | meta: 1727 | author = "x0r" 1728 | description = "Affect hook table" 1729 | version = "0.1" 1730 | strings: 1731 | $f1 = "user32.dll" nocase 1732 | $c1 = "UnhookWindowsHookEx" 1733 | $c2 = "SetWindowsHookExA" 1734 | $c3 = "CallNextHookEx" 1735 | condition: 1736 | $f1 and 1 of ($c*) 1737 | } 1738 | rule vmdetect_misc : vmdetect 1739 | { 1740 | meta: 1741 | author = "@abhinavbom" 1742 | maltype = "NA" 1743 | version = "0.1" 1744 | date = "31/10/2015" 1745 | description = "Following Rule is referenced from AlienVault's Yara rule repository.This rule contains additional processes and driver names." 1746 | strings: 1747 | $vbox1 = "VBoxService" nocase ascii wide 1748 | $vbox2 = "VBoxTray" nocase ascii wide 1749 | $vbox3 = "SOFTWARE\\Oracle\\VirtualBox Guest Additions" nocase ascii wide 1750 | $vbox4 = "SOFTWARE\\\\Oracle\\\\VirtualBox Guest Additions" nocase ascii wide 1751 | 1752 | $wine1 = "wine_get_unix_file_name" ascii wide 1753 | 1754 | $vmware1 = "vmmouse.sys" ascii wide 1755 | $vmware2 = "VMware Virtual IDE Hard Drive" ascii wide 1756 | 1757 | $miscvm1 = "SYSTEM\\ControlSet001\\Services\\Disk\\Enum" nocase ascii wide 1758 | $miscvm2 = "SYSTEM\\\\ControlSet001\\\\Services\\\\Disk\\\\Enum" nocase ascii wide 1759 | 1760 | // Drivers 1761 | $vmdrv1 = "hgfs.sys" ascii wide 1762 | $vmdrv2 = "vmhgfs.sys" ascii wide 1763 | $vmdrv3 = "prleth.sys" ascii wide 1764 | $vmdrv4 = "prlfs.sys" ascii wide 1765 | $vmdrv5 = "prlmouse.sys" ascii wide 1766 | $vmdrv6 = "prlvideo.sys" ascii wide 1767 | $vmdrv7 = "prl_pv32.sys" ascii wide 1768 | $vmdrv8 = "vpc-s3.sys" ascii wide 1769 | $vmdrv9 = "vmsrvc.sys" ascii wide 1770 | $vmdrv10 = "vmx86.sys" ascii wide 1771 | $vmdrv11 = "vmnet.sys" ascii wide 1772 | 1773 | // SYSTEM\ControlSet001\Services 1774 | $vmsrvc1 = "vmicheartbeat" ascii wide 1775 | $vmsrvc2 = "vmicvss" ascii wide 1776 | $vmsrvc3 = "vmicshutdown" ascii wide 1777 | $vmsrvc4 = "vmicexchange" ascii wide 1778 | $vmsrvc5 = "vmci" ascii wide 1779 | $vmsrvc6 = "vmdebug" ascii wide 1780 | $vmsrvc7 = "vmmouse" ascii wide 1781 | $vmsrvc8 = "VMTools" ascii wide 1782 | $vmsrvc9 = "VMMEMCTL" ascii wide 1783 | $vmsrvc10 = "vmware" ascii wide 1784 | $vmsrvc11 = "vmx86" ascii wide 1785 | $vmsrvc12 = "vpcbus" ascii wide 1786 | $vmsrvc13 = "vpc-s3" ascii wide 1787 | $vmsrvc14 = "vpcuhub" ascii wide 1788 | $vmsrvc15 = "msvmmouf" ascii wide 1789 | $vmsrvc16 = "VBoxMouse" ascii wide 1790 | $vmsrvc17 = "VBoxGuest" ascii wide 1791 | $vmsrvc18 = "VBoxSF" ascii wide 1792 | $vmsrvc19 = "xenevtchn" ascii wide 1793 | $vmsrvc20 = "xennet" ascii wide 1794 | $vmsrvc21 = "xennet6" ascii wide 1795 | $vmsrvc22 = "xensvc" ascii wide 1796 | $vmsrvc23 = "xenvdb" ascii wide 1797 | 1798 | // Processes 1799 | $miscproc1 = "vmware2" ascii wide 1800 | $miscproc2 = "vmount2" ascii wide 1801 | $miscproc3 = "vmusrvc" ascii wide 1802 | $miscproc4 = "vmsrvc" ascii wide 1803 | $miscproc5 = "vboxservice" ascii wide 1804 | $miscproc6 = "vboxtray" ascii wide 1805 | $miscproc7 = "xenservice" ascii wide 1806 | 1807 | $vmware_mac_1a = "00-05-69" 1808 | $vmware_mac_1b = "00:05:69" 1809 | $vmware_mac_2a = "00-50-56" 1810 | $vmware_mac_2b = "00:50:56" 1811 | $vmware_mac_3a = "00-0C-29" 1812 | $vmware_mac_3b = "00:0C:29" 1813 | $vmware_mac_4a = "00-1C-14" 1814 | $vmware_mac_4b = "00:1C:14" 1815 | $virtualbox_mac_1a = "08-00-27" 1816 | $virtualbox_mac_1b = "08:00:27" 1817 | 1818 | condition: 1819 | 2 of them 1820 | } 1821 | -------------------------------------------------------------------------------- /peframe/signatures/yara_plugins/pe/packer_compiler_signatures.yar: -------------------------------------------------------------------------------- 1 | /* 2 | This Yara ruleset is under the GNU-GPLv2 license (http://www.gnu.org/licenses/gpl-2.0.html) and open to any user or organization, as long as you use it under this license. 3 | */ 4 | 5 | import "pe" 6 | import "math" 7 | 8 | rule IsPE32 : PECheck 9 | { 10 | condition: 11 | // MZ signature at offset 0 and ... 12 | uint16(0) == 0x5A4D and 13 | // ... PE signature at offset stored in MZ header at 0x3C 14 | uint16(uint32(0x3C)+0x18) == 0x010B 15 | } 16 | 17 | rule IsPE64 : PECheck 18 | { 19 | condition: 20 | // MZ signature at offset 0 and ... 21 | uint16(0) == 0x5A4D and 22 | // ... PE signature at offset stored in MZ header at 0x3C 23 | uint16(uint32(0x3C)+0x18) == 0x020B 24 | } 25 | 26 | rule IsNET_EXE : PECheck 27 | { 28 | condition: 29 | pe.imports ("mscoree.dll","_CorExeMain") 30 | } 31 | 32 | rule IsNET_DLL : PECheck 33 | { 34 | condition: 35 | pe.imports ("mscoree.dll","_CorDllMain") 36 | } 37 | 38 | rule IsDLL : PECheck 39 | { 40 | condition: 41 | // MZ signature at offset 0 and ... 42 | uint16(0) == 0x5A4D and 43 | // ... PE signature at offset stored in MZ header at 0x3C 44 | (uint16(uint32(0x3C)+0x16) & 0x2000) == 0x2000 45 | 46 | } 47 | 48 | rule IsConsole : PECheck 49 | { 50 | condition: 51 | // MZ signature at offset 0 and ... 52 | uint16(0) == 0x5A4D and 53 | // ... PE signature at offset stored in MZ header at 0x3C 54 | uint16(uint32(0x3C)+0x5C) == 0x0003 55 | } 56 | 57 | rule IsWindowsGUI : PECheck 58 | { 59 | condition: 60 | // MZ signature at offset 0 and ... 61 | uint16(0) == 0x5A4D and 62 | // ... PE signature at offset stored in MZ header at 0x3C 63 | uint16(uint32(0x3C)+0x5C) == 0x0002 64 | } 65 | 66 | rule IsPacked : PECheck 67 | { 68 | meta: 69 | description = "Entropy Check" 70 | condition: 71 | // MZ signature at offset 0 and ... 72 | uint16(0) == 0x5A4D and 73 | // ... PE signature at offset stored in MZ header at 0x3C 74 | uint32(uint32(0x3C)) == 0x00004550 and 75 | math.entropy(0, filesize) >= 7.0 76 | } 77 | 78 | 79 | rule HasOverlay : PECheck 80 | { 81 | meta: 82 | author="_pusher_" 83 | description = "Overlay Check" 84 | condition: 85 | // MZ signature at offset 0 and ... 86 | uint16(0) == 0x5A4D and 87 | // ... PE signature at offset stored in MZ header at 0x3C 88 | uint32(uint32(0x3C)) == 0x00004550 and 89 | //stupid check if last section is 0 90 | //not (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size) == 0x0 and 91 | 92 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size) < filesize 93 | 94 | } 95 | 96 | rule HasTaggantSignature : PECheck 97 | { 98 | meta: 99 | author="_pusher_" 100 | description = "TaggantSignature Check" 101 | date="2016-07" 102 | strings: 103 | $a0 = { 54 41 47 47 ?? ?? ?? ?? ?? ?? 00 00 ?? 00 30 82 ?? ?? 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 ?? ?? 30 82 ?? ?? 02 01 01 31 09 30 07 06 05 2B 0E 03 02 1A 30 82 ?? ?? 06 09 2A 86 48 86 F7 0D 01 07 01 A0 82 ?? ?? 04 82 ?? ?? ?? 00 01 00 ?? ?? } 104 | //$c0 = { 06 09 2A 86 } 105 | condition: 106 | // MZ signature at offset 0 and ... 107 | uint16(0) == 0x5A4D and 108 | // ... PE signature at offset stored in MZ header at 0x3C 109 | uint32(uint32(0x3C)) == 0x00004550 and 110 | //TAGG+4E==packerid 111 | //(uint32be(@a0+0x4E) == 0x0B51D132) and 112 | //(uint32be(@a0+0x12) == 0x006092a86) and 113 | //(uint32be(@a0+0x12)) == uint32be(@c0) and 114 | 115 | //uint32be(@a0+0x04) < (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size) and 116 | $a0 117 | } 118 | 119 | 120 | rule HasDigitalSignature : PECheck 121 | { 122 | meta: 123 | author="_pusher_" 124 | description = "DigitalSignature Check" 125 | date="2016-07" 126 | strings: 127 | //size check is wildcarded 128 | $a0 = { ?? ?? ?? ?? 00 02 02 00 30 82 ?? ?? 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 ?? ?? 30 82 ?? ?? 02 01 01 31 0B 30 09 06 05 2B 0E 03 02 1A 05 00 30 68 06 0A 2B 06 01 04 01 82 37 02 01 04 A0 5A 30 58 30 33 06 0A 2B 06 01 04 01 82 37 02 01 0F 30 25 03 01 00 A0 20 A2 1E 80 1C 00 3C 00 3C 00 3C 00 4F 00 62 00 73 00 6F 00 6C 00 65 00 74 00 65 00 3E 00 3E 00 3E 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 } 129 | $a1 = { ?? ?? ?? ?? 00 02 02 00 30 82 ?? ?? 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 ?? ?? 30 82 ?? ?? 02 01 01 31 0B 30 09 06 05 2B 0E 03 02 1A 05 00 30 ?? 06 0A 2B 06 01 04 01 82 37 02 01 04 A0 ?? 30 ?? 30 ?? 06 0A 2B 06 01 04 01 82 37 02 01 0F 30 ?? 03 01 00 A0 ?? A2 ?? 80 00 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 } 130 | $a2 = { ?? ?? ?? ?? 00 02 02 00 30 82 ?? ?? 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 ?? ?? 30 82 ?? ?? 02 01 01 31 0E 30 ?? 06 ?? ?? 86 48 86 F7 0D 02 05 05 00 30 67 06 0A 2B 06 01 04 01 82 37 02 01 04 A0 59 30 57 30 33 06 0A 2B 06 01 04 01 82 37 02 01 0F 30 25 03 01 00 A0 20 A2 1E 80 1C 00 3C 00 3C 00 3C 00 4F 00 62 00 73 00 6F 00 6C 00 65 00 74 00 65 00 3E 00 3E 00 3E 30 20 30 0C 06 08 2A 86 48 86 F7 0D 02 05 05 00 04 } 131 | $a3 = { ?? ?? ?? ?? 00 02 02 00 30 82 ?? ?? 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 ?? ?? 30 82 ?? ?? 02 01 01 31 0F 30 ?? 06 ?? ?? 86 48 01 65 03 04 02 01 05 00 30 78 06 0A 2B 06 01 04 01 82 37 02 01 04 A0 6A 30 68 30 33 06 0A 2B 06 01 04 01 82 37 02 01 0F 30 25 03 01 00 A0 20 A2 1E 80 1C 00 3C 00 3C 00 3C 00 4F 00 62 00 73 00 6F 00 6C 00 65 00 74 00 65 00 3E 00 3E 00 3E 30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 } 132 | condition: 133 | // MZ signature at offset 0 and ... 134 | uint16(0) == 0x5A4D and 135 | // ... PE signature at offset stored in MZ header at 0x3C 136 | uint32(uint32(0x3C)) == 0x00004550 and 137 | (for any of ($a*) : ($ in ( (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size)..filesize)) ) 138 | //its not always like this: 139 | //and uint32(@a0) == (filesize-(pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size)) 140 | } 141 | 142 | rule HasDebugData : PECheck 143 | { 144 | meta: 145 | author = "_pusher_" 146 | description = "DebugData Check" 147 | date="2016-07" 148 | condition: 149 | // MZ signature at offset 0 and ... 150 | uint16(0) == 0x5A4D and 151 | // ... PE signature at offset stored in MZ header at 0x3C 152 | uint32(uint32(0x3C)) == 0x00004550 and 153 | //orginal 154 | //((uint32(uint32(0x3C)+0xA8) >0x0) and (uint32be(uint32(0x3C)+0xAC) >0x0)) 155 | //((uint16(uint32(0x3C)+0x18) & 0x200) >> 5) x64/x32 156 | (IsPE32 or IsPE64) and 157 | ((uint32(uint32(0x3C)+0xA8+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5)) >0x0) and (uint32be(uint32(0x3C)+0xAC+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5)) >0x0)) 158 | } 159 | 160 | rule IsBeyondImageSize : PECheck 161 | { 162 | meta: 163 | author = "_pusher_" 164 | date = "2016-07" 165 | description = "Data Beyond ImageSize Check" 166 | condition: 167 | // MZ signature at offset 0 and ... 168 | uint16(0) == 0x5A4D and 169 | // ... PE signature at offset stored in MZ header at 0x3C 170 | uint32(uint32(0x3C)) == 0x00004550 and 171 | for any i in (0..pe.number_of_sections-1): 172 | ( 173 | (pe.sections[i].virtual_address+pe.sections[i].virtual_size) > (uint32(uint32(0x3C)+0x50)) or 174 | (pe.sections[i].raw_data_offset+pe.sections[i].raw_data_size) > filesize 175 | ) 176 | } 177 | 178 | rule ImportTableIsBad : PECheck 179 | { 180 | meta: 181 | author = "_pusher_ & mrexodia" 182 | date = "2016-07" 183 | description = "ImportTable Check" 184 | condition: 185 | // MZ signature at offset 0 and ... 186 | uint16(0) == 0x5A4D and 187 | // ... PE signature at offset stored in MZ header at 0x3C 188 | uint32(uint32(0x3C)) == 0x00004550 and 189 | (IsPE32 or IsPE64) and 190 | ( //Import_Table_RVA+Import_Data_Size .. cannot be outside imagesize 191 | ((uint32(uint32(0x3C)+0x80+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5) )) + (uint32(uint32(0x3C)+0x84+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5)))) > (uint32(uint32(0x3C)+0x50)) 192 | or 193 | (((uint32(uint32(0x3C)+0x80+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5) )) + (uint32(uint32(0x3C)+0x84+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5)))) == 0x0) 194 | //or 195 | 196 | //doest work 197 | //pe.imports("", "") 198 | 199 | //need to check if this is ok.. 15:06 2016-08-12 200 | //uint32( uint32(uint32(0x3C)+0x80+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5))+uint32(uint32(0x3C)+0x34)) == 0x408000 201 | //this works.. 202 | //uint32(uint32(0x3C)+0x80+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5))+uint32(uint32(0x3C)+0x34) == 0x408000 203 | 204 | //uint32be(uint32be(0x409000)) == 0x005A 205 | //pe.image_base 206 | //correct: 207 | 208 | //uint32(uint32(0x3C)+0x80)+pe.image_base == 0x408000 209 | 210 | //this works (file offset): 211 | //$a0 at 0x4000 212 | //this does not work rva: 213 | //$a0 at uint32(0x0408000) 214 | 215 | //(uint32(uint32(uint32(0x3C)+0x80)+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5))+pe.image_base) == 0x0) 216 | 217 | or 218 | //tiny PE files.. 219 | (uint32(0x3C)+0x80+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5) > filesize) 220 | 221 | //or 222 | //uint32(uint32(0x3C)+0x80) == 0x21000 223 | //uint32(uint32(uint32(0x3C)+0x80)) == 0x0 224 | //pe.imports("", "") 225 | ) 226 | } 227 | 228 | rule ExportTableIsBad : PECheck 229 | { 230 | meta: 231 | author = "_pusher_ & mrexodia" 232 | date = "2016-07" 233 | description = "ExportTable Check" 234 | condition: 235 | // MZ signature at offset 0 and ... 236 | uint16(0) == 0x5A4D and 237 | // ... PE signature at offset stored in MZ header at 0x3C 238 | uint32(uint32(0x3C)) == 0x00004550 and 239 | (IsPE32 or IsPE64) and 240 | ( //Export_Table_RVA+Export_Data_Size .. cannot be outside imagesize 241 | ((uint32(uint32(0x3C)+0x78+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5) )) + (uint32(uint32(0x3C)+0x7C+((uint16(uint32(0x3C)+0x18) & 0x200) >> 5)))) > (uint32(uint32(0x3C)+0x50)) 242 | ) 243 | } 244 | 245 | 246 | rule HasModified_DOS_Message : PECheck 247 | { 248 | meta: 249 | author = "_pusher_" 250 | description = "DOS Message Check" 251 | date="2016-07" 252 | strings: 253 | $a0 = "This program must be run under Win32" wide ascii nocase 254 | $a1 = "This program cannot be run in DOS mode" wide ascii nocase 255 | //UniLink 256 | $a2 = "This program requires Win32" wide ascii nocase 257 | $a3 = "This program must be run under Win64" wide ascii nocase 258 | condition: 259 | // MZ signature at offset 0 and ... 260 | uint16(0) == 0x5A4D and 261 | // ... PE signature at offset stored in MZ header at 0x3C 262 | uint32(uint32(0x3C)) == 0x00004550 and not 263 | (for any of ($a*) : ($ in (0x0..uint32(0x3c) ))) 264 | } 265 | 266 | rule HasRichSignature : PECheck 267 | { 268 | meta: 269 | author = "_pusher_" 270 | description = "Rich Signature Check" 271 | date="2016-07" 272 | strings: 273 | $a0 = "Rich" ascii 274 | condition: 275 | // MZ signature at offset 0 and ... 276 | uint16(0) == 0x5A4D and 277 | // ... PE signature at offset stored in MZ header at 0x3C 278 | uint32(uint32(0x3C)) == 0x00004550 and 279 | (for any of ($a*) : ($ in (0x0..uint32(0x3c) ))) 280 | } 281 | 282 | rule IsSuspicious 283 | { 284 | meta: 285 | author="_pusher_" 286 | date = "2016-07" 287 | description="Might be PE Virus" 288 | condition: 289 | uint32(0x20) == 0x20202020 290 | } 291 | 292 | rule IsGoLink 293 | { 294 | meta: 295 | author="_pusher_" 296 | date = "2016-08" 297 | description="www.GoDevTool.com" 298 | strings: 299 | $a0 = { 47 6F 4C 69 6E 6B } 300 | condition: 301 | // MZ signature at offset 0 and ... 302 | uint16(0) == 0x5A4D and 303 | // ... PE signature at offset stored in MZ header at 0x3C 304 | $a0 at 0x40 305 | 306 | } 307 | 308 | 309 | rule borland_cpp { 310 | meta: 311 | author = "_pusher_" 312 | description = "Borland C++" 313 | date = "2015-08" 314 | version = "0.1" 315 | strings: 316 | $c0 = { 59 5F 6A 00 E8 ?? ?? ?? ?? 59 68 ?? ?? ?? ?? 6A 00 E8 ?? ?? ?? ?? A3 ?? ?? ?? ?? 6A 00 E9 ?? ?? ?? ?? E9 ?? ?? ?? ?? 33 C0 A0 ?? ?? ?? ?? C3 A1 ?? ?? ?? ?? C3 } 317 | $c1 = { A1 ?? ?? ?? ?? C1 E0 02 A3 ?? ?? ?? ?? 52 6A 00 E8 ?? ?? ?? ?? 8B D0 E8 ?? ?? ?? ?? 5A E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 6A 00 E8 ?? ?? ?? ?? 59 68 ?? ?? ?? ?? 6A 00 E8 ?? ?? ?? ?? A3 ?? ?? ?? ?? 6A 00 E9 ?? ?? ?? ?? E9 ?? ?? ?? ?? 33 C0 A0 ?? ?? ?? ?? C3 A1 ?? ?? ?? ?? C3 } 318 | $c2 = { 6A 00 E8 ?? ?? ?? ?? A3 ?? ?? ?? ?? 6A 00 E9 ?? ?? ?? ?? E9 ?? ?? ?? ?? 33 C0 A0 ?? ?? ?? ?? C3 A1 ?? ?? ?? ?? C3 } 319 | condition: 320 | ( 321 | //linker 2.25 and 5.00 322 | ((pe.linker_version.major == 2) and (pe.linker_version.minor == 25 )) or 323 | ((pe.linker_version.major == 5) and (pe.linker_version.minor == 0 )) 324 | ) and 325 | any of them 326 | } 327 | 328 | rule borland_delphi { 329 | meta: 330 | author = "_pusher_" 331 | description = "Borland Delphi 2.0 - 7.0 / 2005 - 2007" 332 | date = "2016-03" 333 | version = "0.2" 334 | strings: 335 | $c0 = { 53 8B D8 33 C0 A3 ?? ?? ?? ?? 6A ?? E8 ?? ?? ?? FF A3 ?? ?? ?? ?? A1 ?? ?? ?? ?? A3 ?? ?? ?? ?? 33 C0 A3 ?? ?? ?? ?? 33 C0 A3 } 336 | $c1 = { 53 8B D8 33 C0 A3 ?? ?? ?? ?? 6A ?? E8 ?? ?? ?? ?? A3 ?? ?? ?? ?? A1 ?? ?? ?? ?? A3 ?? ?? ?? ?? 33 C0 A3 ?? ?? ?? ?? 33 C0 A3 ?? ?? ?? ?? 8D 43 08 A3 ?? ?? ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 8B C3 E8 ?? ?? ?? ?? 5B C3 } 337 | //some x64 version of delphi 338 | $c2 = { 53 48 83 EC 20 48 89 CB C7 05 ?? ?? ?? ?? ?? ?? ?? ?? 48 33 C9 E8 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 48 8D 43 10 48 89 05 ?? ?? ?? ?? 48 8D 05 ?? FC FF FF 48 89 05 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 89 D9 48 8D 15 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 83 C4 20 5B C3 } 339 | //unusual delphi version unknown version (unpackme- FSG 1.31 - dulek) 340 | $c3 = { 50 6A 00 E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 52 89 05 ?? ?? ?? ?? 89 42 04 C7 42 08 00 00 00 00 C7 42 0C 00 00 00 00 E8 ?? ?? ?? ?? 5A 58 E8 ?? ?? ?? ?? C3 } 341 | //delphi2 342 | $c4 = { E8 ?? ?? ?? ?? 6A ?? E8 ?? ?? ?? ?? 89 05 ?? ?? ?? ?? E8 ?? ?? ?? ?? 89 05 ?? ?? ?? ?? C7 05 ?? ?? ?? ?? 0A ?? ?? ?? B8 ?? ?? ?? ?? C3 } 343 | //delphi3 344 | $c5 = { 50 6A 00 E8 ?? ?? FF FF BA ?? ?? ?? ?? 52 89 05 ?? ?? ?? ?? 89 42 04 E8 ?? ?? ?? ?? 5A 58 E8 ?? ?? ?? ?? C3 55 8B EC 33 C0 } 345 | //delphi5 346 | $c6 = { 50 6A ?? E8 ?? ?? FF FF BA ?? ?? ?? ?? 52 89 05 ?? ?? ?? ?? 89 42 04 C7 42 08 ?? ?? ?? ?? C7 42 0C ?? ?? ?? ?? E8 ?? ?? ?? ?? 5A 58 E8 ?? ?? ?? ?? C3 } 347 | condition: 348 | any of them 349 | and 350 | ( 351 | //if its not linker 2.25 its been modified (unpacked usually) 352 | //unknown x64 build of delphi 353 | ((pe.linker_version.major == 2) and (pe.linker_version.minor == 25 )) or ((pe.linker_version.major == 8) and (pe.linker_version.minor == 0 )) 354 | //unpacked files usually have this linker: 355 | or ((pe.linker_version.major == 0) and (pe.linker_version.minor == 0 )) ) 356 | //could check for dvclal.. maybe too much 357 | } 358 | 359 | rule free_pascal { 360 | meta: 361 | author = "_pusher_" 362 | description = "Free Pascal" 363 | date = "2015-08" 364 | version = "0.1" 365 | strings: 366 | $c0 = { 55 89 E5 83 ?? ?? 89 5D FC B8 ?? ?? ?? ?? 50 E8 ?? ?? ?? ?? A0 ?? ?? ?? ?? 84 C0 75 0C 6A 00 E8 ?? ?? ?? ?? A3 ?? ?? ?? ?? A1 ?? ?? ?? ?? A3 } 367 | $c1 = { 55 89 E5 53 B8 ?? ?? ?? ?? 50 E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? 00 75 0C 6A 00 E8 ?? ?? ?? ?? A3 ?? ?? ?? ?? A1 ?? ?? ?? ?? A3 ?? ?? ?? ?? B8 } 368 | $c2 = { 55 89 E5 83 EC 04 89 5D FC B8 ?? ?? ?? ?? 50 E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? A0 ?? ?? ?? ?? 84 C0 75 05 E8 ?? ?? ?? ?? C7 05 } 369 | condition: 370 | any of them 371 | } 372 | 373 | rule borland_delphi_dll { 374 | meta: 375 | author = "_pusher_" 376 | description = "Borland Delphi DLL" 377 | date = "2015-08" 378 | version = "0.1" 379 | info = "one is at entrypoint" 380 | strings: 381 | $c0 = { BA ?? ?? ?? ?? 83 7D 0C 01 75 ?? 50 52 C6 05 ?? ?? ?? ?? ?? 8B 4D 08 89 0D ?? ?? ?? ?? 89 4A 04 } 382 | $c1 = { 55 8B EC 83 C4 ?? B8 ?? ?? ?? ?? E8 ?? ?? FF FF E8 ?? ?? FF FF 8D 40 00 } 383 | condition: 384 | any of them 385 | } 386 | 387 | rule borland_component { 388 | meta: 389 | author = "_pusher_" 390 | description = "Borland Component" 391 | date = "2015-08" 392 | version = "0.1" 393 | strings: 394 | $c0 = { E9 ?? ?? ?? FF 8D 40 00 } 395 | condition: 396 | $c0 at pe.entry_point 397 | } 398 | 399 | rule PureBasic : Neil Hodgson 400 | { 401 | meta: 402 | author="_pusher_" 403 | date="2016-07" 404 | strings: 405 | //make check for msvrt.dll 406 | $c0 = { 55 8B EC 6A 00 68 00 10 00 00 6A ?? FF 15 ?? ?? ?? ?? A3 ?? ?? ?? ?? C7 05 ?? ?? ?? ?? 00 00 00 00 C7 05 ?? ?? ?? ?? 10 00 00 00 A1 ?? ?? ?? ?? 50 6A ?? 8B 0D ?? ?? ?? ?? 51 FF 15 ?? ?? ?? ?? A3 ?? ?? ?? ?? 5D C3 CC CC CC CC CC CC CC CC CC } 407 | $c1 = { 68 ?? ?? 00 00 68 00 00 00 00 68 ?? ?? ?? 00 E8 ?? ?? ?? 00 83 C4 0C 68 00 00 00 00 E8 ?? ?? ?? 00 A3 ?? ?? ?? 00 68 00 00 00 00 68 00 10 00 00 68 00 00 00 00 E8 ?? ?? ?? 00 A3 } 408 | $aa0 = "\x00MSVCRT.dll\x00" ascii 409 | $aa1 = "\x00CRTDLL.dll\x00" ascii 410 | condition: 411 | (for any of ($c0,$c1) : ( $ at pe.entry_point )) and 412 | (any of ($aa*) ) and 413 | ((pe.linker_version.major == 2) and (pe.linker_version.minor == 50 )) 414 | } 415 | 416 | rule PureBasicDLL : Neil Hodgson 417 | { 418 | meta: 419 | author="malware-lu" 420 | strings: 421 | $a0 = { 83 7C 24 08 01 75 ?? 8B 44 24 04 A3 ?? ?? ?? 10 E8 } 422 | 423 | condition: 424 | $a0 at pe.entry_point 425 | } 426 | 427 | rule PureBasic4xDLL : Neil Hodgson 428 | { 429 | meta: 430 | author="malware-lu" 431 | strings: 432 | $a0 = { 83 7C 24 08 01 75 0E 8B 44 24 04 A3 ?? ?? ?? 10 E8 22 00 00 00 83 7C 24 08 02 75 00 83 7C 24 08 00 75 05 E8 ?? 00 00 00 83 7C 24 08 03 75 00 B8 01 00 00 00 C2 0C 00 68 00 00 00 00 68 00 10 00 00 68 00 00 00 00 E8 ?? 0F 00 00 A3 } 433 | 434 | condition: 435 | $a0 at pe.entry_point 436 | } 437 | 438 | rule SkDUndetectabler : SkDrat { 439 | meta: 440 | author = "_pusher_" 441 | condition: 442 | ( 443 | borland_delphi or //check All FSG or 444 | ((pe.linker_version.major == 6) and (pe.linker_version.minor == 0 )) 445 | ) 446 | and 447 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size < filesize) and 448 | //is overlay at offset 2A00,1A00,C00,745,739 449 | //pe.overlay & pe.overlay_size would have been prettier 450 | ( 451 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size == 0x00000739) or 452 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size == 0x00000745) or 453 | //Uncompressed 454 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size == 0x00000C00) or 455 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size == 0x00002A00) or 456 | (pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size == 0x00001A00) 457 | ) 458 | and 459 | //is xored MZ ? 460 | ( 461 | uint16(pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size) == 0x6275 or 462 | uint16(pe.sections[pe.number_of_sections-1].raw_data_offset+pe.sections[pe.number_of_sections-1].raw_data_size) == 0x4057 463 | ) 464 | } 465 | 466 | /* usefull ? 18:53 2016-08-12 467 | rule MicrosoftVisualCV80 468 | { 469 | meta: 470 | author="malware-lu" 471 | strings: 472 | $a0 = { 6A 14 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? BB 94 00 00 00 53 6A 00 8B ?? ?? ?? ?? ?? FF D7 50 FF ?? ?? ?? ?? ?? 8B F0 85 F6 75 0A 6A 12 E8 ?? ?? ?? ?? 59 EB 18 89 1E 56 FF ?? ?? ?? ?? ?? 56 85 C0 75 14 50 FF D7 50 FF ?? ?? ?? ?? ?? B8 } 473 | 474 | condition: 475 | $a0 at pe.entry_point 476 | } 477 | */ 478 | 479 | rule Cygwin : Red Hat 480 | { 481 | meta: 482 | author = "_pusher_" 483 | date = "2016-07" 484 | strings: 485 | $a0 = "cygwin1.dll" ascii nocase 486 | $aa1 = "cygwin_internal" 487 | $aa2 = "cygwin_detach_dll" 488 | condition: 489 | ( 490 | (pe.linker_version.major == 2) and (pe.linker_version.minor == 56 ) or 491 | (pe.linker_version.major == 2) and (pe.linker_version.minor == 24 ) or 492 | (pe.linker_version.major == 2) and (pe.linker_version.minor == 25 ) 493 | ) 494 | and 495 | ($a0 and (any of ($aa*) )) 496 | } 497 | 498 | rule MinGW_1 499 | { 500 | meta: 501 | author = "_pusher_" 502 | date = "2016-07" 503 | strings: 504 | $a0 = "msvcrt.dll" ascii nocase 505 | $aa1 = "Mingw-w64 runtime failure:" 506 | $aa2 = "-LIBGCCW32-EH-3-SJLJ-GTHR-MINGW32" wide ascii nocase 507 | $aa3 = "_mingw32_init_mainargs" 508 | //too wild ? 509 | $aa4 = "mingw32" 510 | $aa5 = "-LIBGCCW32-EH-2-SJLJ-GTHR-MINGW32" wide ascii nocase 511 | $aa6 = "-GCCLIBCYGMING-EH-TDM1-SJLJ-GTHR-MINGW32" wide ascii nocase 512 | $aa7 = "Mingw runtime failure:" 513 | condition: 514 | ( 515 | (pe.linker_version.major == 2) and (pe.linker_version.minor == 56 ) or 516 | (pe.linker_version.major == 2) and ((pe.linker_version.minor >= 21) and (pe.linker_version.minor <= 25)) 517 | ) 518 | and 519 | ($a0 and (any of ($aa*) )) 520 | } 521 | 522 | rule FASM : flat assembler { 523 | //abit weak, needs more targets & testing 524 | meta: 525 | author = "_pusher_" 526 | date = "2016-01" 527 | description = "http://flatassembler.net" 528 | //strings: 529 | //$c0 = { 55 89 E5 83 EC 1C 8D 45 E4 6A 1C 50 FF 75 08 FF 15 ?? ?? ?? ?? 8B 45 E8 C9 C2 04 00 } 530 | condition: 531 | ( 532 | //linker 1.60..1.79 533 | (pe.linker_version.major == 1) and ((pe.linker_version.minor >= 60) and (pe.linker_version.minor < 80)) 534 | ) 535 | //and $c0 536 | } 537 | 538 | rule AutoIt 539 | { 540 | meta: 541 | author = "_pusher_" 542 | date = "2016-07" 543 | description = "www.autoitscript.com/site/autoit/" 544 | strings: 545 | $aa0 = "AutoIt has detected the stack has become corrupt.\n\nStack corruption typically occurs when either the wrong calling convention is used or when the function is called with the wrong number of arguments.\n\nAutoIt supports the __stdcall (WINAPI) and __cdecl calling conventions. The __stdcall (WINAPI) convention is used by default but __cdecl can be used instead. See the DllCall() documentation for details on changing the calling convention." wide ascii nocase 546 | $aa1 = "AutoIt Error" wide ascii nocase 547 | $aa2 = "Missing right bracket ')' in expression." wide ascii nocase 548 | $aa3 = "Missing operator in expression." wide ascii nocase 549 | $aa4 = "Unbalanced brackets in expression." wide ascii nocase 550 | $aa5 = "Error parsing function call." wide ascii nocase 551 | 552 | $aa6 = ">>>AUTOIT NO CMDEXECUTE<<<" wide ascii nocase 553 | $aa7 = "#requireadmin" wide ascii nocase 554 | $aa8 = "#OnAutoItStartRegister" wide ascii nocase 555 | $aa9 = "#notrayicon" wide ascii nocase 556 | $aa10 = "Cannot parse #include" wide ascii nocase 557 | condition: 558 | 5 of ($aa*) 559 | } 560 | 561 | 562 | rule PellesC : Pelle Orinius 563 | { 564 | meta: 565 | author = "_pusher_" 566 | date = "2016-08" 567 | description = "www.smorgasbordet.com/pellesc" 568 | strings: 569 | $aa0 = " -- terminating\x0D\x0A\x00 -- terminating\x0A\x00CRT: \x00unexpected error\x00" wide ascii nocase 570 | $aa1 = "unhandled exception (main)\x00unhandled exception in thread\x00unable to create thread\x00unable to destroy semaphore\x00" wide ascii nocase 571 | $aa2 = "unable to wait on semaphore\x00unable to post semaphore\x00unable to init semaphore\x00unable to unlock mutex\x00unable to lock mutex\x00unable to init mutex\x00" wide ascii nocase 572 | $aa3 = "invalid stream lock number\x00corrupt per-thread data\x00out of memory\x00unable to init threads\x00unable to init HEAP" wide ascii nocase 573 | condition: 574 | 3 of ($aa*) and 575 | (pe.linker_version.major == 2) and (pe.linker_version.minor == 50 ) 576 | } 577 | 578 | rule QtFrameWork 579 | { 580 | meta: 581 | author="_pusher_" 582 | date="2016-08" 583 | strings: 584 | $aa0 = "\x00Qt5Core.dll\x00" ascii 585 | $aa1 = "\x00QtCore4.dll\x00" ascii 586 | condition: 587 | (any of ($aa*) ) 588 | } 589 | 590 | /* usefull ? 18:32 2016-08-10 591 | rule masm32_tasm32 592 | { 593 | meta: 594 | author = "PEiD" 595 | description = "MASM32 / TASM32" 596 | group = "20" 597 | function = "0" 598 | strings: 599 | $a0 = { 6A ?? E8 ?? ?? ?? ?? A3 } 600 | condition: 601 | $a0 602 | } 603 | */ 604 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pefile 2 | python-magic 3 | yara-python 4 | virustotal-api 5 | oletools 6 | M2Crypto -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ---------------------------------------------------------------------- 5 | # This file is part of peframe 6 | # ---------------------------------------------------------------------- 7 | 8 | from setuptools import setup 9 | from codecs import open # To use a consistent encoding 10 | from os import path 11 | 12 | with open('requirements.txt') as f: 13 | required = f.read().splitlines() 14 | 15 | setup( 16 | name='peframe', 17 | version='6.0.3', 18 | 19 | description='peframe is a open source tool to perform static analysis on Portable Executable malware and malicious MS Office documents.', 20 | url='https://github.com/guelfoweb/peframe', 21 | 22 | author='Gianni \'guelfoweb\' Amato', 23 | author_email='guelfoweb@gmail.com', 24 | 25 | license='GNU', 26 | 27 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 28 | classifiers=[ 29 | # How mature is this project? Common values are 30 | # 3 - Alpha 31 | # 4 - Beta 32 | # 5 - Production/Stable 33 | 'Development Status :: 3 - Production/Stable', 34 | 35 | # Indicate who your project is intended for 36 | 'Intended Audience :: Developers', 37 | 'Topic :: Software Development :: Build Tools', 38 | 39 | # Pick your license as you wish (should match "license" above) 40 | 'License :: OSI Approved :: GNU General Public License (GPL)', 41 | 42 | # Specify the Python versions you support here. In particular, ensure 43 | # that you indicate whether you support Python 2, Python 3 or both. 44 | 'Programming Language :: Python :: 3', 45 | 'Programming Language :: Python :: 3.6', 46 | 'Programming Language :: Python :: 3.7', 47 | ], 48 | 49 | keywords='peframe', 50 | 51 | packages=["peframe", "peframe.modules"], 52 | package_data={ 53 | 'peframe': [ 54 | 'config/config-peframe.json', 55 | 'signatures/stringsmatch.json', 56 | 'signatures/yara_plugins/doc/*.yar', 57 | 'signatures/yara_plugins/pdf/*.yar', 58 | 'signatures/yara_plugins/pe/*.yar', 59 | 'signatures/yara_plugins/pe/*.yara', 60 | ], 61 | }, 62 | 63 | install_requires=required, 64 | 65 | entry_points={ 66 | 'console_scripts': [ 67 | 'peframe=peframe.peframecli', 68 | ], 69 | }, 70 | 71 | ) 72 | --------------------------------------------------------------------------------