Reproducing and Exploiting ZK Circuit Vulnerabilities
written by Stefanos Chaliasos and Chenyang Yu on

zkbugs

Last February, we published a paper on systemizing vulnerabilities in Zero-Knowledge Proof (ZKP) implementations with collaborators from TUM, Imperial College London, Scroll, EF, and MatterLabs. Building on the dataset we released alongside the paper, we have been working to create a comprehensive GitHub repository where we reproduce known ZK circuit vulnerabilities.

Reproducing these vulnerabilities serves several important purposes:

  • Understanding Attack Vectors: Replicating vulnerabilities allows researchers and developers to gain deep insights into how specific attacks are executed. This understanding is crucial for identifying potential weaknesses in new systems and improving overall security measures.
  • Testing and Validating Fixes: By having a controlled environment to reproduce vulnerabilities, it becomes possible to test the efficacy of proposed fixes. This helps ensure that vulnerabilities are thoroughly patched and that no residual issues remain.
  • Educational and Research Value: Reproductions act as powerful educational tools, enabling the community to learn from existing vulnerabilities. This knowledge can be instrumental in identifying and mitigating similar issues in their own implementations.

The zkbugs Repository

We are excited to announce the launch of our GitHub repository dedicated to reproducing ZK circuit vulnerabilities. Currently, the repository contains 11 vulnerabilities, all of which are within the Circom DSL. However, we are actively working to expand this to include more DSLs and a broader range of vulnerabilities. You can find the repo here.

Each vulnerability within the repository is documented with a complete, end-to-end reproducible scripts that demonstrate how the exploit works. These scripts are designed to be as transparent and accessible as possible, providing users with a clear and detailed understanding of the vulnerability’s root cause and its exploitation.

Steps for Reproducing a Vulnerability

Reproducing a ZK circuit vulnerability typically involves several key steps, which we’ve carefully structured in our repository:

  1. Identifying the Vulnerability: The first step is to select a vulnerability that has been documented and has sufficient information available, including a description, source code, and ideally, a Proof of Concept (PoC). Note that most of the times PoC are not provided in the audit reports.
  2. Setting Up the Environment: Before diving into the reproduction, it’s essential to set up the environment. This includes installing all relevant dependencies for the DSL in which the vulnerable code is written. We provide helper scripts in the repository to streamline this process.
  3. Understanding the Exploit: Once the environment is ready, the next step is to analyze the vulnerable code to understand how the exploit can be executed. This often involves identifying specific points in the code where the logic fails, leading to an exploitable state. Typically, this information can be extracted by the bug report.
  4. Crafting the Exploit: After understanding the vulnerability, the next task is to craft the exploit. This typically involves manipulating input values or other parameters to trigger the vulnerability. In ZK circuits, this often means finding a witness that satisfies the constraints incorrectly, allowing the generation of a valid proof for an invalid statement. In many cases, this step is not trivial and we have been using Sage to help us come up with a malicious witness that surpass the constraints.
  5. Executing the Exploit: With the exploit crafted, it can then be executed using the scripts provided. This step involves running the code, generating the proof, and demonstrating that the verifier accepts the manipulated proof, thereby confirming the vulnerability.

Next Steps and Contributions

Moving forward, we are committed to expanding the repository with more vulnerabilities, covering additional DSLs, and improving our repo. Our goal is to create a robust resource that can be used by anyone interested in the security of ZK circuits.

We have already opened several issues in the repository, which anyone in the community is welcome to work on. Contributions are highly encouraged, whether by reproducing existing vulnerabilities, or improving the documentation and scripts. If you’re interested in contributing, please check out the open issues, and feel free to propose new ones.

In a following blog post, we will explain how we can create a PoC for a Circom vulnerability.