Skip to content

Commit 70f0689

Browse files
committed
Add first public version of SmartBugs.
0 parents  commit 70f0689

File tree

77 files changed

+7655
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+7655
-0
lines changed

.gitignore

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# ignore results
2+
results/oyente/*
3+
results/mythril/*
4+
results/securify/*
5+
results/smartcheck/*
6+
results/logs/*
7+
8+
# keep folders
9+
!results/securify/.keep
10+
!results/oyente/.keep
11+
!results/mythril/.keep
12+
!results/smartcheck/.keep
13+
!results/logs/.keep
14+
15+
#Ignore DS_Store
16+
.DS_Store
17+
18+
#Ignore pycache
19+
*.pyc
20+
__pycache__

README.md

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# SmartBugs: A Dataset of Vulnerable Solidity Smart Contracts
2+
SmartBugs is a dataset for research in automated reasoning and testing of smart contracts written in Solidity, the primary language used in Ethereum. The key new idea that SmartBugs proposes is that a reproducible dataset for automated analysis of smart contracts should also provide the possibility to integrate tools easily, so that they can be automatically compared (and their results reproduced). To the best of our knowledge, SmartBugs is the first dataset to provide this facility.
3+
4+
SmartBugs is publicly available as a [GitHub repository](https://github.com/smartbugs/smartbugs).
5+
6+
## Features
7+
8+
- Organized collection of vulnerable Solidity smart contracts (organized according to the [DASP taxonomy](https://dasp.co))
9+
- Users can create _named sets_, which are intended to represent subsets of contracts that share a common property. For example, a named dataset already provided by SmartBugs is `reentrancy`: it corresponds to contracts that are vulnerable to reentrancy attacks
10+
- Users can easily integrate new analysis tools and use SmartBugs' interface to run them. Tools available include [oyente](https://github.com/melonproject/oyente), [mythril](https://github.com/ConsenSys/mythril), [securify](https://github.com/eth-sri/securify), and [smartcheck](https://github.com/smartdec/smartcheck)
11+
- SmartBugs provides an interface that allows users to query the dataset and run different analysis tools on sets of contracts.
12+
13+
14+
## Requirements
15+
The first step is to clone [SmartBugs's repository](https://github.com/smartbugs/smartbugs):
16+
17+
```
18+
git clone https://github.com/smartbugs/smartbugs.git
19+
```
20+
21+
SmartBugs requires [Python3](https://www.python.org). To install all the requirements, you can execute:
22+
23+
```
24+
pip3 install -r requirements.txt
25+
```
26+
27+
28+
## Usage
29+
SmartBugs provides a command-line interface that can be used as follows:
30+
```
31+
smartBugs.py [-h, --help]
32+
(--file FILES | --type TYPE)
33+
--tool TOOLS
34+
--info TOOLS
35+
--list tools types
36+
````
37+
38+
For example, we can analyse all contracts labelled with type `reentrancy` with the tool oyente by executing:
39+
40+
```
41+
python3 smartBugs.py --tool oyente --type reentrancy
42+
```
43+
44+
By default, results will be placed in the directory `results`.
45+
46+
47+
### Adding your tool or any third-party tool to SmartBugs
48+
49+
You will need to add a configuration file in `config/tools` and define the docker image to use and command to run. The config file should follow a structure similar to the following:
50+
```
51+
docker_image:
52+
default: primary docker image [REQUIRED]
53+
solc<5: [OPTIONAL]
54+
cmd: command to run analysis [REQUIRED]
55+
info: info about the tool [OPTIONAL]
56+
57+
output_in_files:
58+
folder: if the tool does not log results in console, you should provide the path file inside the docker image to get the results [OPTIONAL]
59+
```
60+
Please check the provided config files for more concrete examples.
61+
62+
63+
### Adding new named sets
64+
65+
To add a new named set, edit the configuration file `dataset.yml` (in the folder `config/dataset`) and add the named path you want (can be files or dirs):
66+
67+
The config file should follow a structure similar to:
68+
```
69+
type_1: PATH
70+
type_2:
71+
- PATH
72+
- PATH
73+
```
74+
Please check the provided config files for more concrete examples.
75+
76+
## Known limitations
77+
78+
When running a tool the user must be aware of the solc compatibility. Due to the major changes introduced in solidity v0.5.0, we provide the option to pass another docker image to run contracts with solidity version below v0.5.0. However, please note that there may still be problems with the solidity compiler when compiling older versions of solidity code.
79+
80+
## Vulnerabilities
81+
82+
SmartBugs provides a collection of vulnerable Solidity smart contracts organized according to the [DASP taxonomy](https://dasp.co):
83+
84+
| Vulnerability | Description | Level |
85+
| --- | --- | -- |
86+
| [Reentrancy](https://github.com/smartbugs/smartbugs/blob/master/dataset/reentrancy) | Reentrant function calls make a contract to behave in an unexpected way | Solidity |
87+
| [Access Control](https://github.com/smartbugs/smartbugs/blob/master/dataset/access_control) | Failure to use function modifiers or use of tx.origin | Solidity |
88+
| [Arithmetic](https://github.com/smartbugs/smartbugs/blob/master/dataset/arithmetic) | Integer over/underflows | Solidity |
89+
| [Unchecked Low Level Calls](https://github.com/smartbugs/smartbugs/blob/master/dataset/unchecked_low_level_calls) | call(), callcode(), delegatecall() or send() fails and it is not checked | Solidity |
90+
| [Denial Of Service](https://github.com/smartbugs/smartbugs/blob/master/dataset/denial_of_service) | The contract is overwhelmed with time-consuming computations | Solidity |
91+
| [Bad Randomness](https://github.com/smartbugs/smartbugs/blob/master/dataset/bad_randomness) | Malicious miner biases the outcome | Blockchain |
92+
| [Front Running](https://github.com/smartbugs/smartbugs/blob/master/dataset/front_running) | Two dependent transactions that invoke the same contract are included in one block | Blockchain |
93+
| [Time Manipulation](https://github.com/smartbugs/smartbugs/blob/master/dataset/time_manipulation) | The timestamp of the block is manipulated by the miner | Blockchain |
94+
| [Short Addresses](https://github.com/smartbugs/smartbugs/blob/master/dataset/short_addresses) | EVM itself accepts incorrectly padded arguments | EVM |
95+
96+
97+
## Contributing to SmartBugs
98+
Everyone is welcome to contribute to the development of SmartBugs.
99+
100+
The easiest way is to create a pull request. Please write your commit messages in the present tense. We suggest you follow this guide: [Commit Message Guidelines](https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53).

config/dataset/dataset.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
datasetaccess_control: dataset/access_control
2+
arithmetic: dataset/arithmetic
3+
bad_randomness: dataset/bad_randomness
4+
denial_of_service: dataset/denial_of_service
5+
front_running: dataset/front_running
6+
reentrancy: dataset/reentrancy
7+
short_addresses: dataset/short_addresses
8+
time_manipulation: dataset/time_manipulation
9+
unchecked_ll_calls: dataset/unchecked_low_level_calls

config/tools/mythril.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
docker_image:
2+
default: qspprotocol/mythril-usolc
3+
solc<5: qspprotocol/mythril-0.4.25
4+
cmd: -x
5+
info: Mythril analyses EVM bytecode using symbolic analysis, taint analysis and control flow checking to detect a variety of security vulnerabilities.

config/tools/oyente.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
docker_image:
2+
default: qspprotocol/oyente-0.4.25
3+
cmd: -s
4+
info: Oyente runs on symbolic execution, determines which inputs cause which program branches to execute, to find potential security vulnerabilities. Oyente works directly with EVM bytecode without access high level representation and does not provide soundness nor completeness.

config/tools/securify.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
docker_image:
2+
default: qspprotocol/securify-usolc
3+
solc<5: qspprotocol/securify-0.4.25
4+
cmd: --livestatusfile /results/output.json -fs
5+
output_in_files:
6+
folder: /results/output.json
7+
info: Securify uses formal verification, also relying on static analysis checks. Securify’s analysis consists of two steps. First, it symbolically analyzes the contract’s dependency graph to extract precise semantic information from the code. Then, it checks compliance and violation patterns that capture suffi- cient conditions for proving if a property holds or not.

config/tools/smartcheck.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
docker_image:
2+
default: smartbugs/smartcheck
3+
cmd: -p
4+
info: Securify automatically checks for vulnerabilities and bad coding practices. It runs lexical and syntactical analysis on Solidity source code.

dataset/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# SmartBugs: A Dataset of Vulnerable Solidity Smart Contracts
2+
SmartBugs is a dataset for research in automated reasoning and testing of smart contracts written in Solidity, the primary language used in Ethereum. The key new idea that SmartBugs proposes is that a reproducible dataset for automated analysis of smart contracts should also provide the possibility to integrate tools easily, so that they can be automatically compared (and their results reproduced). To the best of our knowledge, SmartBugs is the first dataset to provide this facility.
3+
4+
## Description
5+
6+
This is the directory where all the contracts are located. The directory is organized according to the [DASP taxonomy](https://dasp.co). Each class of vulnerability may include:
7+
8+
* Brief description of the vulnerability
9+
* Attack scenarios to exploit the vulnerability
10+
* Methods of mitigation
11+
* Examples of real world exploitation
12+
13+
## Vulnerabilities
14+
15+
SmartBugs provides a collection of vulnerable Solidity smart contracts organized according to the [DASP taxonomy](https://dasp.co):
16+
17+
| Vulnerability | Description | Level |
18+
| --- | --- | -- |
19+
| [Reentrancy](https://github.com/smartbugs/smartbugs/blob/master/dataset/reentrancy) | Reentrant function calls make a contract to behave in an unexpected way | Solidity |
20+
| [Access Control](https://github.com/smartbugs/smartbugs/blob/master/dataset/access_control) | Failure to use function modifiers or use of tx.origin | Solidity |
21+
| [Arithmetic](https://github.com/smartbugs/smartbugs/blob/master/dataset/arithmetic) | Integer over/underflows | Solidity |
22+
| [Unchecked Low Level Calls](https://github.com/smartbugs/smartbugs/blob/master/dataset/unchecked_low_level_calls) | call(), callcode(), delegatecall() or send() fails and it is not checked | Solidity |
23+
| [Denial Of Service](https://github.com/smartbugs/smartbugs/blob/master/dataset/denial_of_service) | The contract is overwhelmed with time-consuming computations | Solidity |
24+
| [Bad Randomness](https://github.com/smartbugs/smartbugs/blob/master/dataset/bad_randomness) | Malicious miner biases the outcome | Blockchain |
25+
| [Front Running](https://github.com/smartbugs/smartbugs/blob/master/dataset/front_running) | Two dependent transactions that invoke the same contract are included in one block | Blockchain |
26+
| [Time Manipulation](https://github.com/smartbugs/smartbugs/blob/master/dataset/time_manipulation) | The timestamp of the block is manipulated by the miner | Blockchain |
27+
| [Short Addresses](https://github.com/smartbugs/smartbugs/blob/master/dataset/short_addresses) | EVM itself accepts incorrectly padded arguments | EVM |

dataset/access_control/README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Access Control
2+
Access Control issues are common in all programs, not just smart contracts. In fact, it's number 5 on the OWASP top 10. One usually accesses a contract's functionality through its public or external functions. While insecure visibility settings give attackers straightforward ways to access a contract's private values or logic, access control bypasses are sometimes more subtle. These vulnerabilities can occur when contracts use the deprecated tx.origin to validate callers, handle large authorization logic with lengthy require and make reckless use of delegatecall in proxy libraries or proxy contracts.
3+
4+
Loss: estimated at 150,000 ETH (~30M USD at the time)
5+
6+
## Attack Scenario
7+
A smart contract designates the address which initializes it as the contract's owner. This is a common pattern for granting special privileges such as the ability to withdraw the contract's funds.
8+
Unfortunately, the initialization function can be called by anyone — even after it has already been called. Allowing anyone to become the owner of the contract and take its funds.
9+
10+
## Examples
11+
In the following example, the contract's initialization function sets the caller of the function as its owner. However, the logic is detached from the contract's constructor, and it does not keep track of the fact that it has already been called.
12+
```
13+
function initContract() public {
14+
owner = msg.sender;
15+
}
16+
```
17+
In the Parity multi-sig wallet, this initialization function was detached from the wallets themselves and defined in a "library" contract. Users were expected to initialize their own wallet by calling the library's function via a delegateCall. Unfortunately, as in our example, the function did not check if the wallet had already been initialized. Worse, since the library was a smart contract, anyone could initialize the library itself and call for its destruction.
18+
19+
## References
20+
Taken from [DASP TOP10](https://dasp.co/)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/unprotected_critical_functions/simple_suicide.sol
3+
* @author: -
4+
*/
5+
6+
contract SimpleSuicide {
7+
8+
function sudicideAnyone() {
9+
selfdestruct(msg.sender);
10+
}
11+
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* @source: https://github.com/trailofbits/not-so-smart-contracts/blob/master/wrong_constructor_name/incorrect_constructor.sol
3+
* @author: -
4+
*/
5+
6+
pragma solidity ^0.4.15;
7+
8+
contract Missing{
9+
address private owner;
10+
11+
modifier onlyowner {
12+
require(msg.sender==owner);
13+
_;
14+
}
15+
16+
// The name of the constructor should be Missing
17+
// Anyone can call the IamMissing once the contract is deployed
18+
function IamMissing()
19+
public
20+
{
21+
owner = msg.sender;
22+
}
23+
24+
function withdraw()
25+
public
26+
onlyowner
27+
{
28+
owner.transfer(this.balance);
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/unprotected_critical_functions/multiowned_vulnerable.sol
3+
* @author: -
4+
*/
5+
6+
pragma solidity ^0.4.23;
7+
8+
/**
9+
* @title MultiOwnable
10+
*/
11+
contract MultiOwnable {
12+
address public root;
13+
mapping (address => address) public owners; // owner => parent of owner
14+
15+
/**
16+
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
17+
* account.
18+
*/
19+
constructor() public {
20+
root = msg.sender;
21+
owners[root] = root;
22+
}
23+
24+
/**
25+
* @dev Throws if called by any account other than the owner.
26+
*/
27+
modifier onlyOwner() {
28+
require(owners[msg.sender] != 0);
29+
_;
30+
}
31+
32+
/**
33+
* @dev Adding new owners
34+
* Note that the "onlyOwner" modifier is missing here.
35+
*/
36+
function newOwner(address _owner) external returns (bool) {
37+
require(_owner != 0);
38+
owners[_owner] = msg.sender;
39+
return true;
40+
}
41+
42+
/**
43+
* @dev Deleting owners
44+
*/
45+
function deleteOwner(address _owner) onlyOwner external returns (bool) {
46+
require(owners[_owner] == msg.sender || (owners[_owner] != 0 && msg.sender == root));
47+
owners[_owner] = 0;
48+
return true;
49+
}
50+
}
51+
52+
contract TestContract is MultiOwnable {
53+
54+
function withdrawAll() onlyOwner {
55+
msg.sender.transfer(this.balance);
56+
}
57+
58+
function() payable {
59+
}
60+
61+
}

dataset/access_control/mycontract.sol

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* @source: https://consensys.github.io/smart-contract-best-practices/recommendations/#avoid-using-txorigin
3+
* @author: Consensys Diligence
4+
* Modified by Gerhard Wagner
5+
*/
6+
7+
pragma solidity 0.4.24;
8+
9+
contract MyContract {
10+
11+
address owner;
12+
13+
function MyContract() public {
14+
owner = msg.sender;
15+
}
16+
17+
function sendTo(address receiver, uint amount) public {
18+
require(tx.origin == owner);
19+
receiver.transfer(amount);
20+
}
21+
22+
}

0 commit comments

Comments
 (0)