Skip to content

Commit 754ca2d

Browse files
authored
Merge pull request Pennyw0rth#404 from tiyeuse/main
Add file write check on smb
2 parents e1c6635 + f17a61f commit 754ca2d

1 file changed

Lines changed: 31 additions & 5 deletions

File tree

nxc/protocols/smb.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from impacket.dcerpc.v5.dtypes import NULL
2828
from impacket.dcerpc.v5.dcomrt import DCOMConnection
2929
from impacket.dcerpc.v5.dcom.wmi import CLSID_WbemLevel1Login, IID_IWbemLevel1Login, IWbemLevel1Login
30+
from impacket.smb3structs import FILE_SHARE_WRITE, FILE_SHARE_DELETE
3031

3132
from nxc.config import process_secret, host_info_colors
3233
from 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

Comments
 (0)