Skip to content

About

A proof‑of‑concept demonstration of a simple Windows‑based remote control tool written in Rust.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project Overview

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:

  1. dropper: Downloads the main executable (magzware.exe) and the injector library (rabinolib.dll) into the user’s %APPDATA% folder, then spawns magzware.exe.
  2. magzware: Identifies the explorer.exe process, 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.
  3. 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 via CreateProcessA with output redirection, and forwards the command’s stdout/stderr back over the same TCP connection.
  4. 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

Components & Workflow

  1. dropper/

    • src/main.rs: Downloads magzware.exe and rabinolib.dll into %APPDATA%\Anti virus Zhou Rabinovitch\, then executes magzware.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

  2. magzware/

    • src/main.rs:

      • Locates the PID of explorer.exe.
      • Allocates memory inside that process, writes the path to rabinolib.dll into it, and calls CreateRemoteThread on LoadLibraryA to inject rabinolib.dll.
      • Creates/updates the Run registry key under HKCU\Software\Microsoft\Windows\CurrentVersion\Run so it auto‑launches on user logon.
    • 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

  3. rabinolib/

    • src/lib.rs:

      • In its DllMain, spawns a separate thread that:

        1. Initializes Winsock.

        2. Opens three UDP sockets bound to ports 7000, 8000, and 9000.

        3. Loops on select() until it sees the exact knock sequence (7000 → 8000 → 9000).

        4. Closes the UDP sockets, then opens a TCP socket listening on port 10000 (0.0.0.0:10000).

        5. Calls accept(), blocks until a client connects, then enters a read loop. For each line (command) received over TCP:

          • Uses CreatePipe and CreateProcessA with STARTF_USESTDHANDLES to redirect stdout/stderr of 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, …).
        6. 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

  4. 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:

        1. Prints remote> prompt.
        2. Reads a line from stdin (until \n).
        3. If the line is exit (or EOF), breaks.
        4. Otherwise, sends the line + \n to the TCP connection.
        5. 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.
        6. Repeats.
    • 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

Requirements

  • Rust Toolchain

    • Rust 1.50+
    • MSVC or GNU (MinGW) on Windows; this demo uses the x86_64‑pc‑windows‑gnu target.
  • Network Access

    • A simple HTTP server that serves magzware.exe and rabinolib.dll on 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.

Building & Running

1. Clone & Build Malware Components

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.exe
  • magzware/target/x86_64‑pc‑windows‑gnu/release/magzware.exe
  • rabinolib/target/x86_64‑pc‑windows‑gnu/release/rabinolib.dll

2. Host the Files

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).

3. Execute the Dropper on the Target Machine

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.exe

What happens:

  1. Creates %APPDATA%\Anti virus Zhou Rabinovitch\.
  2. Downloads magzware.exe into the newly created folder under magzware.exe.
  3. Downloads rabinolib.dll into the newly created folder under rabinolib.dll.
  4. Launches magzware.exe.

You might need to disable Windows defender and allow the execution of the dropper.

4. magzware.exe

When magzware.exe runs:

  1. It locates %APPDATA%\Anti virus Zhou Rabinovitch\rabinolib.dll.

  2. 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 load rabinolib.dll.
    • Closes the process handle.
  3. Creates (or updates) the Run key so that on next logon, magzware.exe executes.

  4. Exits.

At this point, rabinolib.dll (now in‑proc inside explorer.exe) has begun running its port‑knocking thread.

5. rabinolib.dll (Injected DLL)

Once rabinolib.dll is loaded into explorer.exe:

  1. Its DllMain sees DLL_PROCESS_ATTACH and spawns a new thread (control_thread).

  2. control_thread initializes Winsock and binds to UDP ports 7000, 8000, and 9000.

  3. It loops, waiting for a knock sequence: receiving one packet on port 7000, then one on 8000, then one on 9000, in that order.

  4. When the sequence is completed, it closes all three UDP sockets and opens a TCP socket on port 10000 (0.0.0.0:10000).

  5. It calls accept(), blocks until a client connects, then enters a read loop. For each line (command) received over TCP:

    • Uses CreatePipe and CreateProcessA with STARTF_USESTDHANDLES to redirect stdout/stderr of 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, …).
  6. 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.

6. Running the Remote Command Client

On a separate machine (or the same machine, adjusting target_ip=127.0.0.1), run:

cd remote-command/
cargo run

If you are using a windows machine, you may need to add the --target x86_64‑pc‑windows‑gnu flag.

Steps:

  1. It performs a UDP knock to <target_ip>:7000, <target_ip>:8000, <target_ip>:9000.

  2. It connects via TCP to <target_ip>:10000.

  3. Enters an interactive prompt:

    remote>
    
  4. Type a command (e.g. whoami) and press Enter.

    • The command is sent to rabinolib.dll in Explorer.
    • The DLL runs whoami.exe with stdout/stderr redirected into a pipe.
    • The DLL reads from the pipe and forwards the string MYMACHINE\Username\r\n back over TCP.
    • The client reads the data and prints it, then re‑prompts:
    remote> whoami
    MYMACHINE\User
    remote>
    
  5. To launch a GUI program (e.g. notepad.exe or calc.exe), type its name. The client will show nothing (because stdout is empty) but the program will open on the target user’s desktop.

  6. Type exit to close the session and terminate the client.

TODO / Future Improvements

  1. Windows Firewall & SmartScreen

    • Currently, the first run of dropper.exe may 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. Parent Process & DLL Persistence

    • Currently, we inject into explorer.exe (which runs under the user context). A reboot will kill it unless Run re‑spawns magzware.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.dll next to a signed Microsoft binary).
      • Implement a stealthier update/check mechanism: only re‑inject if a specific condition is met.

About

A proof‑of‑concept demonstration of a simple Windows‑based remote control tool written in Rust.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages