2727from impacket .dcerpc .v5 .dtypes import NULL
2828from impacket .dcerpc .v5 .dcomrt import DCOMConnection
2929from impacket .dcerpc .v5 .dcom .wmi import CLSID_WbemLevel1Login , IID_IWbemLevel1Login , IWbemLevel1Login
30+ from impacket .smb3structs import FILE_SHARE_WRITE , FILE_SHARE_DELETE
3031
3132from nxc .config import process_secret , host_info_colors
3233from nxc .connection import connection , sem , requires_admin , dcom_FirewallChecker
@@ -774,6 +775,7 @@ def ps_execute(self, payload=None, get_output=False, methods=None, force_ps32=Fa
774775
775776 def shares (self ):
776777 temp_dir = ntpath .normpath ("\\ " + gen_random_string ())
778+ temp_file = ntpath .normpath ("\\ " + gen_random_string () + ".txt" )
777779 permissions = []
778780
779781 try :
@@ -812,6 +814,8 @@ def shares(self):
812814 share_info = {"name" : share_name , "remark" : share_remark , "access" : []}
813815 read = False
814816 write = False
817+ write_dir = False
818+ write_file = False
815819 try :
816820 self .conn .listPath (share_name , "*" )
817821 read = True
@@ -823,18 +827,40 @@ def shares(self):
823827 if not self .args .no_write_check :
824828 try :
825829 self .conn .createDirectory (share_name , temp_dir )
826- write = True
827- share_info ["access" ].append ("WRITE" )
830+ write_dir = True
831+ try :
832+ self .conn .deleteDirectory (share_name , temp_dir )
833+ except SessionError as e :
834+ error = get_error_string (e )
835+ if error == "STATUS_OBJECT_NAME_NOT_FOUND" :
836+ pass
837+ else :
838+ self .logger .debug (f"Error DELETING created temp dir { temp_dir } on share { share_name } : { error } " )
828839 except SessionError as e :
829840 error = get_error_string (e )
830841 self .logger .debug (f"Error checking WRITE access on share { share_name } : { error } " )
831842
832- if write :
843+ try :
844+ tid = self .conn .connectTree (share_name )
845+ fid = self .conn .createFile (tid , temp_file , desiredAccess = FILE_SHARE_WRITE , shareMode = FILE_SHARE_DELETE )
846+ self .conn .closeFile (tid , fid )
847+ write_file = True
833848 try :
834- self .conn .deleteDirectory (share_name , temp_dir )
849+ self .conn .deleteFile (share_name , temp_file )
835850 except SessionError as e :
836851 error = get_error_string (e )
837- self .logger .debug (f"Error DELETING created temp dir { temp_dir } on share { share_name } : { error } " )
852+ if error == "STATUS_OBJECT_NAME_NOT_FOUND" :
853+ pass
854+ else :
855+ self .logger .debug (f"Error DELETING created temp file { temp_file } on share { share_name } " )
856+ except SessionError as e :
857+ error = get_error_string (e )
858+ self .logger .debug (f"Error checking WRITE access with file on share { share_name } : { error } " )
859+
860+ # If we either can create a file or a directory we add the write privs to the output. Agreed on in https://github.com/Pennyw0rth/NetExec/pull/404
861+ if write_dir or write_file :
862+ write = True
863+ share_info ["access" ].append ("WRITE" )
838864
839865 permissions .append (share_info )
840866
0 commit comments