coercer.network.smb
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# File name : smb.py 4# Author : Podalirius (@podalirius_) 5# Date created : 17 Sep 2022 6 7 8import sys 9from impacket.dcerpc.v5 import transport 10from impacket.uuid import uuidtup_to_bin 11from impacket.smbconnection import SMBConnection, SMB2_DIALECT_002, SMB2_DIALECT_21, SMB_DIALECT, SessionError 12 13 14def init_smb_session(args, domain, username, password, address, lmhash, nthash, verbose=False): 15 smbClient = SMBConnection(address, args.target_ip, sess_port=int(args.port)) 16 dialect = smbClient.getDialect() 17 if dialect == SMB_DIALECT: 18 if verbose: 19 print("[debug] SMBv1 dialect used") 20 elif dialect == SMB2_DIALECT_002: 21 if verbose: 22 print("[debug] SMBv2.0 dialect used") 23 elif dialect == SMB2_DIALECT_21: 24 if verbose: 25 print("[debug] SMBv2.1 dialect used") 26 else: 27 if verbose: 28 print("[debug] SMBv3.0 dialect used") 29 if args.k is True: 30 smbClient.kerberosLogin(username, password, domain, lmhash, nthash, args.aesKey, args.dc_ip) 31 else: 32 smbClient.login(username, password, domain, lmhash, nthash) 33 if smbClient.isGuestSession() > 0: 34 if verbose: 35 print("[debug] GUEST Session Granted") 36 else: 37 if verbose: 38 print("[debug] USER Session Granted") 39 return smbClient 40 41 42def try_login(credentials, target, port=445, verbose=False): 43 """Documentation for try_login""" 44 # Checking credentials if any 45 if not credentials.is_anonymous(): 46 try: 47 smbClient = SMBConnection( 48 remoteName=target, 49 remoteHost=target, 50 sess_port=int(port) 51 ) 52 smbClient.login( 53 user=credentials.username, 54 password=credentials.password, 55 domain=credentials.domain, 56 lmhash=credentials.lmhash, 57 nthash=credentials.nthash 58 ) 59 except Exception as e: 60 print("[!] Could not login as '%s' with these credentials on '%s'." % (credentials.username, target)) 61 print(" | Error: %s" % str(e)) 62 return False 63 else: 64 return True 65 else: 66 return True 67 68 69def list_remote_pipes(target, credentials, share='IPC$', maxdepth=-1, debug=False): 70 """ 71 Function list_remote_pipes(target, credentials, share='IPC$', maxdepth=-1, debug=False) 72 """ 73 pipes = [] 74 try: 75 smbClient = SMBConnection(target, target, sess_port=int(445)) 76 dialect = smbClient.getDialect() 77 if credentials.doKerberos is True: 78 smbClient.kerberosLogin(credentials.username, credentials.password, credentials.domain, credentials.lmhash, credentials.nthash, credentials.aesKey, credentials.dc_ip) 79 else: 80 smbClient.login(credentials.username, credentials.password, credentials.domain, credentials.lmhash, credentials.nthash) 81 if smbClient.isGuestSession() > 0: 82 if debug: 83 print("[>] GUEST Session Granted") 84 else: 85 if debug: 86 print("[>] USER Session Granted") 87 except Exception as e: 88 if debug: 89 print(e) 90 return pipes 91 92 # Breadth-first search algorithm to recursively find .extension files 93 searchdirs = [""] 94 depth = 0 95 while len(searchdirs) != 0 and ((depth <= maxdepth) or (maxdepth == -1)): 96 depth += 1 97 next_dirs = [] 98 for sdir in searchdirs: 99 if debug: 100 print("[>] Searching in %s " % sdir) 101 try: 102 for sharedfile in smbClient.listPath(share, sdir + "*", password=None): 103 if sharedfile.get_longname() not in [".", ".."]: 104 if sharedfile.is_directory(): 105 if debug: 106 print("[>] Found directory %s/" % sharedfile.get_longname()) 107 next_dirs.append(sdir + sharedfile.get_longname() + "/") 108 else: 109 if debug: 110 print("[>] Found file %s" % sharedfile.get_longname()) 111 full_path = sdir + sharedfile.get_longname() 112 pipes.append(full_path) 113 except SessionError as e: 114 if debug: 115 print("[error] %s " % e) 116 searchdirs = next_dirs 117 if debug: 118 print("[>] Next iteration with %d folders." % len(next_dirs)) 119 pipes = sorted(list(set(["\\PIPE\\" + f for f in pipes])), key=lambda x:x.lower()) 120 return pipes 121 122 123 124def can_connect_to_pipe(target, pipe, credentials, targetIp=None, verbose=False): 125 """ 126 Function can_connect_to_pipe(target, pipe, credentials, targetIp=None, verbose=False) 127 """ 128 ncan_target = r'ncacn_np:%s[%s]' % (target, pipe) 129 __rpctransport = transport.DCERPCTransportFactory(ncan_target) 130 131 if hasattr(__rpctransport, 'set_credentials'): 132 __rpctransport.set_credentials( 133 username=credentials.username, 134 password=credentials.password, 135 domain=credentials.domain, 136 lmhash=credentials.lmhash, 137 nthash=credentials.nthash 138 ) 139 140 if credentials.doKerberos: 141 __rpctransport.set_kerberos(credentials.doKerberos, kdcHost=credentials.kdcHost) 142 if targetIp is not None: 143 __rpctransport.setRemoteHost(targetIp) 144 145 dce = __rpctransport.get_dce_rpc() 146 # dce.set_auth_type(RPC_C_AUTHN_WINNT) 147 # dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 148 149 if verbose: 150 print(" [>] Connecting to %s ... " % ncan_target, end="") 151 sys.stdout.flush() 152 try: 153 dce.connect() 154 except Exception as e: 155 if verbose: 156 print("\x1b[1;91mfail\x1b[0m") 157 print(" [!] Something went wrong, check error status => %s" % str(e)) 158 return None 159 else: 160 if verbose: 161 print("\x1b[1;92msuccess\x1b[0m") 162 return dce 163 164 165def can_bind_to_interface(target, pipe, credentials, uuid, version, targetIp=None, verbose=False): 166 """ 167 Function can_bind_to_interface(target, pipe, credentials, uuid, version, targetIp=None, verbose=False) 168 """ 169 ncan_target = r'ncacn_np:%s[%s]' % (target, pipe) 170 __rpctransport = transport.DCERPCTransportFactory(ncan_target) 171 172 if hasattr(__rpctransport, 'set_credentials'): 173 __rpctransport.set_credentials( 174 username=credentials.username, 175 password=credentials.password, 176 domain=credentials.domain, 177 lmhash=credentials.lmhash, 178 nthash=credentials.nthash 179 ) 180 181 if credentials.doKerberos: 182 __rpctransport.set_kerberos(credentials.doKerberos, kdcHost=credentials.kdcHost) 183 if targetIp is not None: 184 __rpctransport.setRemoteHost(targetIp) 185 186 dce = __rpctransport.get_dce_rpc() 187 # dce.set_auth_type(RPC_C_AUTHN_WINNT) 188 # dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 189 190 if verbose: 191 print(" [>] Connecting to %s ... " % ncan_target, end="") 192 sys.stdout.flush() 193 try: 194 dce.connect() 195 except Exception as e: 196 if verbose: 197 print("\x1b[1;91mfail\x1b[0m") 198 print(" [!] Something went wrong, check error status => %s" % str(e)) 199 return False 200 201 if verbose: 202 print(" [>] Binding to <uuid='%s', version='%s'> ... " % (uuid, version), end="") 203 sys.stdout.flush() 204 try: 205 dce.bind(uuidtup_to_bin((uuid, version))) 206 except Exception as e: 207 if verbose: 208 print("\x1b[1;91mfail\x1b[0m") 209 print(" [!] Something went wrong, check error status => %s" % str(e)) 210 if "STATUS_PIPE_DISCONNECTED" in str(e): 211 # SMB SessionError: STATUS_PIPE_DISCONNECTED() 212 return False 213 elif "STATUS_OBJECT_NAME_NOT_FOUND" in str(e): 214 # SMB SessionError: STATUS_OBJECT_NAME_NOT_FOUND(The object name is not found.) 215 return False 216 elif "STATUS_ACCESS_DENIED" in str(e): 217 # SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.) 218 return False 219 elif "abstract_syntax_not_supported" in str(e): 220 # Bind context 1 rejected: provider_rejection; abstract_syntax_not_supported (this usually means the interface isn't listening on the given endpoint) 221 return False 222 elif "Unknown DCE RPC packet type received" in str(e): 223 # Unknown DCE RPC packet type received: 11 224 return False 225 elif "Authentication type not recognized" in str(e): 226 # DCERPC Runtime Error: code: 0x8 - Authentication type not recognized 227 return False 228 else: 229 return True 230 else: 231 if verbose: 232 print("\x1b[1;92msuccess\x1b[0m") 233 return True
def
init_smb_session( args, domain, username, password, address, lmhash, nthash, verbose=False):
15def init_smb_session(args, domain, username, password, address, lmhash, nthash, verbose=False): 16 smbClient = SMBConnection(address, args.target_ip, sess_port=int(args.port)) 17 dialect = smbClient.getDialect() 18 if dialect == SMB_DIALECT: 19 if verbose: 20 print("[debug] SMBv1 dialect used") 21 elif dialect == SMB2_DIALECT_002: 22 if verbose: 23 print("[debug] SMBv2.0 dialect used") 24 elif dialect == SMB2_DIALECT_21: 25 if verbose: 26 print("[debug] SMBv2.1 dialect used") 27 else: 28 if verbose: 29 print("[debug] SMBv3.0 dialect used") 30 if args.k is True: 31 smbClient.kerberosLogin(username, password, domain, lmhash, nthash, args.aesKey, args.dc_ip) 32 else: 33 smbClient.login(username, password, domain, lmhash, nthash) 34 if smbClient.isGuestSession() > 0: 35 if verbose: 36 print("[debug] GUEST Session Granted") 37 else: 38 if verbose: 39 print("[debug] USER Session Granted") 40 return smbClient
def
try_login(credentials, target, port=445, verbose=False):
43def try_login(credentials, target, port=445, verbose=False): 44 """Documentation for try_login""" 45 # Checking credentials if any 46 if not credentials.is_anonymous(): 47 try: 48 smbClient = SMBConnection( 49 remoteName=target, 50 remoteHost=target, 51 sess_port=int(port) 52 ) 53 smbClient.login( 54 user=credentials.username, 55 password=credentials.password, 56 domain=credentials.domain, 57 lmhash=credentials.lmhash, 58 nthash=credentials.nthash 59 ) 60 except Exception as e: 61 print("[!] Could not login as '%s' with these credentials on '%s'." % (credentials.username, target)) 62 print(" | Error: %s" % str(e)) 63 return False 64 else: 65 return True 66 else: 67 return True
Documentation for try_login
def
list_remote_pipes(target, credentials, share='IPC$', maxdepth=-1, debug=False):
70def list_remote_pipes(target, credentials, share='IPC$', maxdepth=-1, debug=False): 71 """ 72 Function list_remote_pipes(target, credentials, share='IPC$', maxdepth=-1, debug=False) 73 """ 74 pipes = [] 75 try: 76 smbClient = SMBConnection(target, target, sess_port=int(445)) 77 dialect = smbClient.getDialect() 78 if credentials.doKerberos is True: 79 smbClient.kerberosLogin(credentials.username, credentials.password, credentials.domain, credentials.lmhash, credentials.nthash, credentials.aesKey, credentials.dc_ip) 80 else: 81 smbClient.login(credentials.username, credentials.password, credentials.domain, credentials.lmhash, credentials.nthash) 82 if smbClient.isGuestSession() > 0: 83 if debug: 84 print("[>] GUEST Session Granted") 85 else: 86 if debug: 87 print("[>] USER Session Granted") 88 except Exception as e: 89 if debug: 90 print(e) 91 return pipes 92 93 # Breadth-first search algorithm to recursively find .extension files 94 searchdirs = [""] 95 depth = 0 96 while len(searchdirs) != 0 and ((depth <= maxdepth) or (maxdepth == -1)): 97 depth += 1 98 next_dirs = [] 99 for sdir in searchdirs: 100 if debug: 101 print("[>] Searching in %s " % sdir) 102 try: 103 for sharedfile in smbClient.listPath(share, sdir + "*", password=None): 104 if sharedfile.get_longname() not in [".", ".."]: 105 if sharedfile.is_directory(): 106 if debug: 107 print("[>] Found directory %s/" % sharedfile.get_longname()) 108 next_dirs.append(sdir + sharedfile.get_longname() + "/") 109 else: 110 if debug: 111 print("[>] Found file %s" % sharedfile.get_longname()) 112 full_path = sdir + sharedfile.get_longname() 113 pipes.append(full_path) 114 except SessionError as e: 115 if debug: 116 print("[error] %s " % e) 117 searchdirs = next_dirs 118 if debug: 119 print("[>] Next iteration with %d folders." % len(next_dirs)) 120 pipes = sorted(list(set(["\\PIPE\\" + f for f in pipes])), key=lambda x:x.lower()) 121 return pipes
Function list_remote_pipes(target, credentials, share='IPC$', maxdepth=-1, debug=False)
def
can_connect_to_pipe(target, pipe, credentials, targetIp=None, verbose=False):
125def can_connect_to_pipe(target, pipe, credentials, targetIp=None, verbose=False): 126 """ 127 Function can_connect_to_pipe(target, pipe, credentials, targetIp=None, verbose=False) 128 """ 129 ncan_target = r'ncacn_np:%s[%s]' % (target, pipe) 130 __rpctransport = transport.DCERPCTransportFactory(ncan_target) 131 132 if hasattr(__rpctransport, 'set_credentials'): 133 __rpctransport.set_credentials( 134 username=credentials.username, 135 password=credentials.password, 136 domain=credentials.domain, 137 lmhash=credentials.lmhash, 138 nthash=credentials.nthash 139 ) 140 141 if credentials.doKerberos: 142 __rpctransport.set_kerberos(credentials.doKerberos, kdcHost=credentials.kdcHost) 143 if targetIp is not None: 144 __rpctransport.setRemoteHost(targetIp) 145 146 dce = __rpctransport.get_dce_rpc() 147 # dce.set_auth_type(RPC_C_AUTHN_WINNT) 148 # dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 149 150 if verbose: 151 print(" [>] Connecting to %s ... " % ncan_target, end="") 152 sys.stdout.flush() 153 try: 154 dce.connect() 155 except Exception as e: 156 if verbose: 157 print("\x1b[1;91mfail\x1b[0m") 158 print(" [!] Something went wrong, check error status => %s" % str(e)) 159 return None 160 else: 161 if verbose: 162 print("\x1b[1;92msuccess\x1b[0m") 163 return dce
Function can_connect_to_pipe(target, pipe, credentials, targetIp=None, verbose=False)
def
can_bind_to_interface( target, pipe, credentials, uuid, version, targetIp=None, verbose=False):
166def can_bind_to_interface(target, pipe, credentials, uuid, version, targetIp=None, verbose=False): 167 """ 168 Function can_bind_to_interface(target, pipe, credentials, uuid, version, targetIp=None, verbose=False) 169 """ 170 ncan_target = r'ncacn_np:%s[%s]' % (target, pipe) 171 __rpctransport = transport.DCERPCTransportFactory(ncan_target) 172 173 if hasattr(__rpctransport, 'set_credentials'): 174 __rpctransport.set_credentials( 175 username=credentials.username, 176 password=credentials.password, 177 domain=credentials.domain, 178 lmhash=credentials.lmhash, 179 nthash=credentials.nthash 180 ) 181 182 if credentials.doKerberos: 183 __rpctransport.set_kerberos(credentials.doKerberos, kdcHost=credentials.kdcHost) 184 if targetIp is not None: 185 __rpctransport.setRemoteHost(targetIp) 186 187 dce = __rpctransport.get_dce_rpc() 188 # dce.set_auth_type(RPC_C_AUTHN_WINNT) 189 # dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 190 191 if verbose: 192 print(" [>] Connecting to %s ... " % ncan_target, end="") 193 sys.stdout.flush() 194 try: 195 dce.connect() 196 except Exception as e: 197 if verbose: 198 print("\x1b[1;91mfail\x1b[0m") 199 print(" [!] Something went wrong, check error status => %s" % str(e)) 200 return False 201 202 if verbose: 203 print(" [>] Binding to <uuid='%s', version='%s'> ... " % (uuid, version), end="") 204 sys.stdout.flush() 205 try: 206 dce.bind(uuidtup_to_bin((uuid, version))) 207 except Exception as e: 208 if verbose: 209 print("\x1b[1;91mfail\x1b[0m") 210 print(" [!] Something went wrong, check error status => %s" % str(e)) 211 if "STATUS_PIPE_DISCONNECTED" in str(e): 212 # SMB SessionError: STATUS_PIPE_DISCONNECTED() 213 return False 214 elif "STATUS_OBJECT_NAME_NOT_FOUND" in str(e): 215 # SMB SessionError: STATUS_OBJECT_NAME_NOT_FOUND(The object name is not found.) 216 return False 217 elif "STATUS_ACCESS_DENIED" in str(e): 218 # SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.) 219 return False 220 elif "abstract_syntax_not_supported" in str(e): 221 # Bind context 1 rejected: provider_rejection; abstract_syntax_not_supported (this usually means the interface isn't listening on the given endpoint) 222 return False 223 elif "Unknown DCE RPC packet type received" in str(e): 224 # Unknown DCE RPC packet type received: 11 225 return False 226 elif "Authentication type not recognized" in str(e): 227 # DCERPC Runtime Error: code: 0x8 - Authentication type not recognized 228 return False 229 else: 230 return True 231 else: 232 if verbose: 233 print("\x1b[1;92msuccess\x1b[0m") 234 return True
Function can_bind_to_interface(target, pipe, credentials, uuid, version, targetIp=None, verbose=False)