Abusing the Ethereum Smart Contract Verification Services for Fun and Profit

Pengxiang Ma

Network and Distributed System Security (NDSS) Symposium 2024 · Day 2 · Blockchain & Smart Contracts · Blockchain & Smart Contracts

Overview

In the intricate and high-stakes world of blockchain, trust is paramount, especially when billions of dollars in assets are managed by smart contracts. The integrity of these contracts hinges on a crucial, yet often overlooked, component: smart contract verification services. This talk, "Abusing the Ethereum Smart Contract Verification Services for Fun and Profit," presented by Pengxiang Ma at the NDSS Symposium, shines a much-needed spotlight on the pervasive security vulnerabilities within these fundamental services. The presentation delves into how attackers can exploit weaknesses in platforms like Etherscan, Sourcify, and Blockscout to either discredit legitimate contracts or cloak malicious ones under a veneer of trustworthiness, leading to significant financial losses and erosion of user confidence.

Slides

Visual summary for Abusing the Ethereum Smart Contract Verification Services for Fun and Profit by Pengxiang Ma
Visual summary for Abusing the Ethereum Smart Contract Verification Services for Fun and Profit by Pengxiang Ma

Key moments

  1. 0:00 Introduction: Critical role and security gap of verification
  2. 2:00 Smart contract basics and verification process explained
  3. 4:00 Adversary models: A1 (Adversarial Verification) and A2 (Source Scam)
  4. 6:00 Overview of verifier architecture and M1 module

Abusing the Ethereum Smart Contract Verification Services for Fun and Profit

Speakers: Pengxiang Ma

Conference: NDSS Symposium

YouTube: (no public video)

Overview

In the intricate and high-stakes world of blockchain, trust is paramount, especially when billions of dollars in assets are managed by smart contracts. The integrity of these contracts hinges on a crucial, yet often overlooked, component: smart contract verification services. This talk, "Abusing the Ethereum Smart Contract Verification Services for Fun and Profit," presented by Pengxiang Ma at the NDSS Symposium, shines a much-needed spotlight on the pervasive security vulnerabilities within these fundamental services. The presentation delves into how attackers can exploit weaknesses in platforms like Etherscan, Sourcify, and Blockscout to either discredit legitimate contracts or cloak malicious ones under a veneer of trustworthiness, leading to significant financial losses and erosion of user confidence.

The core of the issue lies in the process of matching a deployed contract's bytecode with its human-readable source code. This verification is essential for transparency, enabling users to audit contracts, and empowering downstream security tools to detect vulnerabilities. Despite their critical role in establishing mutual trust and supporting the broader Ethereum ecosystem, these verification services have historically lacked comprehensive security analysis. Ma's research fills this critical void, providing the first systematic investigation into their architecture, identifying eight distinct classes of vulnerabilities, and demonstrating their real-world exploitability across mainstream platforms.

The implications of these findings are profound. A compromised verification service can allow malicious actors to replace a legitimate contract's source code with discrediting information (Adversarial Verification), or conversely, verify a malicious contract with benign-looking source code (Source Scam). Such exploits undermine the very foundation of trust in decentralized applications, impacting users, developers, and the integrity of essential tools like vulnerability detectors and auditing services. Ma's work not only exposes these severe weaknesses but also proposes concrete mitigation strategies, urging the community to address this urgent security gap for the stability and trustworthiness of Ethereum.

Background

[▶ Watch: Introduction: Critical role and security gap of verification (0:00)]()

Ethereum smart contracts form the backbone of decentralized applications, written primarily in Solidity, a high-level programming language. These contracts are then compiled into EVM bytecode, which is the executable format stored on the blockchain. A typical EVM bytecode consists of three main parts: creation code, which executes once to deploy the contract; runtime code, containing the contract's core logic; and metadata, a fixed-length hash of compilation information appended to the runtime code, often used for indexing. The inherent unreadability of bytecode makes it nearly impossible for users to understand a contract's true functionality or distinguish legitimate tokens from scams.

This transparency challenge led to the emergence of smart contract verification services. Platforms like Etherscan, Blockscout, and Sourcify allow users to upload source code, compiler settings, and the on-chain address of a deployed contract. The service then compiles the provided source code and compares the resulting bytecode with the one on-chain. A successful match results in the source code being labeled as "verified" and made publicly accessible. Verification can be a partial match (bytecode identical except for metadata) or an exact match (everything, including metadata, is identical). Sourcify differentiates these, allowing an exact match to override a partial one, while Etherscan and Blockscout do not allow replacements for manually verified contracts.

