PowerShell DNS C2

I'd heard about this some time ago and it was one of those things that I wanted to try.  Basically, the idea is that you base64 encode commands and you input the commands as TXT records in DNS.  Then you call those records, decode the payload, and execute it.  Honestly, this would have taken seconds on a Linux machine but it's more like the target would be Windows so I went with PowerShell.  I'm having a love-hate relationship with PowerShell and this, as always, is not elegant but it is functional.

I don't have a screenshot for this first encoding but it's the base64 equivalent of "calc.exe".  We input it as our TXT record and we need to surround each encoded string with quotes:



Looking at the PowerShell below, we're performing a lookup on the record, we're parsing the string to get what's in between the brackets, and then we're executing it:



When we execute our script:



The calculator pops!  Now let's encode a real payload.  We could obviously do any numbers of things but I'm using a base64 encoded reverse shell, I'm calling it with certutil, I'm decoding it, and I'm executing.  Lots of Base64 encoding going on between the C2 and the shell.  ;)



We replace our TXT record with our new string:



And here's where we get into trouble.  If you recall from the commentary above, we are parsing for what is between the brackets.  It's only reading across and not continuing down.  In other words, there is only an open bracket but not a close bracket as far as the script is concerned. 



I tried to make this happen without it getting ugly but no such luck.  So the first thing we do is we remove the carriage returns / line feeds:



Next, we need to remove all of the spaces:



And with that, we have a single string to parse and our payload is sitting between the two brackets once again.  Our final script:



With our handler setup:



Shellz!

I believe there's a 255 character limit on TXT records but I also believe there's a work around for that by using multiple lines.  We could also use multiple records and we could just join the strings.  My character count was half of that so I think we can go a long way without an issue.  Anyway, I don't think I have an actual use for this trick but I thought it was a fun exercise.