Tales from the Atlas CORP Web3 Auditing Department
Atlas Corp web3 auditing case study.
Trusting bots with your seed
Note: As this blog is based on a true story, some details such as names and exact use cases have been altered to protect the identity of our clients. The themes and lessons remain valid.
The Bot Heist
When the reward potential is large, one must heed the risks inherent in the game. A client approached us this past summer with news that can make anyone who has been in crypto long enough cringe: “I’ve been hacked”. An EVM wallet used to house NFT assets had somehow been compromised and the NFTs sent to addresses not controlled by the client. The client ran a bot with access to their private keys to automate blockchain activity (e.g. staking, signing messages, etc… – the exact use case withheld to protect the client’s identity). Knowing that Atlas CORP is a premier provider of blockchain analytics and auditing services, they came to us for our help in understanding how this might have happened to prevent future incidents; recognizing that there was little to no hope of actual recovery of the original assets.
When opening an investigation like this, no assumptions should be made. This is crypto; you shouldn’t trust anyone or anything by default. Was the client actually hacked? The client had a third party develop, host, and run a bot for them – was the developer at fault? Was the “hacker” human, or another bot or even smart control protocol? We first went to the blockchain to observe the details of the transfer of the assets to see if they aligned with the story told to us by our client.
There’s were a few things one might be able to surmise by looking at the blockchain event log:
The theft account did not have any obvious correlation to any of the client accounts. A sophisticated user would certainly be able to cover their tracks, but always best to check for obvious outcomes first.
There were no set approval transactions on the NFTs that were stolen in recent history. This makes it a bit more unlikely that it was a smart contract hack.
The hack occurred over several hours. The transfer of NFTs did not occur quickly which is the strongest evidence that this was not done by a bot or programmatic entity. This was also the strongest evidence that this hack was done by a human.
Not everything was taken. This indicates the hack was not as targeted an attack, as a hacker would have done their diligence to understand what assets are in the wallet, and what additional assets are staked in various places around the blockchain that could also be reclaimed and stolen. This was a crime of opportunity and not necessarily premeditated.
So based on a high level observation of the blockchain, we can deduce that:
the claim of a hack can’t be formally ruled out – the client still has the benefit of the doubt.
The actual theft was likely performed by a human and not a bot or smart contract protocol and…
This was likely a crime of opportunity rather than a targeted, premeditated effort.
A deeper dive was commissioned to better understand how this may have happened which involved a thorough review of the source code. The developer of the app provided the code (an action which further puts into question the possibility that the developer was intentionally involved in the hack) and the Atlas CORP team took a look.
Review of a Web3 Bot
When reviewing the bot, we looked at four areas of potential concern:
User security – how are user credentials managed? Extremely important when one credential is a seed phrase with access to high-value NFTs
Database security – How well is the data protected when not in use?
Data transfer security – How well is the data protected when its being moved around or used?
Application Security – Are there vulnerabilities in the code that would allow unprivileged access or exploits?
In this case, we were not expressly able to find a “smoking gun”, but we were able to find a few areas of concern as indicated by our high level summary.
User Security
The application used basic authentication to log in, or a simple user name and password. While this isn’t automatically an issue, it does imply that anyone with access to this information would also have access to the seed phrase (as described later). There was no rate-limiting on password attempts, making the application susceptible to brute-force hacking (though unlikely). Our recommendations to improve included using a more secure hash function and inclusion of 2FA authentication.
Database Security
There were a number of problematic issues with the design of the “database” of the application. Typically data should always be encrypted at rest, whereas both seed phrase information and user password information was stored in plaintext on disk. While the bot code would need to decrypt this data to make use of it, this could make for an issue if anyone got unauthorized access to the server it was being run on (highly problematic if you are running on cloud-provided infrastructure as employees may or may not be able to log into your machines).
Further, elements in the database were named things like “seed” or “seed-phrase”. While not a direct problem, it does provide evidence that a seed phrase is being stored on the device if that text were to show up in application logs or in a filesystem search.
Data Transfer Findings
Data should also always be encrypted in motion (e.g. by using HTTPS). The application transferred data unencrypted, which may have included the seed phrase. It is possible that one would see a seed phrase, next to text including the words “seed phrase” in application traffic logs.
The application also provided endpoints to retrieve the seed phrase. If the data was only available to the bot, then this would have provided evidence that someone gained access to the computer the bot was being run on. There was also a section on the user interface that retrieved and displayed The presence of these functions means that anyone with the basic auth password would have easily been able to retrieve the seed phrase.
Application Security findings
We also reviewed whether there were vulnerabilities in the architecture of the bot application itself that could be used to gain unauthorized access or cause malicious behavior. The bot did not support any kind of input data and instead just gave a series of buttons / GET requests to hit which could be triggered from telegram or the user interface. Aside from the aforementioned design flaws, there didn’t appear to be any other obvious ways to “break” the application to obtain the seed phrase.
Conclusion
Although we were unable to provide hard evidence for the exact cause of the hack, we did provide our best guesses as to what happens in increasing probability of likelihood:
[unlikely but plausible] The cloud server was compromised – either by an employee of the cloud service provider or a random malicious actor – and a search of the logs or of the disk for “seed” revealed the unencrypted database file containing the seed phrase. While unlikely on the major cloud platforms, recent news about deficient security controls at major tech companies implies it can never be truly ruled out.
[possible, but unlikely] The developer of the bot either directly, or more likely indirectly, provided access to the seed. While it’s unlikely that the developer themselves was involved given a history of trust with our client, it is possible that through inadvertent action (committing the database to git, poor security on their own devices containing files or access to servers) compromised access to the client’s seed.
[more likely] Someone gained access to the basic authentication password that unlocks the app and then requested the seed using built-in functions. As the application was a web application it’s highly likely that passwords were saved using a web browser (chrome, safari). If a user were to obtain access to the client’s chrome account (sim swapping, email hacking) and saw the site in the history or bookmarked in the browser, they could visit, log in, and extract the seed.
These possibilities align with what we originally observed on the blockchain – a seemingly random address got access to the valuable account and started slowly moving around valuable items. If the attack had been more targeted the theft would have occurred more quickly, but a malicious actor stumbling upon an unsecured seed phrase would likely look like what we saw.
Design Principles for Securing your Seed
If you’re building bots for web3 use cases, you must respect the seed phrase and protect it at all costs. Some lessons learned from the above audit include the following guiding principles all web3 developers should take to heart:
Determine if seed phrase storage is necessary. If you’re signing messages or committing transactions frequently then there’s no way around a hot wallet being in play. See if your use case allows for authorization tokens to minimize use or movement of a seed phrase.
If storing a seed phrase or password information, always ensure data is encrypted in motion and at rest. This will minimize the possibility that it will be discovered in logs or on disk during searches.
Don’t ever display a seed phrase. You’re not metamask. Don’t ever put a seed phrase on the screen or return it via API call – there’s never a good reason to do so. Just provide an ability to overwrite what’s there.
Practice good web2 security hygiene. Implement 2FA, utilize secure hash functions, rate limit password attemps. Assume everyone is trying to hack you all the time.
Atlas CORP Web3 Auditing Services
If you’re concerned about the security or architecture of a web3 application, feel free to reach out to Atlas CORP to learn more about how we can help. By applying best security practices and performing third party audits prior to deployment, hacks can be better prevented.
We always prefer to do preemptive audits over post-mortems, but we’re happy to help whoever is in need.