Despite their critical function, a surprisingly low percentage of contracts are manually verified: less than 1% on Etherscan, 0.7% on Sourcify, and 0.3% on Blockscout. This leaves an enormous attack surface, as a vast majority of contracts remain unverified, making them susceptible to adversarial verification attempts. Furthermore, even for verified contracts, the integrity of the verification process itself has largely been taken for granted. Prior research on blockchain security and scams has primarily focused on on-chain vulnerabilities or social engineering, rarely delving into the security of the off-chain verification infrastructure. This talk highlights this significant oversight, emphasizing that compromised verification services can render all downstream security analyses, which assume correct source code, unreliable.

Key Findings

[▶ Watch: Smart contract basics and verification process explained (2:00)]()

The research presented by Pengxiang Ma represents the first comprehensive security analysis of widely-adopted Ethereum smart contract verification services. The investigation uncovered eight distinct types of previously overlooked but exploitable vulnerabilities inherent in the design and implementation of Etherscan, Sourcify, and Blockscout. Through rigorous detection and exploitation methods, the study revealed a staggering 19 exploitable vulnerabilities across these three popular platforms.

The impact of these vulnerabilities is categorized into two primary adversary models: Adversarial Verification (A1), where an attacker verifies a victim's contract with forged, discrediting source code, and Source Scam (A2), where an attacker verifies their own malicious contract with seemingly benign source code to deceive users. The findings demonstrate an "extreme negative impact" on the Ethereum ecosystem, with tens of millions of innocent contracts susceptible to abuse under A1-related vulnerabilities. For instance, over 49,000 contracts on the mainnet were identified as influenced by R1 (Exploitable Compiler Features), and approximately 58.9 million unverified contracts on Sourcify were found vulnerable to R2 and R3.

Furthermore, the research found evidence of hundreds of contracts already manipulated for fraud through A2-related vulnerabilities. Specifically, 2 contracts were suspected of abusing R4 (Replaceable On-chain Contracts), including a $750,000 financial loss related to a Tornado.cash attack. For R5 (Unverified Linked Libraries), 244 contracts were suspected of abuse, with at least 6 confirmed instances leading to significant financial damage, such as a $7.2 million loss from an attack on Saddle Finance.

Crucially, the research team responsibly disclosed all identified vulnerabilities to the respective verifier teams. Out of the 19 uncovered vulnerabilities, 15 have been officially confirmed, and 10 have already been patched, some within 12 hours for Sourcify and Blockscout. However, R1, R4, R5, and R8 remained exploitable in almost all verifiers at the time of the talk, highlighting ongoing challenges and the need for continuous vigilance.

Technical Deep Dive

[▶ Watch: Adversary models: A1 (Adversarial Verification) and A2 (Source Scam) (4:00)]()

The comprehensive security analysis began by abstracting the general workflow of Etherscan, Sourcify, and Blockscout into six interconnected modules (M1-M6) and identifying two key security properties, Unrestorability (P1) and Consistency (P2), which these services should ideally uphold.

Verifier Architecture (M1-M6):

  • Module 1 (M1): Untrusted Source Code Data Acquisition is responsible for collecting user inputs: source code files (potentially multiple in JSON format), configuration items (compiler version, optimization settings), and the target contract address. Blockscout additionally requires the contract name.
  • Module 2 (M2): On-chain Data Acquisition retrieves the contract's runtime code using eth.getCode() and the full bytecode (creation code + runtime code) by querying third-party databases for the creation transaction hash, then using eth_getTransactionByHash() to extract it from the transaction's input field.
  • Module 3 (M3): Compilation Module invokes the solc compiler to deterministically compile the provided source code and configuration into bytecode and runtime code. A significant challenge here is handling immutable variables, whose values are determined at deployment. Verifiers employ two strategies:
  1. Directly replacing immutable variables: Blanks are left during compilation and filled in by fetching corresponding bytes from the on-chain runtime code before comparison.
  2. Simulating creation code: eth_call() is used to simulate the creation code's execution, dynamically assigning values (e.g., msg.sender for an owner) to avoid hardcoding.
  • Module 4 (M4): Comparison Module compares the locally compiled bytecode with the on-chain version. Challenges include:
  • Constructor parameters: Bytecode from creation transactions may include these. Verifiers often use prefix matching, checking if the compiled bytecode is a prefix of the on-chain one.
  • Metadata: Must be identified and removed before comparison. Sourcify uses regex matching at the end of the runtime code, while Blockscout uses a differential extracting method by observing byte changes after inserting a meaningless configuration item.
  • Module 5 (M5): Data Storage Module stores the verified source code. Etherscan and Blockscout use centralized backend servers, raising single point of failure concerns. Sourcify, for higher confidence, uses IPFS, a decentralized file system.
  • Module 6 (M6): Display & API Module serves the verified source code and metadata to users. Sourcify also provides a metadata file with all uploaded configuration items.

