Consensys / mythril

Security analysis tool for EVM bytecode. Supports smart contracts built for Ethereum, Hedera, Quorum, Vechain, Rootstock, Tron and other EVM-compatible blockchains.
https://mythx.io/
MIT License
3.88k stars 741 forks source link

Providing decoded tx_data in reports #1309

Closed sunbeomso closed 4 years ago

sunbeomso commented 4 years ago

Description

Mythril reports vulnerable transaction sequences with corresponding argument values which may be included in tx_data. However, reports currently provide tx_data that is not decoded .

Therefore, if I want to test whether Mythril's inputs work or not, it seems to I have to manually parse tx_data when multiple argument values exist in functions (transactions).

For the running example in README.md, an expected report format may be:

Caller: [CREATOR], constructor 
Caller: [CREATOR], killerize (0x....)
Caller: [CREATOR], activatekillability()
Caller: [CREATOR], commencekilling()

where we don't need to parse tx_data anymore.

norhh commented 4 years ago

You can try using -o argument like -o json or any other option.

sunbeomso commented 4 years ago

@norhh I have tried, but the output is still hard for me to understand.

Example contract:

contract Test{
  uint n;

  constructor (uint _n) public {
    require (_n==1);
    n = _n;
  }

  function test (uint8 a, uint[] memory b) public {
    require (a==10);
    n--;
  }
}

Mythril's output:

{'error': None,
 'issues': [{'address': 274,
             'code': 'n--',
             'contract': 'Test',
             'description': 'The binary subtraction can underflow.\n'
                            'The operands of the subtraction operation are not '
                            'sufficiently constrained. The subtraction could '
                            'therefore result in an integer underflow. Prevent '
                            'the underflow by checking inputs or ensure sure '
                            'that the underflow is caught by an assertion.',
             'filename': '/tmp/underflow.sol',
             'function': 'test(uint8,uint256[])',
             'lineno': 12,
             'max_gas_used': 28829,
             'min_gas_used': 6052,
             'severity': 'High',
             'sourceMap': ':3',
             'swc-id': '101',
             'title': 'Integer Underflow',
             'tx_sequence': {'initialState': {'accounts': {'0x901d12ebe1b195e5aa8748e62bd7734ae19b51f': {'balance': '0x0',
                                                                                                         'code': '608060405234801561001057600080fd5b506004361061002b5760003560e01c806382668f2014610030575b600080fd5b6100f36004803603604081101561004657600080fd5b81019080803560ff1690602001909291908035906020019064010000000081111561007057600080fd5b82018360208201111561008257600080fd5b803590602001918460208302840111640100000000831117156100a457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506100f5565b005b600a8260ff161461010557600080fd5b600080815480929190600190039190505550505056fea265627a7a72315820905474c85d6fd0ebd279b11519999d22ce65e110e6808035fa36813309dcad2a64736f6c634300050d0032',
                                                                                                         'nonce': 0,
                                                                                                         'storage': '{}'},
                                                           '0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe': {'balance': '0x400000001',
                                                                                                          'code': '',
                                                                                                          'nonce': 0,
                                                                                                          'storage': '{}'},
                                                           '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef': {'balance': '0x0',
                                                                                                          'code': '',
                                                                                                          'nonce': 0,
                                                                                                          'storage': '{}'}}},
                             'steps': [{'address': '',
                                        'input': '0x608060405234801561001057600080fd5b506040516101b83803806101b88339818101604052602081101561003357600080fd5b81019080805190602001909291905050506001811461005157600080fd5b8060008190555050610150806100686000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806382668f2014610030575b600080fd5b6100f36004803603604081101561004657600080fd5b81019080803560ff1690602001909291908035906020019064010000000081111561007057600080fd5b82018360208201111561008257600080fd5b803590602001918460208302840111640100000000831117156100a457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506100f5565b005b600a8260ff161461010557600080fd5b600080815480929190600190039190505550505056fea265627a7a72315820905474c85d6fd0ebd279b11519999d22ce65e110e6808035fa36813309dcad2a64736f6c634300050d003200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
                                        'name': 'unknown',
                                        'origin': '0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe',
                                        'value': '0x0'},
                                       {'address': '0x901d12ebe1b195e5aa8748e62bd7734ae19b51f',
                                        'input': '0x82668f20000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000',
                                        'name': 'test(uint8,uint256[])',
                                        'origin': '0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe',
                                        'value': '0x0'},
                                       {'address': '0x901d12ebe1b195e5aa8748e62bd7734ae19b51f',
                                        'input': '0x82668f20000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000',
                                        'name': 'test(uint8,uint256[])',
                                        'origin': '0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe',
                                        'value': '0x0'}]}}],
 'success': True}

As you can see in the contract, one possible sequence to detect underflow is: contructor(1) -> test(10, [0]) -> test (10,[0]).

Then, given the Mythril's report, how can I obtain a readable sequence like contructor(1) -> test(10, [0]) -> test (10,[0])?

My particularly uncertain part is the input field in the constructor part, which is very long.

norhh commented 4 years ago

constructor_input = bytecode + calldata. Remove the bytecode and you can get the call data. But it takes some effort to extract the calldata into int, uint, address etc. As Mythril is a bytecode analyzer it doesn't perform such operations, MythX has this feature.

sunbeomso commented 4 years ago

@norhh I have three additional questions.

  1. But it takes some effort to extract the calldata into int, uint, address etc.

Could you provide any examples? What do you mean by int, uint, address etc ? In my example, the constructor has only one input parameter which has uint type.

Or do you have any relevant documents?

  1. When dynamic arrays are passed into arguments (e.g., test function in my example), how can I know the size of the dynamic arrays from input field?
norhh commented 4 years ago

In my example, the constructor has only one input parameter which has uint type. I meant in general case when a constructor has multiple args. Look into solidity abi spec for more info https://solidity.readthedocs.io/en/develop/abi-spec.html