134 lines
3.1 KiB
PowerShell
134 lines
3.1 KiB
PowerShell
|
<#
|
||
|
Simulate-DNSTunnel.ps1
|
||
|
|
||
|
Author: Mariusz Banach (@mgeeky)
|
||
|
License: GPL
|
||
|
Required Dependencies: None
|
||
|
Optional Dependencies: None
|
||
|
|
||
|
#>
|
||
|
|
||
|
$MaxQueryLength = 253
|
||
|
$MaxDnsLabelLength = 63
|
||
|
|
||
|
# Although it can get even up to 127, keeping it lower value may seem more genuine
|
||
|
$MaxNumberOfLevels = 5
|
||
|
|
||
|
|
||
|
function Simulate-DNSTunnel
|
||
|
{
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
|
||
|
Performs DNS Tunnelling simulation.
|
||
|
|
||
|
|
||
|
.DESCRIPTION
|
||
|
|
||
|
This function performs DNS tunelling simulation for purpose
|
||
|
of triggering installed Network IPS and IDS systems. By issuing
|
||
|
DNS queries over system's default resolver, will introduce peak
|
||
|
in high-entropy anomalous queries to be picked up by blue teams.
|
||
|
|
||
|
.PARAMETER Domain
|
||
|
|
||
|
Domain to be queried against randomly generated anomalous-looking long subdomain.
|
||
|
This domain should have a '*' type A record pointing to some IP address
|
||
|
for every wildcard subdomain queried, to avoid subsequent DNS failures.
|
||
|
Also, obviously the domain should be resolveable.
|
||
|
|
||
|
.PARAMETER Interval
|
||
|
|
||
|
This parameter introduces delay between subsequent queries (in seconds). When unset,
|
||
|
every query will be triggered sequentially one after another. Otherwise,
|
||
|
a sleep will be introduced between queries, simulating thus DNS beaconing.
|
||
|
|
||
|
.PARAMETER QueriesNumber
|
||
|
|
||
|
Number of DNS queries to perform. If unset, script will perform inifinite number
|
||
|
of DNS queries. In such case, it can be terminated by CTRL+C.
|
||
|
|
||
|
.EXAMPLE
|
||
|
|
||
|
Simulate-DNSTunnel -Domain google.com
|
||
|
|
||
|
#>
|
||
|
|
||
|
[CmdletBinding()] Param(
|
||
|
[String]
|
||
|
$Domain,
|
||
|
|
||
|
[Double]
|
||
|
$Interval = 0.0,
|
||
|
|
||
|
[Int]
|
||
|
$QueriesNumber = 0
|
||
|
)
|
||
|
|
||
|
$Num = 0
|
||
|
|
||
|
While ( ($Num -lt $QueriesNumber) -or ($QueriesNumber -eq 0))
|
||
|
{
|
||
|
$Num += 1
|
||
|
$Query = Generate-AnomalousQuery -Domain $Domain
|
||
|
|
||
|
If ($Interval -ne 0.0 )
|
||
|
{
|
||
|
Start-Sleep -m ($Interval * 1000)
|
||
|
}
|
||
|
|
||
|
Try
|
||
|
{
|
||
|
Write-Host "[+] $Num. Querying: $Query"
|
||
|
[System.Net.Dns]::GetHostByName($Query).Hostname
|
||
|
}
|
||
|
Catch
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
function Get-RandomString
|
||
|
{
|
||
|
[CmdletBinding()] Param(
|
||
|
[int]
|
||
|
$Count
|
||
|
)
|
||
|
return -join ((65..90) + (97..122) | Get-Random -Count $Count | %{[char]$_})
|
||
|
}
|
||
|
|
||
|
function Generate-AnomalousQuery
|
||
|
{
|
||
|
Param(
|
||
|
[String]
|
||
|
$Domain
|
||
|
)
|
||
|
|
||
|
$QueryToGenerateLen = (Get-Random) % ($MaxQueryLength - $Domain.Length - 1)
|
||
|
$PartLen = [math]::Min($MaxDnsLabelLength, $QueryToGenerateLen)
|
||
|
$NumberOfParts = (Get-Random) % $MaxNumberOfLevels
|
||
|
|
||
|
$Query = ""
|
||
|
|
||
|
For ($i = 0; $i -lt $NumberOfParts; $i++ )
|
||
|
{
|
||
|
$Query += Get-RandomString -Count ($PartLen / $NumberOfParts)
|
||
|
$Query += "."
|
||
|
}
|
||
|
|
||
|
While ($Query.Length -lt $QueryToGenerateLen )
|
||
|
{
|
||
|
$Query += Get-RandomString -Count 1
|
||
|
}
|
||
|
|
||
|
If (($Query.Length + $Domain.Length) -ge ($MaxQueryLength + 1) )
|
||
|
{
|
||
|
$Query = $Query.Substring(0, $MaxQueryLength - $Domain.Length - 1)
|
||
|
}
|
||
|
|
||
|
$Query = $Query -replace "\.\.", "."
|
||
|
|
||
|
$Query += ".$Domain"
|
||
|
return $Query
|
||
|
}
|