Beyond these modules, the researchers identified two significant shortcuts implemented to reduce workload:

  1. Source Code Inheritance across Identical Runtime Code: Etherscan and Blockscout automatically verify all contracts with identical runtime code if one instance is verified, common for factory-deployed contracts.
  2. Source Code Inheritance across Platforms: Blockscout inherits verification results directly from Sourcify. Etherscan does not participate in this.

For Etherscan, being closed-source, a black-box testing approach was used, involving deploying contracts, crafting source code, and observing verification outcomes to infer its internal logic (e.g., metadata identification varies by solc version).

Security Properties and Vulnerabilities:

The analysis is framed around two security properties:

  • Property 1 (P1): Unrestorability: It should be impossible to obtain source code via reverse engineering or compiler exploitation that passes verification but is not the original. This prevents forging and misrepresentation. P1 is threatened by M3 and M4 vulnerabilities.
  • Property 2 (P2): Consistency: The semantics of the verified source code must be identical to the on-chain contract, with no redundancy or absence. This ensures displayed information is accurate. P2 is threatened by M2, M3, M4, M5, and M6 vulnerabilities.

The eight identified vulnerability types (R1-R8) are categorized by their impact:

Vulnerabilities Leading to Adversarial Verification (A1):

  • R1: Exploitable Compiler Features: Abuses solc features like YUL and loose inline assembly (especially with solc = 0.4), which allow direct opcode designation.
  • PoC: Craft a contract A_ with a fallback function using inline assembly to replicate a victim contract A's runtime code (excluding metadata), allowing A_ to pass verification for A. Etherscan's shortcut then applies A_'s source to A.
  • Impact: Over 49,000 mainnet contracts influenced by R1, including 25,000 ERC20 and 2,440 ERC721 tokens.
  • R2: Unchecked Simulating: Exploits Sourcify's M3 strategy of simulating creation code for immutable variables.
  • PoC: Construct a wrapper contract A_ that explicitly returns the victim A's runtime code before the actual codecopy opcode, tricking the simulator into returning A's runtime code prematurely.
  • Impact: Affects all unverified Solidity contracts in Sourcify (approx. 58.9 million) and 9,000 partially verified contracts.
  • R3: Incomplete Bytecode Validation: Arises from verifiers using prefix matching for constructor parameters, allowing empty or invalid prefixes to pass.
  • PoC: Use an abstract contract (e.g., WrappedToken) which compiles to empty bytecode, serving as a prefix for any on-chain bytecode. This can display misleading ABI functions with fake vulnerabilities.
  • Impact: Affects all unverified Solidity contracts in Sourcify (approx. 58.9 million).

Vulnerabilities Leading to Source Scam (A2):

  • R4: Replaceable On-chain Contracts: Exploits features like the create2 opcode and selfdestruct, allowing a contract at a specific address to be replaced, invalidating prior verification.
  • PoC: Deploy a benign contract A using create2, verify it, then selfdestruct A, and redeploy a malicious A_ to the exact same address using create2. The verification results for A are then mistakenly bound to A_.
  • Impact: Found in 2 suspected contracts, including a $750,000 loss in a Tornado.cash attack.
  • R5: Unverified Linked Libraries: Occurs when verifiers only check function signatures of linked libraries (invoked via delegatecall) but not their actual implementations.
  • PoC: Deploy a contract A that calls a malicious linked library L (e.g., containing selfdestruct). Then, upload a benign version of L with an identical function signature for verification. Verification passes, hiding the malicious logic.
  • Impact: Found in 244 suspected contracts, with 6 confirmed instances, including a $7.2 million loss from a Saddle Finance attack.
  • R6: Mislabeled Bytecode: Verifiers intentionally skip or mislabel fields (metadata, linked library placeholders) during comparison, leading to inconsistency.
  • PoC #1 (Blockscout): Import a file with a specific name (SOME_TEXT_USED_AS_FILENAME). Deploy a contract with a malicious selfdestruct opcode where Blockscout would insert its predefined library placeholder. Blockscout mislabels the selfdestruct as metadata and removes it, allowing verification with benign source.
  • PoC #2 (Sourcify): Define filePath and libName as regex patterns. Sourcify's regex matching for placeholders replaces valid runtime logic with a predefined byte sequence, allowing malicious code injection.
  • R7: Path Traversal Risk: Verifiers don't strictly validate paths in solc JSON files, allowing attackers to use ../ to traverse directories and overwrite existing source code.
  • PoC: An attacker deploys a malicious contract A. They then deploy a benign A_ but claim its path during verification is ../../0x12..fe/source/A.sol, overwriting A's source.
  • R8: Inadequate Information Disclosure: Misleading or ambiguous information displayed by verifiers, such as displaying a contract's name without its directory.
  • PoC: Upload two erc721.sol contracts, one in test/ and one in main/, with different totalSupply values. If the verifier only displays "erc721.sol," users might be fooled into trusting the main/ version with a seemingly limited edition, unaware of the higher totalSupply in the test/ version.

