Saturday, April 7, 2012

Detecting honeypots using unique binaries

Most of us use online services like Virustotal, Threatexpert etc to get a quick analyze of newly "acquired" malware, it's fast and can quickly help us distinguish known malware from the not so known ones.

Virustotal had a functions, back in the day to enable the uploader to disallow VT to spread the sample to the connected AV vendors. This functions was abused by malware authors and thus removed.

The current situation is that all malware uploaded to VT is easily searchable for both security researchers and malware creators/distributors alike.

My idea or rather my thought (This might not be so novel and yes others have come to the same conclusions before) was that this creates a "great" way for an attacker to learn when he/she is discovered or a way to detect honeypots using unique binaries.

If malware authors starts to uses unique binaries(if they have not already..) not only as today to lure AV vendors but to pinpoint infections points and adversaries, this could have a very harming effect on security research as a whole. SPAM distributors have been using uniqueness as a way to verify email accounts for years.

This method could be extended to web applications attacks as well, using unique strings and data mine reports from the security community. And then it's just a matter of remembering which binary or web request was sent to which host.

A simple PoC has been developed that can detect the Dionaea honeypot (with VT submit enabled, it queries VT for verification) or other SMB honeypots.

The use of Dionaea was mostly because I have a couple of installations running, but this can be used against any kind of honeypot (as long as it(or the admin) shares information that you can data mine).

I hope this gives you some idea, about the pitfalls with information sharing. Which is a wonderful "tool" for researcher to gain knowledge from systems besides their own, but it can also tip of a attacker that you are on to them. So if you get compromised, uploading the malware to VT might not be the help you where looking for.

The script below will most certainly not make it into the Nmap NSE script library as it uses a couple of shell functions, but it will work under most *nix variants. It also required a valid VT API key which you can get from the VT site.  

You will also have to configure the script to use a binary of your choice. And one last thing I somewhat deliberately did not create this script for speed. Default sleep time for the script before checking with virustotal is 20 min, this should be enough time for the honeypot to upload the binary and for virustotal to process it.   

Script output (if successful):
--Host script results:                                                                                                                                                               ---|_honeydetect: Binary detected by Virustotal, host most likely a Honeypot!

The script creates a file called hash.log, which contains the hostname of the host you scanned and the current hash. This can be useful if you scan multiple hosts or is the 20 min is not enough. This way you can manually check with VT afterwards. 

cat hash.log
localhost: 8ddf5b6c575cec55c5f1b1f8b984b178

The script searches for MD5 sums but VT presents the findings with a sha254 checksum.

sha256sum nping.exe
4753e5a9b8c1b53aa72cf45a193a8e4138099db84fcf33ac4b74d4e77e53321e  nping.exe

As you can see the file sent to the honeypot is the same as the one uploaded to VT
description = [[

Detect honeypots (like Dionaea) targeting the smb service and using Virustotal hash search for verification.
This is to be considered a PoC of a method of mapping honeypots and not an attack against Dionaea itself.

The code below could for example be extended to target other services(like FTP, HTTP etc) and also split the honeypot file upload and the Virustotal hash search to speed up detection for larger address ranges

Detection of honeypots is a double edged sword, we rely on them to catch new vulnerabilities and malware targeting common used services. But the presence of a honeypot can be a sign of vigilant opponent and could be used against the organizations that hosts the honeypot.

Please see my blog: for more information.


--- Output
--Host script results:                                                                                                                                                               ---|_honeydetect: Binary detected by Virustotal, host most likely a Honeypot!

author = "Mikael Keri"
license = "Same as Nmap--See"
categories = {"default", "discovery", "safe"}

require 'http'
require 'stdnse'
require 'smb'

hostrule = function(host)
        return smb.get_port(host) ~= nil

--- Get your VirusTotal API key from the
 local VTAPI = "XXX"

--- Name of binary and path to it
local BIN = "XXX"

-- This just takes a binary of your choice and adds a random string at the end of the file, very low tech. The reason to use a "real" file was in case the honeypot uses PEID or similar to determine if the uploaded file really is a binary.
 local RANDY = (math.random(10, 99999))
 file = io.output(, "a+"))

action = function(host)

 name = stdnse.get_hostname(host)
-- Get the Hash of the binary
-- OSX change to "md5 -q"
local ET = ("md5sum " .. BIN)
local BINHASH = io.popen(ET .. "| awk {' print $1 '}"):read'*l'

-- Write the hash to file .. just in case Virustotal is not able to process it during the 20 min this script waits..or if you would like to scan larger nets. Remove the sleep part
-- and process the hash.log file afterwards.
local hashf = io.output("hash.log", "a"))
   io.write(name ..": " .. BINHASH .."\n")

--- Upload the file to the "honeypot"
    local UPLOAD = ("smbclient //localhost/test -N -c='put " .. BIN .. "'
>/dev/null 2>&1")

--- Give the honeypot a chance to upload the file to .. sleep 20 min

--- Check with Virustotal to see what they say..
     local headers = {["Content-Type"] = "application/x-www-form-urlencoded"}
     local postdata = "resource=" .. BINHASH .. "&apikey=" .. VTAPI .. ""
     local body ="", 443, "/vtapi/v2/file/report", {["header"]=headers}, nil, postdata).body

     if string.find(body, 'response_code": 0') then
            return "Binary not uploaded to Virustotal"
         elseif string.find(body, 'response_code": 1') then
            return "Binary detected by Virustotal, host most likely a Honeypot!"



This area of research is quite fascinating so I'm looking forward to comment or future research ideas.

Thanks to @nevdull77 for his help!

Update: fixed a syntax error in the script


No comments:

Post a Comment