Pennyw0rth / NetExec

The Network Execution Tool
https://netexec.wiki/
BSD 2-Clause "Simplified" License
3.16k stars 345 forks source link

Exception while calling proto_flow() #258

Closed nikaiw closed 6 months ago

nikaiw commented 6 months ago

Exception happens for a particular host during the exception handling.

Steps to reproduce the behavior i.e.: Command: netexec smb particularhost Resulted in:

[20:29:44] ERROR    Exception while calling proto_flow() on target particularhost: 385875968

Calltrace

 ./NetExec/venv/lib/python3.10/site-packages/nxc/protocols/smb.py:605 in create_smbv3_conn    

    602 │                                                                                                    
    603 │   def create_smbv3_conn(self, kdc=""):                                                             
    604 │   │   try:                                                                                         
 ❱  605 │   │   │   self.conn = SMBConnection(                                                               
    606 │   │   │   │   kdc if kdc else self.host,                                                           
    607 │   │   │   │   kdc if kdc else self.host,                                                           
    608 │   │   │   │   None,                                                                                

 ./NetExec/venv/lib/python3.10/site-packages/impacket/smbconnection.py:80 in __init__         

    77 │   │   ##preferredDialect = smb.SMB_DIALECT                                                          
    78 │   │                                                                                                 
    79 │   │   if manualNegotiate is False:                                                                  
 ❱  80 │   │   │   self.negotiateSession(preferredDialect)                                                   
    81 │                                                                                                     
    82 │   def negotiateSession(self, preferredDialect=None,                                                 
    83 │   │   │   │   │   │    flags1=smb.SMB.FLAGS1_PATHCASELESS |                                         
       smb.SMB.FLAGS1_CANONICALIZED_PATHS,                                                                   

./NetExec/venv/lib/python3.10/site-packages/impacket/smbconnection.py:129 in negotiateSession

   126 │   │   │   │   │   │   │   │   │   │   │   │   negSessionResponse=SMB2Packet(packet))                
   127 │   │   │   else:                                                                                     
   128 │   │   │   │   # Answer is SMB packet, sticking to SMBv1                                             
 ❱ 129 │   │   │   │   self._SMBConnection = smb.SMB(self._remoteName, self._remoteHost,                     
       self._myName, hostType,                                                                               
   130 │   │   │   │   │   │   │   │   │   │   │     self._sess_port, self._timeout,                         
       session=self._nmbSession,                                                                             
   131 │   │   │   │   │   │   │   │   │   │   │     negPacket=packet)                                       
   132 │   │   else:                                                                                         

./NetExec/venv/lib/python3.10/site-packages/impacket/smb.py:2519 in __init__                 

   2516 │   │   │   │   │   self.login('', '')                                                               
   2517 │   │   else:                                                                                        
   2518 │   │   │   self._sess = session                                                                     
 ❱ 2519 │   │   │   self.neg_session(negPacket = negPacket)                                                  
   2520 │   │   │   # Call login() without any authentication information to                                 
   2521 │   │   │   # setup a session if the remote server                                                   
   2522 │   │   │   # is in share mode.                                                                      

 ./NetExec/venv/lib/python3.10/site-packages/impacket/smb.py:2734 in neg_session              

   2731 │   │   │   │   return parsePacket(smb)                                                              
   2732 │   │   else:                                                                                        
   2733 │   │   │                                                                                            
 ❱ 2734 │   │   │   return parsePacket( NewSMBPacket( data = negPacket))                                     
   2735 │                                                                                                    
   2736 │   def tree_connect(self, path, password = '', service = SERVICE_ANY):                              
   2737 │   │   LOG.warning("[MS-CIFS] This is an original Core Protocol command.This command                
        has been deprecated.Client Implementations SHOULD use SMB_COM_TREE_CONNECT_ANDX")                    

 ./NetExec/venv/lib/python3.10/site-packages/impacket/smb.py:2685 in parsePacket              

   2682 │   │   │   if smb['Flags2'] & SMB.FLAGS2_UNICODE:                                                   
   2683 │   │   │   │   self.__flags2 |= SMB.FLAGS2_UNICODE                                                  
   2684 │   │   │                                                                                            
 ❱ 2685 │   │   │   if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE):                                             
   2686 │   │   │   │   sessionResponse = SMBCommand(smb['Data'][0])                                         
   2687 │   │   │   │   self._dialects_parameters =                                                          
        SMBNTLMDialect_Parameters(sessionResponse['Parameters'])                                             
   2688 │   │   │   │   self._dialects_data = SMBNTLMDialect_Data()                                          

 ./NetExec/venv/lib/python3.10/site-packages/impacket/smb.py:780 in isValidAnswer             

    777 │   │   │   │   return 1                                                                             
    778 │   │   │   elif self.isMoreProcessingRequired():                                                    
    779 │   │   │   │   return 1                                                                             
 ❱  780 │   │   │   raise SessionError("SMB Library Error", self['ErrorClass'] +                             
        (self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & SMB.FLAGS2_NT_STATUS,                  
        self)                                                                                                
    781 │   │   else:                                                                                        
    782 │   │   │   raise UnsupportedFeature("Unexpected answer from server: Got %d, Expected                
        %d" % (self['Command'], cmd))                                                                        
    783                                                                                                      

Exception during the handling of the exception

During handling of the above exception, another exception occurred:

./NetExec/venv/lib/python3.10/site-packages/nxc/connection.py:143 in __init__             

   140 │   │                                                                                              
   141 │   │   try:                                                                                       
❱  142 │   │   │   self.proto_flow()                                                    
   143 │   │   │                                                                         

./NetExec/venv/lib/python3.10/site-packages/nxc/connection.py:199 in proto_flow           

  196 │   def proto_flow(self):                                                                          
  197 │   │   self.logger.debug("Kicking off proto_flow")                                                
  198 │   │   self.proto_logger()                                                                        
❱ 199 │   │   if self.create_conn_obj():                                                                 
  200 │   │   │   self.logger.debug("Created connection object")                                         
  201 │   │   │   self.enum_host_info()                                                                  
  202 │   │   │   if self.print_host_info() and (self.login() or (self.username == "" and                
      self.password == "")):                                                                             

./NetExec/venv/lib/python3.10/site-packages/nxc/protocols/smb.py:627 in create_conn_obj   

   624 │   │   return True                                                                               
   625 │                                                                                                 
   626 │   def create_conn_obj(self, kdc_host=None):                                                     
❱  627 │   │   return bool(self.create_smbv1_conn(kdc_host) or                                           
       self.create_smbv3_conn(kdc_host))                                                                 
   628 │                                                                                                 
   629 │   def check_if_admin(self):                                                                     
   630 │   │   rpctransport = SMBTransport(self.conn.getRemoteHost(), 445, r"\svcctl",                   
       smb_connection=self.conn)                                                                         

./NetExec/venv/lib/python3.10/site-packages/nxc/protocols/smb.py:622 in create_smbv3_conn 

   619 │   │   │   │   self.logger.fail(f"SMBv3 connection error on {kdc if kdc else                     
       self.host}: {e}")                                                                                 
   620 │   │   │   return False                                                                          
   621 │   │   except (Exception, NetBIOSTimeout) as e:                                                  
❱  622 │   │   │   self.logger.info(f"Error creating SMBv3 connection to {kdc if kdc else                
       self.host}: {e}")                                                                                 
   623 │   │   │   return False                                                                          
   624 │   │   return True                                                                               
   625                                                                                                   

./NetExec/venv/lib/python3.10/site-packages/impacket/smb.py:583 in __str__                

   580 │   │   │   │   error_code_str = '%s(%s)' % error_code                                            
   581 │   │                                                                                             
   582 │   │   if self.nt_status:                                                                        
❱  583 │   │   │   return 'SMB SessionError: %s(%s)' %                                                   
       nt_errors.ERROR_MESSAGES[self.error_code]                                                         
   584 │   │   else:                                                                                     
   585 │   │   │   # Fall back to the old format                                                         
   586 │   │   │   return 'SMB SessionError: class: %s, code: %s' % (error_class_str,                    
       error_code_str)                                                                                   
NeffIsBack commented 6 months ago

Do you know the remote host? Is it a windows or Linux machine?

Marshall-Hallenbeck commented 6 months ago

Hmm weird, 385875968 is 0x17000000, but that code doesn't exist in MS-ERREF. Nothing starting with 0x17 exists either, and the only other reference to that error is old from https://github.com/fortra/impacket/issues/658

nikaiw commented 6 months ago

Sorry, I wanted to add this info. Remote target is a windows. However it seems that it is indeed an impacket issue related to an error code not being handled

reproduced directly with impacket

  File "/home/user/.local/lib/python3.10/site-packages/impacket/smb.py", line 581, in __str__
    return 'SMB SessionError: %s(%s)' % nt_errors.ERROR_MESSAGES[self.error_code]
KeyError: 385875968

A wireshark capture show the server return an error message "Error code: Out of memory" which was probably rarely encountered thus not handled by impacket.

It is handled in SMBv1:

image

But seems not handled in SMBv3:

image

Adding 0x17000000: ("STATUS_MEMORY","Out of memory"), to the impacket file impacket/nt_errors.py fix that.

INFO     Error creating SMBv1 connection to particularhost: SMB SessionError: class: ERRDOS, code: ERRnomem(Insufficient server memory to perform the requested function.)
INFO     Error creating SMBv3 connection to particularhost: SMB SessionError: STATUS_MEMORY(Out of memory)                                                                
mpgn commented 6 months ago

You can open a PR on impacket side ?

mpgn commented 6 months ago

can you make sure you are using latest version of impacket @nikaiw ?

poetry update
poetry run netexec ...
nikaiw commented 6 months ago

hello, I apologize.. using the latest impacket version they indeed handle unkown error message:

[10:55:04] INFO     Socket info: host=redacted, hostname=redacted, kerberos=False, ipv6=False, link-local ipv6=False                                                       
           INFO     Error creating SMBv1 connection to redacted: SMB SessionError: class: ERRDOS, code: ERRnomem(Insufficient server memory to perform the requested function.)
           INFO     Error creating SMBv3 connection to redacted: SMB SessionError: unknown error code: 0x17000000                                                              
           INFO     Failed to create connection object for target redacted, exiting...