Skip to content

Commit

Permalink
Merge pull request #31 from p0dalirius/add-rights-to-shares-command
Browse files Browse the repository at this point in the history
[enhancement] Add READ/WRITE rights in the output table of 'shares' command
  • Loading branch information
p0dalirius authored Jun 13, 2024
2 parents f3f451a + b0462b8 commit 7166880
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 6 deletions.
2 changes: 1 addition & 1 deletion smbclientng/core/CommandCompleter.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ class CommandCompleter(object):
"Lists the SMB shares served by the remote machine.",
"Syntax: 'shares'"
],
"subcommands": []
"subcommands": ["rights"]
},
"tree": {
"description": [
Expand Down
40 changes: 36 additions & 4 deletions smbclientng/core/InteractiveShell.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,21 +825,53 @@ def command_shares(self, arguments, command):
# Active SMB connection needed : Yes
# SMB share needed : No

do_check_rights = False
if len(arguments) != 0:
if arguments[0] == "rights":
do_check_rights = True

shares = self.smbSession.list_shares()
if len(shares.keys()) != 0:
table = Table(title=None)
table.add_column("Share")
table.add_column("Hidden")
table.add_column("Visibility")
table.add_column("Type")
table.add_column("Description", justify="left")
if do_check_rights:
table.add_column("Rights")

for sharename in sorted(shares.keys()):
is_hidden = bool(sharename.endswith('$'))
types = ', '.join([s.replace("STYPE_","") for s in shares[sharename]["type"]])

is_hidden = bool(sharename.endswith('$'))
if is_hidden:
table.add_row(shares[sharename]["name"], str(is_hidden), types, shares[sharename]["comment"])
str_hidden = "[bold bright_blue]Hidden[/bold bright_blue]"
str_sharename = "[bold bright_blue]" + shares[sharename]["name"] + "[/bold bright_blue]"
str_types = "[bold bright_blue]" + types + "[/bold bright_blue]"
str_comment = "[bold bright_blue]" + shares[sharename]["comment"] + "[/bold bright_blue]"
else:
str_hidden = "[bold bright_yellow]Visible[/bold bright_yellow]"
str_sharename = "[bold bright_yellow]" + shares[sharename]["name"] + "[/bold bright_yellow]"
str_types = "[bold bright_yellow]" + types + "[/bold bright_yellow]"
str_comment = "[bold bright_yellow]" + shares[sharename]["comment"] + "[/bold bright_yellow]"

if do_check_rights:
access_rights = self.smbSession.test_rights(sharename=shares[sharename]["name"])
str_access_rights = "[bold yellow]NO ACCESS[/bold yellow]"
if access_rights["readable"] and access_rights["writable"]:
str_access_rights = "[bold green]READ[/bold green], [bold red]WRITE[/bold red]"
elif access_rights["readable"]:
str_access_rights = "[bold green]READ[/bold green]"
elif access_rights["writable"]:
# Without READ?? This should not happen IMHO
str_access_rights = "[bold red]WRITE[/bold red]"
else:
str_access_rights = "[bold yellow]NO ACCESS[/bold yellow]"

if do_check_rights:
table.add_row(str_sharename, str_hidden, str_types, str_comment, str_access_rights)
else:
table.add_row(shares[sharename]["name"], str(is_hidden), types, shares[sharename]["comment"])
table.add_row(str_sharename, str_hidden, str_types, str_comment)

Console().print(table)
else:
Expand Down
43 changes: 42 additions & 1 deletion smbclientng/core/SMBSession.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import impacket.smbconnection
import ntpath
import os
import random
import re
import sys
import traceback
Expand Down Expand Up @@ -1041,6 +1042,44 @@ def umount(self, local_mount_point):
else:
print("[!] Cannot unmount a non existing path.")

# Other functions

def test_rights(self, sharename):
"""
Tests the read and write access rights of the current SMB session.
This method checks the read and write access rights of the current SMB session by attempting to list paths and create/delete temporary directories.
Returns:
dict: A dictionary containing the read and write access rights status.
- "readable" (bool): Indicates if the session has read access rights.
- "writable" (bool): Indicates if the session has write access rights.
"""

# Restore the current share
current_share = self.smb_share
self.set_share(shareName=sharename)

access_rights = {"readable": False, "writable": False}
try:
self.smbClient.listPath(self.smb_share, '*', password=None)
access_rights["readable"] = True
except impacket.smbconnection.SessionError as e:
access_rights["readable"] = False

try:
temp_dir = ntpath.normpath("\\" + ''.join([random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ0123456759") for k in range(16)]))
self.smbClient.createDirectory(self.smb_share, temp_dir)
self.smbClient.deleteDirectory(self.smb_share, temp_dir)
access_rights["writable"] = True
except impacket.smbconnection.SessionError as e:
access_rights["writable"] = False

# Restore the current share
self.set_share(shareName=current_share)

return access_rights

# Setter / Getter

def set_share(self, shareName):
Expand All @@ -1066,7 +1105,9 @@ def set_share(self, shareName):
self.smb_tree_id = self.smbClient.connectTree(self.smb_share)
else:
print("[!] Could not set share '%s', it does not exist remotely." % shareName)

else:
self.smb_share = None

def set_cwd(self, path=None):
"""
Sets the current working directory on the SMB share to the specified path.
Expand Down

0 comments on commit 7166880

Please sign in to comment.