‘Bullies’ in Smart Contracts | Beosin Vulnerability Analysis Series Phase VII
Recently, Chinese media, especially weibo are talking about the “bully incident” on the bullet train. The incident was caused by a man who occupied a seat on bullet train and refused to give it to the person with the ticket. He still insisted to sit on it even under the pressure of police officers. Similar things happened before were all once again under the spotlight. The public are now urging corresponding counter measures to take place.
Taking seat according to the ticket is supposed to be a common courtesy, while some people think their “bully” are reasonable just because they’ve bought tickets. This problem caused disorder and frustration among the crowds on the bullet train. In fact, sitting in the wrong seat in smart contracts can also cause disorder, or even worse, such as vulnerabilities.
Basics
When variable needs to be stored, a position in the system will be given for this variable. This position is like a seat on the train.
In Solidity, there are 2 concepts related to variable storage — Storage and Memory. Storage variable means variable stored in Storage, the persistent memory that every account has. While Memory variable is held until the execution of the function, and will be deleted after invocation.
It is worth mentioning that, for type of variable, there exists default storage location. For instance, local variables of struct, array or mapping type reference are stored in storage by default. Besides, state variables are always in storage and put in sequence. So, the positions for state variables are like seats for each one of them.
Where does the vulnerability come from?
Solidity has a feature different from other traditional developing language. That is, solidity allows the defining of a reference mapping to Storage. Uninitiated storage pointer will be mapping to the starting position in storage by default. If not initialized and assigned values directly, the variable which was on the starting position will be modified.
This situation is like a taking seats on a train. Let’s assume the first wave of passengers didn’t have corresponding seat numbers, thus taking seats sequentially. The second wave of passengers also didn’t get their seat numbers, so they started taking seats sequentially again, leading to the expulsion of the first wave.
Real Examples
Lack of consideration In Development
This type of vulnerability shows as the bug which was exploited by attackers recently, such as the BancorLender incident reported by some security organizations. The problematic part of code shows as below:
State variable agreements was stated as showed in the first yellow box, then entering the starting position slot 0x00. The second yellow box means the statement of another local variable agreement without initialization in function offerTolend(), the consequence of doing so is that slot 0x00 will be taken over by this new local variable agreement. More specifically, starting from the code underlined with pink, three value assignments will modify the original values on positions from slot 0x00 to slot 0x03. Mishandled code like this will affect the implementation and functioning of the contract.
‘Special Design’ in honeypot
Apart from the mistakes happened during development, this vulnerability has also been applied to deploy honeypots in blockchain games. Honeypot is a method to lure hackers in internet industry. In blockchain industry, source code is usually public so it is easier for anyone with programming knowledge to see the loopholes in the smart contracts. However, if there is an obvious bug, you should be cautious, because there might another hidden logic behind it waiting for your attack. This is the second use of this vulnerability.
Let’s see an example called OpenAddressLottery.
The ‘s’ in this part of the code is stated yet not been initialized, so the value assignment operation will modify the value sitting at its position.
Which ones will be modified? We can see them in the following code:
So the ‘LuckyNumber’ which appears to be the predictable answer of the game, took the starting position. While tx.gasprice*7 above will modify it, and address owner will be modified by the value of msg.sender. But the value of msg.sender equals to the value of address owner, so this part doesn’t affect the function.
Since the result of luckyNumberOfAddress shows as a binary number, and the true result after the modification of tx.gasprice*7 will be larger than 7, so it is impossible for players to guess the right number.
It is worth mentioning that, in the first part of the code, require(msg.send==owner) means only the owner of the contract can call this function which manipulates true values.
The facts proved our inference:
Owner of the contract transferred out all the money and initiated self-destruct.
Summary
In conclusion, uninitialized storage pointers could be mapping to state variables in the contracts, resulting in deliberate or unintentional vulnerability.
Here are some typical cases given according to the types of variables.
Typical uninitialized storage pointers in Struct:
When entering
_name=”0x0000000000000000000000000000000000000000000000000000000000000001, and setting the address as random, it will modify the value of ‘unlocked’, making the return value as true.
Typical uninitialized storage pointers in Array
When entering
elements=[“0x0000000000000000000000000000000000000000000000000000000000000001”], the value of ‘frozen’ will be modified, leading to a ‘true’ return value.
Bug-fix
Compilers like Remix-ide will give warnings on uninitialized storage pointers, so it is very important for developers to pay attentions to these warnings and fix problematic code according to this information. When declaring local variables, initialization should be undertaken, or Memory position should be allotted to avoid vulnerability.
Be cautious and optimistic
The vulnerability we discussed this time is caused by solidity conventions of default storage rules and the exception of uninitialized local variables. When coding using traditional language, uninitialized variables will cause an error in compiler. Solidity 0.4.24 doesn’t same rules in compiler, only gives a warning when encountering similar situation.
So we hereby urge all developers:
1. Stick to coding conventions while developing smart contract. Only by implementing functions with corresponding precautions can this new technology be improved.
2. Do some research about the project before investing to avoid “honeypot”.
Currently, blockchain industry just took off, time for development and exploring is needed. We need to adjust our way to deal with local variables as well as our attitude.
References:
[1]:Solidity缺陷易使合约状态失控 https://zhuanlan.zhihu.com/p/41412333
[2]: How does this honeypot work? https://www.reddit.com/r/ethdev/comments/7wp363/how_does_this_honeypot_work_it_seems_like_a/
[3]: 构造函数失控、未初始化的存储指针 https://ethfans.org/posts/comprehensive-list-of-common-attacks-and-defense-part-7
About Beosin
Beosin is headquartered in Chengdu and focuses on blockchain security field.Founded by Prof. Xia Yang and Prof. Wensheng Guo of UESTC, Beosin’s core team consists of 40 associate professors, doctors, and postdoctoral fellows with experience studying overseas and leading universities as well as laboratories industry elites from Alibaba, Huawei, and other known enterprises. Using formal verification as its core technology, the team has been providing years of services for security-critical systems in aerospace, military and other fields. Beosin is the first company in China that applies formal verification technology to blockchain security field.
Beosin has received strategic equity investments from known venture capitals including Fenbushi Capital, Milestone Capital, and Vangoo Capital while building strategic partnerships with over 40 renowned blockchain companies such as Huobi, OKEx, Kucoin, LBank, Seele, ONT, Qtum, Bytom, Wanchain, Scry, Bubi Blockchain, YUNPHANT, QuarkChain, IoTeX, Math Wallet, etc.
Let’s connect
E-mail:vaas@lianantech.com
Official website:https://www.beosin.com
Twitter: https://twitter.com/Beosin_com
Facebook: https://www.facebook.com/BeosinChengdu/
Telegram Chinese Group:https://t.me/joinchat/IRgNDA4iCF0Rs92sg5qoVg
Telegram English group: https://t.me/joinchat/IRgNDBBpCon-695ATmbA4w