Exemplo n.º 1
0
def main():
    parser = argparse.ArgumentParser(
        description="Submit analysis to MythX API")
    create_parser(parser)
    args = parser.parse_args()

    config["endpoints"]["production"] = args.api_url

    handler = APIHandler(middlewares=[
        ClientToolNameMiddleware(name="ApiTests"),
        AnalysisCacheMiddleware(no_cache=args.no_cache),
    ])
    logging.info(f"Running MythX API tests without cache: {args.no_cache}")
    c = Client(eth_address=ETH_ADDRESS, password=PASSWORD, handler=handler)
    logging.info(f"Submit analysis to API: {args.api_url}")
    resp = c.analyze(**API_PAYLOAD)
    logging.info(resp.to_dict())

    while not c.analysis_ready(resp.uuid):
        logging.info("Checking analysis status")
        time.sleep(1)

    issues = c.report(resp.uuid)
    detected_issues = issues.to_dict()
    logging.info(json.dumps(detected_issues, indent=2))
    return detected_issues
Exemplo n.º 2
0
def analyze(contracts: List[SolidityContract],
            analysis_mode: str = "quick") -> Report:
    """
    Analyze contracts via the MythX API.

    :param contracts: List of solidity contracts to analyze
    :param analysis_mode: The mode to submit the analysis request with. "quick" or "full" (default: "quick")
    :return: Report with analyzed contracts
    """
    assert analysis_mode in ("quick",
                             "full"), "analysis_mode must be 'quick' or 'full'"

    c = Client(
        eth_address=os.environ.get("MYTHX_ETH_ADDRESS", TRIAL_ETH_ADDRESS),
        password=os.environ.get("MYTHX_PASSWORD", TRIAL_PASSWORD),
    )

    if c.eth_address == TRIAL_ETH_ADDRESS:
        print(
            "You are currently running MythX in Trial mode. This mode reports only a partial analysis of your smart contracts, limited to three vulnerabilities. To get a more complete analysis, sign up for a free account at https://mythx.io."
        )

    issues = []  # type: List[Issue]

    # TODO: Analyze multiple contracts asynchronously.
    for contract in contracts:
        source_codes = {}
        source_list = []
        sources = {}  # type: Dict[str, Any]
        main_source = None

        try:
            main_source = contract.input_file
            for solidity_file in contract.solidity_files:
                source_codes[solidity_file.filename] = solidity_file.data
            for filename in contract.solc_json["sources"].keys():
                sources[filename] = {}
                if source_codes[filename]:
                    sources[filename]["source"] = source_codes[filename]
                sources[filename]["ast"] = contract.solc_json["sources"][
                    filename]["ast"]

                source_list.append(filename)

            source_list.sort(
                key=lambda fname: contract.solc_json["sources"][fname]["id"])
        except AttributeError:
            # No solidity file
            pass

        assert contract.creation_code, "Creation bytecode must exist."
        try:
            resp = c.analyze(
                contract_name=contract.name,
                analysis_mode=analysis_mode,
                bytecode=contract.creation_code or None,
                deployed_bytecode=contract.code or None,
                sources=sources or None,
                main_source=main_source,
                source_list=source_list or None,
            )
        except MythXAPIError as e:
            log.critical(e)

        while not c.analysis_ready(resp.uuid):
            log.info(c.status(resp.uuid).analysis)
            time.sleep(5)

        for issue in c.report(resp.uuid):
            issue = Issue(
                contract=contract.name,
                function_name=None,
                address=issue.locations[0].source_map.components[0].offset
                if issue.locations else -1,
                swc_id=issue.swc_id[4:] or "None",  # remove 'SWC-' prefix
                title=issue.swc_title,
                bytecode=contract.creation_code,
                severity=issue.severity.capitalize(),
                description_head=issue.description_short,
                description_tail=issue.description_long,
            )
            issue.add_code_info(contract)
            issues.append(issue)

    report = Report(contracts=contracts)
    for issue in issues:
        report.append_issue(issue)

    return report
Exemplo n.º 3
0
for byte_file in binaries:
    print("Analyzing: %s" % byte_file)

    byte: str = ""

    try:
        byte = str(
            open(os.path.join(ROOT_BINARIES_DIR, byte_file), "r").read())
        assert len(byte) > 0
    except:
        print("Data Error in: %s ... Skipping" % byte_file)
        continue

    # submit bytecode, source files, their AST and more!
    resp = c.analyze(bytecode=byte, analysis_mode=ANALYSIS_MODE)

    # wait for the analysis to finish
    while not c.analysis_ready(resp.uuid):
        time.sleep(1)

    # have all your security report data at your fingertips
    for issue in c.report(resp.uuid):
        print(c.report)
        print(resp.uuid)
        print(dir(issue))
        issue_dict = issue.to_dict()
        log_string += ("\n\n\n\n" + "\n".join(
            ["%s : %s" % (k, issue_dict[k])
             for k in issue_dict.keys()]) + "\n\n\n")
        #log_string += "\n\n\n\nTitle: %s\n\nDescription: %s \n\n\n\n" % (issue.swc_title or "Undefined", issue.description_long or "Undefined")