|
|
|
@ -20,60 +20,6 @@ from mythril.laser.smt import symbol_factory, UGT |
|
|
|
|
log = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DelegateCallAnnotation(StateAnnotation): |
|
|
|
|
def __init__(self, call_state: GlobalState, constraints: List) -> None: |
|
|
|
|
""" |
|
|
|
|
Initialize DelegateCall Annotation |
|
|
|
|
:param call_state: Call state |
|
|
|
|
""" |
|
|
|
|
self.call_state = call_state |
|
|
|
|
self.constraints = constraints |
|
|
|
|
self.return_value = call_state.new_bitvec( |
|
|
|
|
"retval_{}".format(call_state.get_current_instruction()["address"]), 256 |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
def _copy__(self): |
|
|
|
|
return DelegateCallAnnotation(self.call_state, copy(self.constraints)) |
|
|
|
|
|
|
|
|
|
def get_issue(self, global_state: GlobalState, transaction_sequence: Dict) -> Issue: |
|
|
|
|
""" |
|
|
|
|
Returns Issue for the annotation |
|
|
|
|
:param global_state: Global State |
|
|
|
|
:param transaction_sequence: Transaction sequence |
|
|
|
|
:return: Issue |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
address = self.call_state.get_current_instruction()["address"] |
|
|
|
|
logging.debug( |
|
|
|
|
"[DELEGATECALL] Detected delegatecall to a user-supplied address : {}".format( |
|
|
|
|
address |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
description_head = "The contract delegates execution to another contract with a user-supplied address." |
|
|
|
|
description_tail = ( |
|
|
|
|
"The smart contract delegates execution to a user-supplied address. Note that callers " |
|
|
|
|
"can execute arbitrary contracts and that the callee contract " |
|
|
|
|
"can access the storage of the calling contract. " |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return Issue( |
|
|
|
|
contract=self.call_state.environment.active_account.contract_name, |
|
|
|
|
function_name=self.call_state.environment.active_function_name, |
|
|
|
|
address=address, |
|
|
|
|
swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, |
|
|
|
|
title="Delegatecall Proxy To User-Supplied Address", |
|
|
|
|
bytecode=global_state.environment.code.bytecode, |
|
|
|
|
severity="Medium", |
|
|
|
|
description_head=description_head, |
|
|
|
|
description_tail=description_tail, |
|
|
|
|
transaction_sequence=transaction_sequence, |
|
|
|
|
gas_used=( |
|
|
|
|
global_state.mstate.min_gas_used, |
|
|
|
|
global_state.mstate.max_gas_used, |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DelegateCallModule(DetectionModule): |
|
|
|
|
"""This module detects calldata being forwarded using DELEGATECALL.""" |
|
|
|
|
|
|
|
|
@ -124,11 +70,36 @@ class DelegateCallModule(DetectionModule): |
|
|
|
|
transaction_sequence = solver.get_transaction_sequence( |
|
|
|
|
state, state.mstate.constraints + constraints |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
address = state.get_current_instruction()["address"] |
|
|
|
|
logging.debug( |
|
|
|
|
"[DELEGATECALL] Detected delegatecall to a user-supplied address : {}".format( |
|
|
|
|
address |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
description_head = "The contract delegates execution to another contract with a user-supplied address." |
|
|
|
|
description_tail = ( |
|
|
|
|
"The smart contract delegates execution to a user-supplied address. Note that callers " |
|
|
|
|
"can execute arbitrary contracts and that the callee contract " |
|
|
|
|
"can access the storage of the calling contract. " |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
DelegateCallAnnotation(state, constraints).get_issue( |
|
|
|
|
state, transaction_sequence=transaction_sequence |
|
|
|
|
Issue( |
|
|
|
|
contract=state.environment.active_account.contract_name, |
|
|
|
|
function_name=state.environment.active_function_name, |
|
|
|
|
address=address, |
|
|
|
|
swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, |
|
|
|
|
bytecode=state.environment.code.bytecode, |
|
|
|
|
title="Delegatecall Proxy To User-Supplied Address", |
|
|
|
|
severity="Medium", |
|
|
|
|
description_head=description_head, |
|
|
|
|
description_tail=description_tail, |
|
|
|
|
transaction_sequence=transaction_sequence, |
|
|
|
|
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), |
|
|
|
|
) |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
except UnsatError: |
|
|
|
|
return [] |
|
|
|
|
|
|
|
|
|