Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Data Exfiltration Detection — SIEM & Behavioral Analysis

3-layer detection architecture: Network signatures (Suricata) + Machine learning behavioral analysis (SLIPS + Zeek) + Centralized SIEM correlation with MITRE ATT&CK mapping (Wazuh). Fully open source, Docker-deployable.

Blue Team MITRE ATT&CK Wazuh Docker License


Why Three Layers?

Stealthy exfiltration techniques (DNS tunneling, C2 beaconing, low-and-slow transfers) mimic legitimate traffic and evade traditional signature-based IDS. Each layer targets a different family of indicators:

Layer Tool What It Detects
Network signatures Suricata Known documented threats (Emerging Threats ruleset)
Traffic logging Zeek All network behaviors, without judgment
ML behavioral SLIPS Statistical anomalies, zero-day attacks, DGA, beaconing
SIEM correlation Wazuh Unified view, custom rules, MITRE ATT&CK mapping, active response

Architecture

flowchart TD
    subgraph ATTACKER["🖥️ Compromised Host"]
        W1[DNS Tunneling\nMassive SCP\nLong Connection]
    end

    subgraph SOC["🛡️ SOC Server — Kali Linux"]

        subgraph CAPTURE["Layer 1 · Network Signatures"]
            S[Suricata 8.0.3\nNIDS · Emerging Threats\neve.json]
        end

        subgraph BEHAVIORAL["Layer 2 · Behavioral Analysis"]
            SLIPS[SLIPS + Zeek\nMachine Learning\nDGA · Beaconing · Long Connection\nalerts.json]
            REDIS[Redis\nML Inter-module Bus]
        end

        subgraph SIEM["Layer 3 · SIEM Correlation — Docker single-node"]
            AGT[Wazuh Agent\nLog Collection\nTCP 1514 AES-256]
            MGR[Wazuh Manager\nCustom Rules 100200→100221\nMITRE ATT&CK Mapping]
            IDX[Wazuh Indexer\nOpenSearch]
            DSH[Wazuh Dashboard\nSOC · Alerts · PDF Report]
        end

        subgraph RESPONSE["Active Response"]
            AR[firewall-drop\niptables · 1h block\nRule 100210]
        end
    end

    W1 -->|wlan0| S
    W1 -->|wlan0| SLIPS
    REDIS <-->|internal bus| SLIPS
    S -->|eve.json| AGT
    SLIPS -->|alerts.json| AGT
    AGT -->|TCP 1514 AES-256| MGR
    MGR --> IDX
    IDX --> DSH
    MGR -->|DNS Tunneling detected| AR
Loading

Stack

  • OS: Kali Linux (or any Debian/Ubuntu distribution)
  • Wazuh 4.14.3 (Manager + Indexer + Dashboard) — Docker single-node
  • Suricata 8.0.3 — native on OS
  • SLIPS (StratosphereLinuxIPS, latest) + Zeek (integrated in SLIPS container) — Docker Compose
  • Redis 7 (Alpine) — SLIPS sidecar
  • Docker 29.x + Docker Compose v5.x

Prerequisites

# Check Docker and Docker Compose
docker --version
docker compose version

# Install required tools
sudo apt-get update
sudo apt-get install -y gnupg apt-transport-https suricata

1. Deploying Wazuh (Central SIEM)

1.1 Docker Single-Node Installation

git clone https://github.com/wazuh/wazuh-docker.git -b v4.14.3
cd wazuh-docker/single-node/

# Generate SSL/TLS certificates
docker compose -f generate-indexer-certs.yml run --rm generator

# Start the stack (Manager + Indexer + Dashboard)
docker compose up -d

The Dashboard is accessible at https://<MACHINE_IP> — default credentials: admin / SecretPassword (change immediately).

1.2 Installing Wazuh Agent on the Host

# Import the official GPG key
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring \
  --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
chmod 644 /usr/share/keyrings/wazuh.gpg

# Add the Wazuh 4.x repository
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" \
  | tee -a /etc/apt/sources.list.d/wazuh.list

apt-get update

# Install the agent pointing to the Manager
WAZUH_MANAGER="<MACHINE_IP>" apt-get install wazuh-agent

# Enable and start
systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent

