fortra / impacket

Impacket is a collection of Python classes for working with network protocols.
https://www.coresecurity.com
Other
13.49k stars 3.57k forks source link

Feature Request: SMBConnection Share Walking #1766

Open Script-Nomad opened 4 months ago

Script-Nomad commented 4 months ago

Configuration

impacket version: 0.11.0 Python version: 3.12.0 Target OS: Debian/Ubuntu

I'm working on some additional functionality for impacket to augment the SMBConnection class so that it can be used for remotely searching through open SMB shares for grepping and permissions checks and so forth without creating an interactive shell.

My use-case is that I am trying to simulate a ransomware attack for a client, and impacket has almost everything I need except for a walk() function.

In the smbprotocol library for python, this is as simple as root, subs, files = smbclient.walk() very similar to the os.walk() method

I'm trying to implement this myself manually, and if I manage to succeed, I'd be happy to submit a pull request, but before I go re-inventing the wheel, I'd appreciate the dev teams' input for this.

I've been reviewing the do_mget functionality for the smbclient.py example, but since it is only passing back filepaths and doing the smb.getFile() method, it's not quite what I need. We manually implemented something similar using the smbprotocol's walk() and stat() functions, but I can't pass the impacket connection to a different smbclient very elegantly. It would be far nicer to implement this functionality within the SMBConnection class itself.

Use-case example:

Dependency: python3 -m pip install smbprotocol

import smbclient

for dirpath, dirnames, filenames in smbclient.walk(path):
                for f in filenames:
                    file_path = os.path.join(dirpath, f)
                    file_info = smbclient.stat(file_path)
                    f_perm = file_info.st_mode

                    # list the SMB perms as reported by the server
                    perm_str = ""
                    perm_str += "d" if stat.S_ISDIR(f_perm) else "-"
                    perm_str += "r" if f_perm & stat.S_IRUSR else "-"
                    perm_str += "w" if f_perm & stat.S_IWUSR else "-"
                    perm_str += "x" if f_perm & stat.S_IXUSR else "-"
                    perm_str += "r" if f_perm & stat.S_IRGRP else "-"
                    perm_str += "w" if f_perm & stat.S_IWGRP else "-"
                    perm_str += "x" if f_perm & stat.S_IXGRP else "-"
                    perm_str += "r" if f_perm & stat.S_IROTH else "-"
                    perm_str += "w" if f_perm & stat.S_IWOTH else "-"
                    perm_str += "x" if f_perm & stat.S_IXOTH else "-"
                    log.info(f"File: {file_path}\nServer Reported Permissions: {perm_str}")
p0dalirius commented 2 months ago

Hey @Script-Nomad,

I have implemented it in smbclient-ng:

If you are interested in understanding the implementation: https://github.com/p0dalirius/smbclient-ng/blob/main/smbclientng/core/SMBSession.py#L226-L274

Maybe I will make a PR to impacket, but I am tired of making pull requests with everything fixed and then wait 6 months to a few years for them to be merged...

Best regards,

Script-Nomad commented 1 month ago

@p0dalirius Thank you for this. Seems like a very tidy implementation, and I like the simplicity of the callback on each SMB file/dir entry. Sadly the engagement I needed it for is already finished with my very janky solution, but it may come up again in the future. You, sir, have earned a star :)