Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPT Review program-analysis/manticore #282

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions program-analysis/manticore/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
# Manticore Tutorial

The aim of this tutorial is to show how to use Manticore to automatically find bugs in smart contracts.
This tutorial demonstrates how to use Manticore to automatically find bugs in smart contracts.

The first part introduces a set of the basic features of Manticore: running under Manticore and manipulating smart contracts through API, getting throwing path, adding constraints.
The second part is exercise to solve.
The first part introduces a set of Manticore's basic features, including running Manticore, manipulating smart contracts through the API, retrieving throwing paths, and adding constraints. The second part consists of exercises to solve.

**Table of contents:**

- [Installation](#installation)
- [Introduction to symbolic execution](./symbolic-execution-introduction.md): Brief introduction to symbolic execution
- [Running under Manticore](./running-under-manticore.md): How to use Manticore's API to run a contract
- [Getting throwing paths](./getting-throwing-paths.md): How to use Manticore's API to get specific paths
- [Adding constraints](./adding-constraints.md): How to use Manticore's API to add paths' constraints
- [Introduction to symbolic execution](./symbolic-execution-introduction.md): A brief introduction to symbolic execution
- [Running Manticore](./running-under-manticore.md): Using Manticore's API to run a contract
- [Getting throwing paths](./getting-throwing-paths.md): Using Manticore's API to obtain specific paths
- [Adding constraints](./adding-constraints.md): Using Manticore's API to add path constraints
- [Exercises](./exercises)

Join the team on Slack at: https://empireslacking.herokuapp.com/ #ethereum, #manticore

## Installation

Manticore requires >= python 3.6. It can be installed through pip or using docker.
Manticore requires Python 3.6 or later. It can be installed using pip or Docker.

## Manticore through docker
## Manticore through Docker

```bash
docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox
```

_The last command runs eth-security-toolbox in a docker that has access to your current directory. You can change the files from your host, and run the tools on the files from the docker_
_The last command runs the eth-security-toolbox in a Docker container with access to your current directory. You can modify the files on your host and run the tools on the files from the Docker container._

Inside docker, run:
Inside the Docker container, run:

```bash
solc-select 0.5.11
Expand All @@ -42,11 +41,11 @@ cd /home/trufflecon/
pip3 install --user manticore
```

solc 0.5.11 is recommended.
It is recommended to use solc 0.5.11.

### Running a script

To run a python script with python 3:
To run a Python script with Python 3:

```bash
python3 script.py
Expand Down
24 changes: 10 additions & 14 deletions program-analysis/manticore/adding-constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@

## Introduction

We will see how to constrain the exploration. We will make the assumption that the
documentation of `f()` states that the function is never called with `a == 65`, so any bug with `a == 65` is not a real bug. The target is still the following smart contract (_[example.sol](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example.sol)_):
We will explore how to limit the exploration by adding constraints. Assuming the documentation of `f()` states that the function is never called with `a == 65`, any bug with `a == 65` is not considered a real bug. Our target is the following smart contract ([example.sol](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example.sol)):

```solidity
pragma solidity >=0.4.24 <0.6.0;
Expand All @@ -30,7 +29,7 @@ contract Simple {

## Operators

The [Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) module facilitates the manipulation of constraints, among other it provides:
The [Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) module enables constraint manipulation and provides various operations, such as:

- Operators.AND,
- Operators.OR,
Expand All @@ -39,26 +38,25 @@ The [Operators](https://github.com/trailofbits/manticore/blob/master/manticore/c
- Operators.ULT (unsigned lower than),
- Operators.ULE (unsigned lower than or equal to).

To import the module use the following:
To import the module, use the following:

```python3
from manticore.core.smtlib import Operators
```

`Operators.CONCAT` is used to concatenate an array to a value. For example, the return_data of a transaction needs to be changed to a value to be checked against another value:
`Operators.CONCAT` can be used to concatenate an array to a value. For instance, the return_data of a transaction needs to be converted to a value before checking it against another value:

```python3
last_return = Operators.CONCAT(256, *last_return)
```

## Constraints

You can use constraints globally or for a specific state.
Constraints can be applied globally or to a specific state.

### Global constraint

Use `m.constrain(constraint)` to add a global cosntraint.
For example, you can call a contract from a symbolic address, and restraint this address to be specific values:
To add a global constraint, use `m.constrain(constraint)`. For example, you can call a contract from a symbolic address and limit this address to specific values:

```python3
symbolic_address = m.make_symbolic_value()
Expand All @@ -71,13 +69,11 @@ m.transaction(caller=user_account,

### State constraint

Use [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=statebase#manticore.core.state.StateBase.constrain) to add a constraint to a specific state
It can be used to constrain the state after its exploration to check some property on it.
To add a constraint to a specific state, use [`state.constrain(constraint)`](https://manticore.readthedocs.io/en/latest/states.html?highlight=statebase#manticore.core.state.StateBase.constrain). It can be employed to constrain the state after its exploration in order to check properties on it.

## Checking Constraint

Use `solver.check(state.constraints)` to know if a constraint is still feasible.
For example, the following will constraint symbolic_value to be different from 65 and check if the state is still feasible:
`solver.check(state.constraints)` can be used to determine if a constraint is still feasible. For instance, the following code constrains `symbolic_value` to be different from 65 and checks if the state is still feasible:

```python3
state.constrain(symbolic_var != 65)
Expand All @@ -87,7 +83,7 @@ if solver.check(state.constraints):

## Summary: Adding Constraints

Adding constraint to the previous code, we obtain:
By incorporating constraints into the previous code, we obtain:

```python3
from manticore.ethereum import ManticoreEVM
Expand Down Expand Up @@ -122,6 +118,6 @@ if no_bug_found:
print(f'No bug found')
```

All the code above you can find into the [example_constraint.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example_constraint.py)
The complete code can be found in [example_constraint.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example_constraint.py).

The next step is to follow the [exercises](./exercises).
6 changes: 3 additions & 3 deletions program-analysis/manticore/exercises/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Manticore Exercises

- [Example](./example.md): Arithmetic overflow
- [Exercise 1](./exercise1.md): Arithmetic rounding
- [Exercise 2](./exercise2.md): Arithmetic overflow through multiple transactions
- [Example](./example.md): Arithmetic Overflow
- [Exercise 1](./exercise1.md): Arithmetic Rounding
- [Exercise 2](./exercise2.md): Arithmetic Overflow in Multiple Transactions
20 changes: 10 additions & 10 deletions program-analysis/manticore/exercises/example.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Example: Arithmetic overflow
# Example: Arithmetic Overflow

This scenario is given as an example. You can follow its structure to solve the exercises.
This scenario is provided as an example. You can use its structure as a guide to solving the exercises.

[`my_token.py`](example/my_token.py) uses Manticore to find for an attacker to generate tokens during a transfer on Token ([my_token.sol](example/my_token.sol)).
[`my_token.py`](example/my_token.py) utilizes Manticore to discover if an attacker can generate tokens during a transfer on the Token contract ([my_token.sol](example/my_token.sol)).

## Proposed scenario
## Proposed Scenario

We use the pattern initialization, exploration and property for our scripts.
We will use the pattern of initialization, exploration, and property checking for our scripts.

## Initialization

Expand All @@ -15,10 +15,10 @@ We use the pattern initialization, exploration and property for our scripts.

## Exploration

- Call balances on the user account
- Call transfer with symbolic destination and value
- Call balances on the user account
- Call 'balances' on the user account
- Call 'transfer' with a symbolic destination and value
- Call 'balances' on the user account again

## Property
## Property Checking

- Check if the user can have more token after the transfer than before.
- Verify if the user can possess more tokens after the transfer than before.
21 changes: 10 additions & 11 deletions program-analysis/manticore/exercises/exercise1.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Exercise 1 : Arithmetic rounding
# Exercise 1: Arithmetic Rounding

Use Manticore to find an input allowing an attacker to generate free tokens in [token.sol](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises/exercise1/token.sol).
Propose a fix of the contract, and test your fix using your Manticore script.
Use Manticore to discover an input that allows an attacker to generate free tokens in [token.sol](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises/exercise1/token.sol). Propose a fix for the contract and test your solution using the Manticore script.

## Proposed scenario
## Proposed Scenario

Follow the pattern initialization, exploration and property for the script.
Follow the initialization, exploration, and property pattern for the script.

## Initialization

Expand All @@ -14,18 +13,18 @@ Follow the pattern initialization, exploration and property for the script.

## Exploration

- Call `is_valid_buy` with two symbolic values for tokens_amount and wei_amount
- Call `is_valid_buy` with two symbolic values for `tokens_amount` and `wei_amount`

## Property

- An attack is found if on a state alive `wei_amount == 0 and tokens_amount >= 1`
- An attack is discovered if, on a live state, `wei_amount == 0 and tokens_amount >= 1`

## Hints

- `m.ready_states` returns the list of state alive
- `Operators.AND(a, b)` allows to create and AND condition
- You can use the template proposed in [template.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises/exercise1/template.py)
- `m.ready_states` returns a list of live states
- Use `Operators.AND(a, b)` to create an AND condition
- The [template.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises/exercise1/template.py) can serve as a starting point

## Solution

[solution.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises/exercise1/solution.py)
Refer to [solution.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises/exercise1/solution.py) for a possible solution.
12 changes: 6 additions & 6 deletions program-analysis/manticore/exercises/exercise2.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Exercise 2 : Arithmetic overflow through multiple transactions
# Exercise 2: Arithmetic Overflow through Multiple Transactions

Use Manticore to find if an overflow is possible in Overflow.add. Propose a fix of the contract, and test your fix using your Manticore script.
Use Manticore to find if an overflow is possible in Overflow.add. Propose a fix for the contract and test your fix using your Manticore script.

## Proposed scenario
## Proposed Scenario

Follow the pattern initialization, exploration and property for the script.
Follow the pattern of initialization, exploration, and property for the script.

## Initialization

Expand All @@ -13,12 +13,12 @@ Follow the pattern initialization, exploration and property for the script.

## Exploration

- Call two times `add` with two symbolic values
- Call `add` twice with two symbolic values
- Call `sellerBalance()`

## Property

- Check if it is possible for the value returned by sellerBalance() to be lower than the first input.
- Check if it is possible for the value returned by `sellerBalance()` to be lower than the first input.

## Hints

Expand Down
40 changes: 20 additions & 20 deletions program-analysis/manticore/getting-throwing-paths.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Getting Throwing Path
# Finding Throwing Paths

**Table of contents:**
**Table of Contents:**

- [Getting Throwing Path](#getting-throwing-path)
- [Finding Throwing Paths](#finding-throwing-paths)
- [Introduction](#introduction)
- [Using state information](#using-state-information)
- [How to generate testcase](#how-to-generate-testcase)
- [Using State Information](#using-state-information)
- [Generating Test Cases](#generating-test-cases)
- [Summary](#summary)
- [Summary: Getting Throwing Path](#summary-getting-throwing-path)
- [Summary: Finding Throwing Paths](#summary-finding-throwing-paths)

## Introduction

We will now improve [the previous example](running-under-manticore.md) and generate specific inputs for the paths raising an exception in `f()`. The target is still the following smart contract (_[example.sol](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example.sol)_):
We will now improve [the previous example](running-under-manticore.md) and generate specific inputs for paths raising an exception in `f()`. The target is still the following smart contract ([example.sol](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example.sol)):

```solidity
pragma solidity >=0.4.24 <0.6.0;
Expand All @@ -25,49 +25,49 @@ contract Simple {
}
```

## Using state information
## Using State Information

Each path executed has its state of the blockchain. A state is either ready or it is killed, meaning that it reaches a THROW or REVERT instruction:
Each executed path has its own blockchain state. A state is either ready or killed, meaning that it reaches a THROW or REVERT instruction:

- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): the list of states that are ready (they did not execute a REVERT/INVALID)
- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): the list of states that are ready (they did not execute a REVERT/INVALID)
- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): the list of killed states (they did execute a REVERT/INVALID)
- [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): all the states

```python3
for state in m.all_states:
# do something with state
```

You can access state information. For example:
You can access information about a state. For example:

- `state.platform.get_balance(account.address)`: the balance of the account
- `state.platform.transactions`: the list of transactions
- `state.platform.transactions[-1].return_data`: the data returned by the last transaction

The data returned by the last transaction is an array, which can be converted to a value with ABI.deserialize, for example:
The data returned by the last transaction is an array, which can be converted to a value with ABI.deserialize. For example:

```python
data = state.platform.transactions[0].return_data
data = ABI.deserialize("uint256", data)
```

## How to generate testcase
## Generating Test Cases

Use [m.generate_testcase(state, name)](https://github.com/trailofbits/manticore/blob/dc8c3c822bbd50adabe50cafef38457505c0bc7b/manticore/ethereum/manticore.py#L1572) to generate testcase:
Use [m.generate_testcase(state, name)](https://github.com/trailofbits/manticore/blob/dc8c3c822bbd50adabe50cafef38457505c0bc7b/manticore/ethereum/manticore.py#L1572) to generate test cases:

```python3
m.generate_testcase(state, 'BugFound')
```

## Summary

- You can iterate over the state with m.all_states
- `state.platform.get_balance(account.address)` returns the accounts balance
- You can iterate over the states with m.all_states
- `state.platform.get_balance(account.address)` returns the account's balance
- `state.platform.transactions` returns the list of transactions
- `transaction.return_data` is the data returned
- `m.generate_testcase(state, name)` generate inputs for the state
- `m.generate_testcase(state, name)` generates inputs for the state

## Summary: Getting Throwing Path
## Summary: Finding Throwing Paths

```python3
from manticore.ethereum import ManticoreEVM
Expand All @@ -91,8 +91,8 @@ for state in m.terminated_states:
m.generate_testcase(state, 'ThrowFound')
```

All the code above you can find into the [example_throw.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example_throw.py)
You can find all the code above in the [example_throw.py](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/examples/example_throw.py) file.

The next step is to [add constraints](./adding-constraints.md) to the state.

_Note we could have generated a much simpler script, as all the states returned by terminated_state have REVERT or INVALID in their result: this example was only meant to demonstrate how to manipulate the API._
_Note: We could have generated a much simpler script since all the states returned by terminated_state have REVERT or INVALID in their result. This example was only meant to demonstrate how to manipulate the API._
Loading