Youโve undoubtedly heard a lot of buzz around blockchain technology: some people see it as a revolution in data security and others just think itโs a fad that will go away. As cybersecurity experts, we recognize that blockchains are here to stay.
Having spent time working on them, our team has a good understanding of the pros and cons of blockchain technology. Our desire to share this experience prompted us to start a new series dedicated to analyzing different blockchain vulnerabilities. In this article, we take a look at EOS smart contract vulnerabilities that are inherent to the particular implementation of the smart contract in this blockchain.
Contents
What is EOS?
EOS is an emerging blockchain network whose creation was announced in May 2017 by the block.one team. The EOS mainnet was successfully launched on June 9, 2018. From the very beginning, EOS creators from the block.one startup planned to achieve support for millions of simultaneous blockchain transactions and thousands of applications by using parallel processing and asynchronous communication of smart contracts.
The EOS network was designed with scalability in mind. Here are some of its main advantages:
- Low transaction latency
- Free transactions for every account
- Easy inter-blockchain communication
This level of scalability was achieved mostly thanks to structuring the EOS network similarly to an operating system. And the smart contract approach plays a significant part in ensuring this systemโs stability and scalability. But as it turns out, smart contracts are also a source of major vulnerabilities in the EOS blockchain.
EOS smart contracts
Itโs noteworthy that different cryptocurrencies implement different types of smart contracts. Smart contracts are essentially computer protocols used for digitally facilitating, verifying, and enforcing the execution and negotiation of contracts. Smart contracts allow network users to avoid unnecessary involvement of third parties when performing credible transactions while keeping all these transactions trackable and irreversible.
In EOS, smart contracts are implemented as applications running under the operating system. The EOS network is responsible for allocating computational resources such as RAM, CPU time, and network bandwidth. However, the programming language for this operating system is left unspecified by the EOS whitepaper:
The details of scripting language and virtual machine are implementation specific details that are mostly independent from the design of the EOS.IO technology. Any language or virtual machine that is deterministic and properly sandboxed with sufficient performance can be integrated with the EOS.IO software API.
In the end, the EOS developers decided that the most efficient solution would be to use WebAssembly (WASM), a low-level assembly-like language and an emerging industry standard backed by Microsoft, Google, and Apple.
Exceptional performance is achieved by compiling WASM to native x86 instructions, thus enabling WASM apps to run at about 80% the speed of native x86 apps. Initial single-threaded benchmarks have shown performance of ~50,000 transactions per second.
One of the best things about using WASM is that EOS smart contracts can be written in any programming language that compiles to WASM. The most popular and officially supported language is C++.
However, the use of C++ also opens the EOS network to potential vulnerabilities. In fact, all that hackers need to do to compromise the network is to compile vulnerable code written in C or C++ into WASM and execute this code in the EOS network.
Letโs take a detailed look at a recently discovered vulnerability in the EOS smart contract system caused by vulnerable C++ code.
EOS node remote code execution vulnerability
In May 2018, just a few weeks prior to the official launch of EOS, a team of security researchers from Qihoo 360 discovered a critical EOS smart contract vulnerability posing a serious cybersecurity threat to the entire network.
The EOS node remote code execution vulnerability comes from an incorrect check for array bounds in libraries/chain/webassembly/binaryen.cpp (line 76 in the code below) in the function binaryen_runtime::instantiate_module:
Here is the vulnerable fragment of code:
for (auto& segment : module->table.segments) {
Address offset = ConstantExpressionRunner<TrivialGlobalManager>(globals).visit(segment.offset).value.geti32();
assert(offset + segment.data.size() <= module->table.initial);
for (size_t i = 0; i != segment.data.size(); ++i) {
table[offset + i] = segment.data[i];
}
}
The full code containing this vulnerability was published on GitHub.
The problem is that the assert check is only present in a debug build of the network. Release builds allow any offset value, which can lead to an out-of-bounds write condition in line 78 in the code above.
In this code, the values offset and segment.data.size() are read from the WASM file. This creates a vulnerability that can be exploited by a malicious contract providing invalid values. By doing so, attackers would be able to write data into arbitrary addresses in memory and, ultimately, take control of the node.
There are different ways attackers could compromise the network: by stealing the private keys of supernodes, controlling the content of new blocks, packing a malicious contract into a new block and publishing it, and so on. But the result would be the same โ every full node in the entire network would be compromised.
In order to understand this vulnerability better, letโs see how we can reproduce it.
Reproducing the smart contract vulnerability
The first thing you need to do in order to reproduce the vulnerability in EOS smart contracts is to create a vulnerable contract. You can accomplish that by manually modifying the WASM binary. The values that can be modified are offset and count of elements in the Elements section of the WASM file.
The vulnerability can be reproduced in three steps:
- Create a WASM binary file. You can do this by following the โHello Worldโ tutorial for EOS smart contracts.
- Open the file using a hex editor and find the section with id 9. You can also use a parser, like this one, to make it easier to find the section.
- Edit the offset and count values in one of the sections with id 9.
For instance, hereโs a file called hello.wasm. In this example, the count is set to a large value so that the node will crash (segfault) when trying to read it. However, this issue was recently patched by EOS developers. In order to reproduce it using the given method, youโd have to download an older version of the EOS software. In particular, you can use the AWN-2018-04-23-ALPHA version as itโs one of the last versions released before the issue was fixed.
Of course, just crashing nodes wonโt be enough for attackers. A real exploit would work somewhat like this:
- An attacker uploads a malicious contract to the EOS node server.
- The server parses the malicious contract, which triggers the smart contract vulnerability.
- The attacker achieves arbitrary memory read/write in the server process, allowing them to bypass the most common exploit mitigation techniques such as Data Execution Prevention (DEP) and Address Space Layout Randomisation (ASLR).
- Once itโs able to write anywhere in the memory, the exploit can start a reverse shell and connect back to the attacker, giving them full control over the remote node.
Fortunately, the block.one team quickly resolved this issue by changing debug assertions and replacing the asserts with a throw so they would throw even in release builds. However, there are still too many risk factors and security pitfalls in the EOS network.
Dealing with other issues
When it comes to the EOS blockchain, one of the dangers hides in using C++ and WASM. If used incorrectly, this pair can create numerous security issues, providing hackers with lots of great opportunities. Here are some of the EOS smart contract vulnerabilities that can be caused by the use of C++:
- Buffer overflows
- Dangling pointer references
- Integer errors
- Unchecked indirect calls
- Denial of service attacks
Furthermore, there are rumors on the web about porting the famous Spectre vulnerability to WASM! However, thereโs no need to panic. Since the EOS operating system is still in its early stages, itโs up to us as developers to make sure that no security breaches take place in the network. Plus, most of these vulnerabilities can be easily avoided by taking appropriate measures during smart contract development. In particular, you can follow security guidelines and receive a security audit from a third party such as Apriorit. This way you can make sure that no insecure code ends up in the final contract.
Itโs also noteworthy that the block.one team is constantly working on resolving any EOS network security issues found during a third-party security audit. The EOS creators have a pretty extensive bug bounty. Since May 2018, theyโve paid over $300,000 in bounty prizes for more than 40 vulnerability and issue disclosures. However, as of August 2018, no bugs have been disclosed so far. For more information about the block.one bug bounty program, visit the Hacker One website.
Conclusion
Just like many other cryptocurrencies, EOS uses smart contracts to achieve a high level of scalability and system stability. While EOS smart contracts can be written in any language that can compile to WebAssembly, C++ is the most popular. However, the combination of C++ and WASM can cause a lot of security issues in the network, including the recently discovered EOS node REC vulnerability. EOS allows developers to update code on the blockchain, however, so any issues can be fixed as soon as theyโre discovered. Also, by implementing an efficient blockchain testing strategy at early development stages, you can faster detect and fix issues.
At Apriorit, we have a passionate team of data encryption and cybersecurity professionals who will gladly assist you in developing a secure solution using blockchain technology.