The NetExec Hackback (CVE-2026-27884)

Introduction

When a pentester runs the spider_plus module with downloading enabled against an SMB share, they expect to be the one in control, but CVE-2026-27884 flips that threat model. A malicious SMB server can exploit NetExec’s trust in server-returned filenames to write arbitrary files on the operator’s own machine. This vulnerability affects NetExec prior to v1.5.1 and all versions of CrackMapExec, which will never receive a patch as the project is deprecated. This post is a full technical walkthrough from the vulnerable code to a working proof of concept.

Background

NetExec is a network security testing tool and the actively maintained successor to CrackMapExec. It supports multiple protocols including SMB, RDP, WinRM, FTP, and more. The tool is comprehensive, covering everything from basic security misconfiguration scanning to lateral movement and post-exploitation techniques such as credential harvesting.

When scanning SMB shares, a common challenge is the sheer volume of files across multiple shares. This is where the spider_plus module comes in. It crawls SMB shares and generates a JSON file logging all discovered files and their paths, making it easy to grep through filenames and content. With DOWNLOAD=true, it will also pull every file down to the operator’s machine for offline review. A common workflow is to exploit Guest access to download all accessible SMB files:

1
nxc smb 192.168.1.0/24 -u Guest -p '' -M spider_plus -o DOWNLOAD=true

Downloaded files are saved to ~/.nxc/modules/nxc_spider_plus/<IP>/ on the attacker’s machine, preserving the original share and directory structure.

The Vulnerability

The vulnerability lies within the get_file_save_path function in nxc/modules/spider_plus.py. It replaces slashes with the path separator for the current OS, then joins the result with the local output folder path. The function fails to sanitize directory traversal sequences, meaning a malicious SMB server can return a filename containing ../ sequences that escape the intended output directory entirely.

The vulnerable code in spider_plus.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
        # Remove the backslash before the remote host part and replace slashes with the appropriate path separator
        remote_file_path = str(remote_file)[2:].replace("/", sep).replace("\\", sep)

        # Split the path to obtain the folder path and the filename
        folder, filename = split(remote_file_path)

        # Join the output folder with the folder path to get the final local folder path
        folder = join(self.output_folder, folder)

        return folder, filename

The problem is on the final join() call. It blindly combines the output folder with whatever path the server returned. Python’s os.path.join() does not sanitize its inputs, meaning if remote_file_path contains ../ sequences, they are preserved and resolved by the filesystem:

1
2
join("/home/pentester/.nxc/modules/nxc_spider_plus", "SHARE/../../../../.bashrc")
# resolves to: /home/pentester/.bashrc

There is no check to verify the resulting path stays within the intended output directory. The server controls the filename, and the client trusts it completely.

Building the malicious SMB Server

A full PoC is on my GitHub, but let’s go over the key caveats. When building this exploit using impacket, it has an isInFileJail check in smbserver.py that blocks path traversals, so we patch it out:

1
impacket.smbserver.isInFileJail = lambda path, file_name: True

The share directory must also be the same number of levels deep as the traversal depth. This is because impacket resolves the file path from the share directory when serving the file to the client. For every ../ in the traversal, impacket walks one directory up, so if the share directory is not deep enough, the traversal will overshoot past the server’s home directory to a path that doesn’t exist and the download will fail:

1
2
3
TARGET_FILE = "nxc_test_exploit.txt"
SHARE_DIR   = os.path.join(HOME, "1", "2","3","4","5")
TRAVERSAL   = f"..\\..\\..\\..\\..\\{TARGET_FILE}"

Running the PoC SMB server, we can write nxc_test_exploit.txt directly to the victim’s home directory:

NetExec arbitrary file write PoC

Figure 1: NetExec spider_plus writing nxc_test_exploit.txt to the victim’s home directory via path traversal

Overwriting sensitive files

Writing a file to the home directory proves the arbitrary write primitive, but the real impact depends on what the attacker chooses to overwrite. Any file writable by the user running NetExec is a valid target:

FilePrivileges RequiredImpact
~/.bashrcUserCode execution on next shell open
~/.ssh/authorized_keysUserPersistent SSH access
~/.nxcUserTamper with NetExec config itself
/etc/passwdRootAdd backdoor user
/etc/cron.d/backdoorRootPersistent code execution via cron

The only change required to escalate to code execution is the target filename and payload:

1
2
3
TARGET_FILE = ".bashrc"
PAYLOAD     = "#!/bin/bash\n"
PAYLOAD    += "echo 'Your NetExec is hacked!' > /tmp/HACKED.txt\n"

.bashrc is sourced automatically the next time the victim opens a shell. After running the PoC and opening a new terminal, code execution is confirmed:

NetExec .bashrc overwrite PoC

Figure 2: NetExec downloading the malicious .bashrc and confirming code execution on exec bash

The Patch

The patch was merged in v1.5.1 and completely replaces the vulnerable get_file_save_path function with three key changes:

1. PurePosixPath instead of raw string manipulation, parsing the path properly rather than blindly replacing separators:

1
raw_path = PurePosixPath(remote_file._RemoteFile__share, remote_file._RemoteFile__fileName.replace("\\", "/"))

2. Explicit traversal stripping, filtering out every .. and . component before the path is ever used:

1
clean_parts = [p for p in raw_path.parts if p not in ("..", ".")]

3. Safe path joining, building the final path from clean individual components rather than concatenating raw strings:

1
resolved = Path(self.output_folder).joinpath(self.host, *clean_parts)

Responsible Disclosure Timeline

TimeEvent
Feb 21, 2026 — 2:00 PMReached out to a maintainer to report the vulnerability
Feb 21, 2026 — 2:30 PMMaintainer responded — provided PoC and proof of exploitation
Feb 21, 2026 — 3:12 PMOpened a public GitHub issue upon maintainer request
Feb 21, 2026 — 4:10 PMMaintainer released patch code in PR #1121
Feb 23, 2026NetExec v1.5.1 released with official patch tag
Feb 24, 2026GitHub publishes CVE-2026-27884

Conclusion

CVE-2026-27884 is a good reminder that even the tools we use to hack and scan our clients are not immune to vulnerabilities. A single missing path sanitization check in spider_plus is enough to turn a routine SMB enumeration into an arbitrary file write against the operator’s own machine. In hindsight, I probably should have stood up a public honeypot and let ransomware actors spider it, purely for research purposes of course (joking). If you are running NetExec, update to v1.5.1 or later. If you are running CrackMapExec, migrate to NetExec as the project is deprecated and will never receive a patch. The full PoC is available on my GitHub.

0%