├── dllrunner.exe ├── README.md └── dllrunner.py /dllrunner.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neo23x0/DLLRunner/master/dllrunner.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DLLRunner 2 | ========= 3 | 4 | DLLRunner is a smart DLL execution script for malware analysis in sandbox systems. 5 | 6 | Instead of executing a DLL file via "rundll32.exe file.dll" it analyzes the PE and executes all exported functions by name or ordinal in order to determine if one of the functions causes malicious activity. 7 | 8 | rundll32.exe path/to/file.dll,exportedfunc1 9 | rundll32.exe path/to/file.dll,exportedfunc2 10 | rundll32.exe path/to/file.dll,exportedfunc3 11 | 12 | Furthermore it tries to fuzz parameters in order to trigger acitivity in functions that require parameters to work. 13 | 14 | rundll32.exe path/to/file.dll,exportedfunc1 "0" 15 | rundll32.exe path/to/file.dll,exportedfunc1 "1" 16 | rundll32.exe path/to/file.dll,exportedfunc1 "http://evil.local" 17 | rundll32.exe path/to/file.dll,exportedfunc1 "Install" 18 | ... 19 | 20 | Usage 21 | ========= 22 | 23 | usage: dllrunner.py [-h] [-f dllfile] [-l limit] [--fuzz] [--demo] [--debug] 24 | 25 | DLLRunner 26 | 27 | optional arguments: 28 | -h, --help show this help message and exit 29 | -f dllfile DLL file to execute exported functions 30 | -l limit Only perform extended calls if export function count is less 31 | than limit 32 | --fuzz Add fuzzing parameters to the functions calls (currently 5 33 | params are defined) 34 | --demo Run a demo using \system32\url.dll 35 | --debug Debug output 36 | -------------------------------------------------------------------------------- /dllrunner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: iso-8859-1 -*- 3 | # -*- coding: utf-8 -*- 4 | # 5 | # DLLRunner 6 | # Executes all DLL exports 7 | # 8 | # Florian Roth 9 | # v0.4a 10 | # October 2014 11 | 12 | import os 13 | import pefile 14 | import argparse 15 | import traceback 16 | from subprocess import Popen 17 | 18 | FUZZ_PARAMS = [ 'http://evil.local', '0', '1', 'Install', 'DefaultInstall', '127.0.0.1', '%Temp%\\IXP000.TMP\\' ] 19 | 20 | 21 | def analyze(dll_file): 22 | 23 | # Debug 24 | if args.debug: 25 | print "[+] Analysing: %s" % dll_file 26 | 27 | # Export dictionary 28 | exports = [] 29 | 30 | try: 31 | pe = pefile.PE(dll_file) 32 | 33 | for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols: 34 | # print exp.name, exp.ordinal 35 | exports.append((exp.name, exp.ordinal)) 36 | 37 | return exports 38 | 39 | except Exception, e: 40 | traceback.print_exc() 41 | 42 | finally: 43 | # Info 44 | if args.debug: 45 | print "[+] %s exported functions detected." % len(exports) 46 | return exports 47 | 48 | 49 | def run_extended(dll_file, exports): 50 | 51 | # Loop through detected function exports 52 | for export in exports: 53 | 54 | try: 55 | exp_name = export[0] 56 | exp_ordinal = export[1] 57 | 58 | # Evaluate function identifier 59 | func_ident = exp_ordinal 60 | if exp_name: 61 | func_ident = exp_name 62 | 63 | # Executing exported function 64 | if exp_name: 65 | # Debug output 66 | if args.debug: 67 | print "[+] Advanced Execution: rundll32.exe %s %s" % ( dll_file, func_ident ) 68 | # Executing function 69 | p = Popen(['rundll32.exe', dll_file, func_ident]) 70 | # Fuzzing 71 | if args.fuzz: 72 | for fuzz_param in FUZZ_PARAMS: 73 | # Debug output 74 | if args.debug: 75 | print "[+] Fuzzed Execution: rundll32.exe %s %s %s" % ( dll_file, func_ident, fuzz_param ) 76 | p = Popen(['rundll32.exe', dll_file, func_ident, fuzz_param]) 77 | 78 | except Exception, e: 79 | traceback.print_exc() 80 | 81 | 82 | def run_simple(dll_file): 83 | try: 84 | # Debug output 85 | if args.debug: 86 | print "[+] Simple Executing: rundll32.exe %s" % ( dll_file ) 87 | # Executing function 88 | p = Popen(['rundll32.exe', dll_file]) 89 | except Exception, e: 90 | traceback.print_exc() 91 | 92 | 93 | # MAIN ################################################################ 94 | if __name__ == '__main__': 95 | 96 | # Parse Arguments 97 | parser = argparse.ArgumentParser(description='DLLRunner') 98 | parser.add_argument('-f', metavar="dllfile", help='DLL file to execute exported functions') 99 | parser.add_argument('-l', metavar="limit", help='Only perform extended calls if export function count is less than limit', default=150) 100 | parser.add_argument('--fuzz', action='store_true', default=False, help='Add fuzzing parameters to the functions calls (currently %s params are defined)' % len(FUZZ_PARAMS) ) 101 | parser.add_argument('--demo', action='store_true', default=False, help='Run a demo using \\system32\\url.dll') 102 | parser.add_argument('--debug', action='store_true', default=False, help='Debug output') 103 | 104 | args = parser.parse_args() 105 | 106 | # DLL file 107 | dllfile = args.f 108 | 109 | # Demo mode 110 | if args.demo: 111 | dllfile = "%s\\system32\\url.dll" % os.environ["SYSTEMROOT"] 112 | 113 | # Get all exports 114 | exports = analyze(dllfile) 115 | 116 | # Execute the DLL exports 117 | if len(exports) > int(args.l): 118 | if args.debug: 119 | print "[-] Found more exports than defined via limit (%s)" % args.l 120 | run_simple(dllfile) 121 | else: 122 | run_extended(dllfile, exports) --------------------------------------------------------------------------------