Demo / Proof of Concept

[▶ Watch: Overview of verifier architecture and M1 module (6:00)]()

The talk detailed various Proof of Concept (PoC) demonstrations, primarily conducted on the Goerli testnet to ensure ethical considerations and avoid impacting the Ethereum mainnet. These PoCs served to unequivocally prove the exploitability of each identified vulnerability.

For R1 (Exploitable Compiler Features), a PoC involved a victim contract A with runtime code 0x608060.... The attacker would craft a contract A_ (Listing 1 in the paper) containing only a fallback function. Within this function, loose inline assembly was used to verbatim replicate A's runtime code, excluding its metadata. By compiling A_ and manually replacing its metadata with A's, A_'s runtime code became identical to A's. This allowed A_ to successfully pass verification for A. Etherscan, due to its shortcut, then automatically labeled A as verified with A_'s malicious source code.

For R2 (Unchecked Simulating), targeting Sourcify, the PoC involved a deployed contract A. An attacker would construct A_ (Listing 2) that assigned A's runtime code to a bytes variable. Crucially, A_ included a YUL return statement that executed before the codecopy opcode in the creation code. This caused Sourcify's simulator to prematurely return a pointer to A's runtime code, achieving an exact match for A despite A_ not being A's original source.

The PoC for R3 (Incomplete Bytecode Validation) demonstrated how an abstract contract could be used. The attacker would choose an unverified victim contract and claim that a simple abstract contract, such as WrappedToken (Listing 3), was its corresponding source code. Abstract contracts compile to empty bytecode, which acts as a valid prefix for any on-chain bytecode. This allowed the attacker to display misleading ABI functions, such as a withdraw function with an apparent integer overflow vulnerability, effectively discrediting the actual deployed contract.

For R4 (Replaceable On-chain Contracts), the PoC (Figure 7 and Listing 4) illustrated a create2 fraud. First, a Dumper contract extracted its creation code. Then, a Deployer contract deployed a harmless contract A to a specific address using create2. A was successfully verified. Next, selfdestruct was called on A to free up the address. Finally, a malicious contract A_ was deployed to the identical address using create2. The previously established verification results for A were then mistakenly bound to the malicious A_, deceiving users.

For R5 (Unverified Linked Libraries), the PoC (Listing 5) involved a contract A calling L.check(), where L was a linked library. The attacker deployed a malicious version of L on-chain (e.g., with selfdestruct(msg.caller)). For verification, the attacker provided the original, benign source code for A and L. Since A was unchanged and L.check's signature was unaltered, verification passed, hiding the malicious selfdestruct within the linked library.

These and other PoCs were instrumental in demonstrating how each vulnerability could be exploited to achieve either adversarial verification or a source scam, providing concrete evidence of the security gaps in these critical services.

Defensive Implications

The findings of this research carry significant defensive implications for both smart contract verification service providers and the wider Ethereum ecosystem, including developers and users.