# Verify
systemctl status wazuh-agent

2. Installing and Integrating Suricata

2.1 Installation

sudo apt-get update
sudo apt-get install -y suricata

2.2 Download Emerging Threats Open Rules

cd /tmp
curl -LO https://rules.emergingthreats.net/open/suricata-6.0.8/emerging.rules.tar.gz
sudo tar -xvzf emerging.rules.tar.gz
sudo mkdir -p /etc/suricata/rules
sudo mv rules/*.rules /etc/suricata/rules/
sudo find /etc/suricata/rules -name "*.rules" -exec chmod 777 {} \;

2.3 suricata.yaml Configuration

Edit /etc/suricata/suricata.yaml:

vars:
  address-groups:
    HOME_NET: "[192.168.0.0/16]"   # adapt to your network
    EXTERNAL_NET: "any"

default-rule-path: /etc/suricata/rules
rule-files:
  - "*.rules"

stats:
  enabled: yes

af-packet:
  - interface: eth0    # adapt to your active interface (eth0, wlan0, enp0s3...)
sudo systemctl restart suricata

2.4 Suricata Log Collection by Wazuh Agent

Add to /var/ossec/etc/ossec.conf (agent):

<ossec_config>
  <localfile>
    <log_format>json</log_format>
    <location>/var/log/suricata/eve.json</location>
  </localfile>
</ossec_config>

Suricata alerts are automatically forwarded to Wazuh via the parent rule 86600 (0515-suricata_rules.xml, included by default).


3. Deploying SLIPS + Zeek

Zeek is natively integrated into the SLIPS container — no separate installation needed.

3.1 Directory Structure

mkdir -p ~/slips-docker/{config,output,dataset}
cd ~/slips-docker

3.2 Fetch SLIPS Configuration Files

git clone https://github.com/stratosphereips/StratosphereLinuxIPS.git
cp -r StratosphereLinuxIPS/config ~/slips-docker/config

3.3 docker-compose.yml

services:
  redis:
    image: redis:7-alpine
    container_name: slips-redis
    restart: unless-stopped
    network_mode: host
    command: redis-server --port 6379 --daemonize no

  slips:
    image: stratosphereips/slips:latest
    container_name: slips
    restart: unless-stopped
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: '0.35'
    depends_on:
      - redis
    volumes:
      - ./config:/StratosphereLinuxIPS/config
      - ./output:/StratosphereLinuxIPS/output
      - ./dataset:/StratosphereLinuxIPS/dataset
    entrypoint: [
      "bash", "-c",
      "python3 /StratosphereLinuxIPS/slips.py -i wlan0 -o /StratosphereLinuxIPS/output & sleep 15 && /StratosphereLinuxIPS/webinterface.sh"
    ]

Adapt -i wlan0 to your active network interface. The SLIPS web interface is accessible on port 55001 (to avoid conflict with Wazuh Manager API on port 55000).

3.4 Start

cd ~/slips-docker
docker compose up -d

3.5 SLIPS Alert Collection by Wazuh

Add to /var/ossec/etc/ossec.conf (agent):

<localfile>
  <log_format>json</log_format>
  <location>/home/<user>/slips-docker/output/alerts.json</location>
</localfile>

4. SLIPS → Wazuh Integration: Custom Decoder and Rules

4.1 SLIPS Decoder

Create /var/ossec/etc/decoders/slips_decoders.xml in the Manager container:

<decoder name="Slips">
  <prematch>"Nom": "Slips"</prematch>
</decoder>

<decoder name="Slips">
  <parent>Slips</parent>
  <use_own_name>true</use_own_name>
  <plugin_decoder>JSON_Decoder</plugin_decoder>
</decoder>

4.2 SLIPS Detection Rules with MITRE ATT&CK Mapping

Create /var/ossec/etc/rules/slips_rules.xml in the Manager container:

<!-- Base rule: any SLIPS event -->
<rule id="100200" level="0">
  <decoded_as>Slips</decoded_as>
  <description>SLIPS: JSON event received</description>
  <group>slips,exfiltration,behavioral</group>
</rule>

<!-- DNS Tunneling / DGA — T1071.004 -->
<rule id="100218" level="13">
  <if_sid>100200</if_sid>
  <field name="Description">dns tunneling|dns exfiltration|NXDOMAIN|long subdomain|DGA</field>
  <description>SLIPS: DNS Tunneling exfiltration detected - T1071.004</description>
  <mitre><id>T1071.004</id></mitre>
  <group>slips,exfiltration,dns,</group>
</rule>

<!-- C2 Beaconing — T1071.001 -->
<rule id="100219" level="8">
  <if_sid>100200</if_sid>
  <field name="Description">beaconing|C2|periodic connection</field>
  <description>SLIPS: C2 Beaconing behavior detected - T1071.001</description>
  <mitre><id>T1071.001</id></mitre>
  <group>slips,c2,beaconing,exfiltration,behavioral</group>
</rule>

<!-- Low and Slow persistent connection — T1041 -->
<rule id="100220" level="10">
  <if_sid>100200</if_sid>
  <field name="Description">long connection|persistent connection|Low and Slow</field>
  <description>SLIPS: Suspicious persistent connection - Low and Slow channel - T1041</description>
  <mitre><id>T1041</id></mitre>
  <group>slips,exfiltration,persistence,behavioral</group>
</rule>

<!-- Abnormal upload volume — T1048 -->
<rule id="100221" level="12">
  <if_sid>100200</if_sid>
  <field name="Description">large data upload|volume|traffic</field>
  <description>SLIPS: Abnormal upload volume - Probable exfiltration - T1048</description>
  <mitre><id>T1048</id></mitre>
  <group>slips,exfiltration,traffic,behavioral</group>
</rule>

Apply the files in the Manager container:

docker exec -it single-node-wazuh.manager-1 bash
# Copy files to /var/ossec/etc/decoders/ and /var/ossec/etc/rules/
# Then restart the manager
systemctl restart wazuh-manager

5. Active Response — Automatic DNS Tunneling Blocking

Add to /var/ossec/etc/ossec.conf on the Manager:

<ossec_config>
  <command>
    <name>firewall-drop</name>
    <executable>firewall-drop</executable>
    <timeout_allowed>yes</timeout_allowed>
  </command>

  <active-response>
    <disabled>no</disabled>
    <command>firewall-drop</command>
    <location>local</location>
    <rules_id>100210</rules_id>   <!-- triggers only on SLIPS DNS Tunneling alert -->
    <timeout>3600</timeout>        <!-- IP blocked for 1h, then automatically revoked -->
  </active-response>
</ossec_config>

⚠️ Warning: Enable only after a 1–2 week passive calibration phase to establish a legitimate traffic baseline. SLIPS can generate false positives on normal behaviors (Teams sessions, browsers, CDN) if thresholds are not tuned.


6. Validation Tests

DNS Tunneling (T1071.004)

# PowerShell (from a Windows machine on the same network)
for ($i=1; $i -le 10; $i++) {
  Resolve-DnsName "random-domain-$i.invalid" -ErrorAction SilentlyContinue
}

Expected result: SLIPS generates a HIGH alert (DGA/DNS tunneling detected), correlated in Wazuh as rule 100218 level 13 within ~5 minutes.

Massive SCP Transfer (T1048)

# Create a test file
dd if=/dev/urandom of=/tmp/large-file.bin bs=1M count=150

# Transfer to a target machine
scp /tmp/large-file.bin user@<TARGET_IP>:/tmp/

Expected result: SLIPS reports Large data upload, Wazuh correlates as rule 100221 level 12.

Persistent Low and Slow Connection (T1041)

Open a browser tab pointing to an external address and keep it open for more than 20 minutes. SLIPS reports Long Connection — this scenario also illustrates the false positive case and the need to calibrate long_connection_threshold in slips.yaml.


Detection Coverage

Attack Technique MITRE ID Detected By Wazuh Rule Level
DNS Tunneling / DGA T1071.004 SLIPS + Suricata 100218 13
C2 Beaconing T1071.001 SLIPS 100219 8
Low and Slow Connection T1041 SLIPS + Zeek 100220 10
Large Data Upload T1048 SLIPS 100221 12

References


Author

Yc-jafar — Blue Team | SOC | Threat Detection
Feel free to ⭐ the repo if it helped you, and open an Issue for feedback or improvements!