mirror of https://github.com/ConsenSys/mythril
parent
d746ab1043
commit
5496ad2f58
@ -0,0 +1,41 @@ |
|||||||
|
from z3 import * |
||||||
|
import re |
||||||
|
from mythril.analysis.ops import * |
||||||
|
from mythril.analysis.report import Issue |
||||||
|
|
||||||
|
|
||||||
|
''' |
||||||
|
MODULE DESCRIPTION: |
||||||
|
|
||||||
|
Check for invocations of delegatecall(msg.data) in the fallback function. |
||||||
|
''' |
||||||
|
|
||||||
|
def execute(statespace): |
||||||
|
|
||||||
|
issues = [] |
||||||
|
|
||||||
|
for call in statespace.calls: |
||||||
|
|
||||||
|
if (call.type == "DELEGATECALL") and (call.node.function_name == "main"): |
||||||
|
|
||||||
|
stack = call.state.stack |
||||||
|
|
||||||
|
meminstart = get_variable(stack[-3]) |
||||||
|
|
||||||
|
if meminstart.type == VarType.CONCRETE: |
||||||
|
|
||||||
|
if (re.search(r'calldata.*_0', str(call.state.memory[meminstart.val]))): |
||||||
|
|
||||||
|
issue = Issue("CALLDATA forwarded with delegatecall()", "INFORMATION") |
||||||
|
issue.description = \ |
||||||
|
"The contract '" + str(call.node.module_name) + "' forwards its calldata via DELEGATECALL in its fallback function. " \ |
||||||
|
"This means that any function in the called contract can be executed. Make sure to scan with the -l option so dependencies are checked as well.\n" |
||||||
|
|
||||||
|
if (call.to.type == VarType.CONCRETE): |
||||||
|
issue.description += ("DELEGATECALL target: " + hex(call.to.val)) |
||||||
|
else: |
||||||
|
issue.description += "DELEGATECALL target: " + str(call.to) |
||||||
|
|
||||||
|
issues.append(issue) |
||||||
|
|
||||||
|
return issues |
@ -0,0 +1,30 @@ |
|||||||
|
class Issue: |
||||||
|
|
||||||
|
def __init__(self, title, _type = "INFORMATIONAL", description = ""): |
||||||
|
|
||||||
|
self.title = title |
||||||
|
self.description = description |
||||||
|
self.type = _type |
||||||
|
|
||||||
|
|
||||||
|
def as_dict(self): |
||||||
|
|
||||||
|
return {'title': self.title, 'description':self.description, 'type': self.type} |
||||||
|
|
||||||
|
|
||||||
|
class Report: |
||||||
|
|
||||||
|
def __init__(self, issues = []): |
||||||
|
self.issues = issues |
||||||
|
|
||||||
|
|
||||||
|
def as_text(self): |
||||||
|
text = "" |
||||||
|
|
||||||
|
for issue in self.issues: |
||||||
|
text += "=== " + issue.title + " ===\n" |
||||||
|
text += "STATUS: " + issue.type + "\n" |
||||||
|
text += issue.description + "\n" |
||||||
|
|
||||||
|
return text |
||||||
|
|
@ -1,9 +1,14 @@ |
|||||||
from .modules import ether_send |
from mythril.analysis.report import Report |
||||||
|
from .modules import delegatecall_forward, unchecked_suicide |
||||||
|
|
||||||
|
|
||||||
def fire_lasers(statespace): |
def fire_lasers(statespace): |
||||||
|
|
||||||
ether_send.execute(statespace) |
issues = [] |
||||||
|
|
||||||
pass |
issues += delegatecall_forward.execute(statespace) |
||||||
|
issues += unchecked_suicide.execute(statespace) |
||||||
|
|
||||||
|
report = Report(issues) |
||||||
|
|
||||||
|
print(report.as_text()) |
||||||
|
Loading…
Reference in new issue