For Verification Service Providers (Etherscan, Sourcify, Blockscout, etc.):

  • Rethink Compilation Strategies (R2): Verifiers, particularly Sourcify, should abandon the "simulating creation code" strategy for handling immutable variables. As demonstrated, this relies on the EVM and can be exploited. The more secure "direct replacing" strategy should be universally adopted. Sourcify has already started moving in this direction based on the research.
  • Strengthen Bytecode Validation (R3): Implement strict non-null checks on locally compiled bytecode. An empty bytecode should never be accepted as a valid match. Furthermore, any suffix bytes after a matched prefix must be parsed as legal constructor parameters according to the contract's ABI.
  • Ensure Contract Immutability (R4): Verifiers must account for the dynamic nature of contract addresses and bytecode, especially with opcodes like create2 and selfdestruct. They should ensure the immutability of verified contracts and, if bytecode changes are detected for a previously verified address, immediately highlight the difference between the current and verified bytecode, or invalidate the verification.
  • Recursive Library Verification (R5): For contracts that invoke linked libraries, verifiers should recursively verify all invoked libraries. If full recursive verification is technically infeasible, they must explicitly warn users that linked library implementations are unverified and potentially unreliable.
  • Improve Bytecode Comparison Logic (R6): Simplify and harden the mechanisms for identifying and removing metadata or linked library placeholders. Blockscout's differential extracting method should be made less susceptible to mislabeling, and Sourcify should enumerate placeholders explicitly rather than relying on potentially exploitable regex matching.
  • Implement Robust Path Sanitization (R7): Verifiers must enforce comprehensive sanity checks on source code paths provided in JSON files, strictly adhering to best practices for path traversal prevention. Malicious inputs like ../ should be rejected or properly canonicalized.
  • Enhance Information Disclosure (R8): Ensure all displayed information is unambiguous and consistent with the compiler's output. If fields cannot be fully displayed (e.g., long file paths), the display should provide enough context (e.g., directory names) to prevent name collisions and user confusion.
  • Manage Compiler Features (R1): For features like loose inline assembly in solc = 0.4, which are necessary for efficiency but exploitable, verifiers should consider raising the threshold for verification requests (e.g., requiring prior authorization) or providing clear warnings to users when these features are heavily used, especially if source code replacement occurs.

For Users, Developers, and Downstream Applications:

  • Skepticism is Key: Do not blindly trust "verified" source code. Understand the limitations of verification services and be aware that even verified contracts can harbor hidden malicious logic.
  • Audit Dependencies (R5): If interacting with a contract that uses linked libraries, independently verify the source code of those libraries, not just the main contract.
  • Beware of Legacy Solc (R1): Exercise caution with contracts compiled using older solc versions (e.g., 0.4) that might leverage exploitable compiler features.
  • Contextual Awareness (R8): Pay close attention to the full context of contract information. If contract names appear ambiguous or lack full path details, investigate further.
  • Multi-Platform Verification: While Blockscout inherits from Sourcify, users should still be aware of the individual vulnerabilities of each platform. Decentralized services like Sourcify are generally preferred over centralized ones but are not immune to issues.
  • Downstream Tool Resilience: Developers of vulnerability detectors (e.g., Slither, Echidna) and auditing companies must no longer assume the integrity of fetched source code. Their tools need to incorporate mechanisms to detect potential source code manipulation or flag contracts verified under suspicious conditions.

In essence, the findings demand a shift from implicit trust to explicit verification and continuous security auditing of the verification infrastructure itself, which is as critical as the on-chain contracts they purport to represent.

Key Takeaways

  • Critical Infrastructure Under-Analyzed: Smart contract verification services, despite being fundamental for trust and security in the Ethereum ecosystem, have historically lacked comprehensive security analysis.
  • Widespread Vulnerabilities Discovered: The research identified 8 types of vulnerabilities, leading to 19 exploitable flaws across all three major verification platforms: Etherscan, Sourcify, and Blockscout.
  • Two Primary Attack Vectors: Vulnerabilities enable Adversarial Verification (A1), where attackers discredit legitimate contracts, and Source Scams (A2), where malicious contracts are hidden behind benign source code.
  • Significant Real-World Impact: Millions of innocent contracts are susceptible to adversarial verification, and hundreds of contracts have already been manipulated for fraud, leading to substantial financial losses (e.g., $750,000 and $7.2 million).
  • Urgent Need for Verifier Improvement: Service providers must prioritize robust bytecode validation, secure handling of compiler features and contract replacements, recursive verification of linked libraries, and unambiguous information disclosure.
  • User Vigilance and Tool Adaptation: Users and developers should exercise extreme caution, not blindly trusting verified source code, and downstream security tools must adapt to account for potential source code manipulation.

About the Speaker(s)

Pengxiang Ma is the researcher behind "Abusing the Ethereum Smart Contract Verification Services for Fun and Profit," a significant contribution to blockchain security presented at the NDSS Symposium. The transcript and metadata do not provide further details about their affiliation or specific title beyond their name. However, their work demonstrates a deep understanding of Ethereum's technical architecture and a keen eye for identifying critical, overlooked security vulnerabilities in widely-used services. Ma's research has directly led to the identification and patching of multiple zero-day vulnerabilities, significantly enhancing the security posture of the Ethereum smart contract verification ecosystem.

All talks from Network and Distributed System Security (NDSS) Symposium 2024