Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
memory_size: Union[int, BitVec],
):
"""Gets call_data from the global_state.
:param global_state: state to look in
:param memory_start: Start index
:param memory_size: Size
:return: Tuple containing: call_data array from memory or empty array if symbolic, type found
"""
state = global_state.mstate
transaction_id = "{}_internalcall".format(global_state.current_transaction.id)
memory_start = cast(
BitVec,
(
symbol_factory.BitVecVal(memory_start, 256)
if isinstance(memory_start, int)
else memory_start
),
)
memory_size = cast(
BitVec,
(
symbol_factory.BitVecVal(memory_size, 256)
if isinstance(memory_size, int)
else memory_size
),
)
uses_entire_calldata = simplify(
memory_size == global_state.environment.calldata.calldatasize
)
length = func_input.size()
func, inv = self.get_function(length)
try:
index = self.interval_hook_for_size[length]
except KeyError:
self.interval_hook_for_size[length] = self._index_counter
index = self._index_counter
self._index_counter -= INTERVAL_DIFFERENCE
lower_bound = index * PART
upper_bound = lower_bound + PART
cond = And(
inv(func(func_input)) == func_input,
ULE(symbol_factory.BitVecVal(lower_bound, 256), func(func_input)),
ULT(func(func_input), symbol_factory.BitVecVal(upper_bound, 256)),
URem(func(func_input), symbol_factory.BitVecVal(64, 256)) == 0,
)
return cond
def _load(self, item: Union[int, Expression]) -> Any:
"""
:param item:
:return:
"""
if isinstance(item, int):
try:
return self._calldata[item]
except IndexError:
return 0
value = symbol_factory.BitVecVal(0x0, 8)
for i in range(self.size):
value = If(cast(Union[BitVec, Bool], item) == i, self._calldata[i], value)
return value
def _make_bitvec_if_not(stack, index):
value = stack[index]
if isinstance(value, BitVec):
return value
stack[index] = symbol_factory.BitVecVal(value, 256)
return stack[index]
def _analyze_state(self, state):
"""
:param state:
:return:
"""
write_slot = state.mstate.stack[-1]
constraints = state.world_state.constraints + [
write_slot == symbol_factory.BitVecVal(324345425435, 256)
]
potential_issue = PotentialIssue(
contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name,
address=state.get_current_instruction()["address"],
swc_id=WRITE_TO_ARBITRARY_STORAGE,
title="Write to an arbitrary storage slot",
severity="High",
bytecode=state.environment.code.bytecode,
description_head="Any storage slot can be written by the caller.",
description_tail="The attacker can modify any value in the storage."
+ " This can lead to unintended consequences.",
detector=self,
constraints=constraints,
)
def _add_external_call(global_state: GlobalState) -> None:
gas = global_state.mstate.stack[-1]
to = global_state.mstate.stack[-2]
try:
constraints = copy(global_state.mstate.constraints)
solver.get_model(
constraints
+ [
UGT(gas, symbol_factory.BitVecVal(2300, 256)),
Or(
to > symbol_factory.BitVecVal(16, 256),
to == symbol_factory.BitVecVal(0, 256),
),
]
)
# Check whether we can also set the callee address
try:
constraints += [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF]
solver.get_model(constraints)
global_state.annotate(StateChangeCallsAnnotation(global_state, True))
except UnsatError:
global_state.annotate(StateChangeCallsAnnotation(global_state, False))
except UnsatError:
pass
def iszero_(self, global_state: GlobalState) -> List[GlobalState]:
"""
:param global_state:
:return:
"""
state = global_state.mstate
val = state.stack.pop()
exp = Not(val) if isinstance(val, Bool) else val == 0
exp = If(
exp, symbol_factory.BitVecVal(1, 256), symbol_factory.BitVecVal(0, 256)
)
state.stack.append(simplify(exp))
return [global_state]
def __init__(
self,
creator=0xAFFEAFFEAFFEAFFEAFFEAFFEAFFEAFFEAFFEAFFE,
attacker=0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF,
someguy=0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
):
self.addresses = {
"CREATOR": symbol_factory.BitVecVal(creator, 256),
"ATTACKER": symbol_factory.BitVecVal(attacker, 256),
"SOMEGUY": symbol_factory.BitVecVal(someguy, 256),
}
def _analyze_state(self, state: GlobalState) -> List[PotentialIssue]:
"""
:param state: the current state
:return: returns the issues for that corresponding state
"""
gas = state.mstate.stack[-1]
to = state.mstate.stack[-2]
constraints = [
to == ATTACKER_ADDRESS,
UGT(gas, symbol_factory.BitVecVal(2300, 256)),
state.new_bitvec(
"retval_{}".format(state.get_current_instruction()["address"]), 256
)
== 1,
]
for tx in state.world_state.transaction_sequence:
if not isinstance(tx, ContractCreationTransaction):
constraints.append(tx.caller == ATTACKER_ADDRESS)
try:
address = state.get_current_instruction()["address"]
logging.debug(
"[DELEGATECALL] Detected potential delegatecall to a user-supplied address : {}".format(
address
if (
isinstance(key, BitVecFunc)
and not isinstance(key.input_, BitVecFunc)
and isinstance(key.input_, BitVec)
and key.input_.symbolic
and key.input_.size() == 512
):
pseudo_input = random.randint(0, 2 ** 256 - 1)
hex_v = hex(pseudo_input)[2:]
if len(hex_v) % 2 == 1:
hex_v += "0"
hash_val = symbol_factory.BitVecVal(
int(sha3.keccak_256(bytes.fromhex(hex_v)).hexdigest()[2:], 16),
256,
)
pseudo_input = symbol_factory.BitVecVal(pseudo_input, 256)
calldata_cond = And(
calldata_cond,
Extract(511, 256, key.input_) == hash_val,
Extract(511, 256, key.input_).potential_input == pseudo_input,
)
Extract(511, 256, key.input_).potential_input_cond = calldata_cond
if not is_true(simplify(Extract(511, 256, key.input_).potential_input_cond != calldata_cond)):
print(key.input_, Extract(511, 256, key.input_).concat_args)
assert Extract(511, 256, key.input_).potential_input_cond == calldata_cond
print(Extract(511, 256, key.input_), calldata_cond, "CONDED")
for actor in ACTOR_ADDRESSES:
try:
models_tuple.append(
(
get_model(
constraints=global_state.mstate.constraints