Hunting in the Dark Forest: How I Uncovered a Private $25M Simulation Fork via an RPC…
quality 9/10 · excellent
0 net
Tags
Hunting in the Dark Forest: How I Uncovered a Private $25M Simulation Fork via an RPC… | by Hacker MD - Freedium
Milestone: 20GB Reached
We’ve reached 20GB of stored data — thank you for helping us grow!
Patreon
Ko-fi
Liberapay
Close
< Go to the original
Hunting in the Dark Forest: How I Uncovered a Private $25M Simulation Fork via an RPC…
Bug bounty hunting in Web3 isn't just about analyzing smart contracts for reentrancy or logic flaws. Sometimes, the biggest vulnerabilities…
Hacker MD
Follow
~4 min read
·
February 27, 2026 (Updated: February 27, 2026)
·
Free: Yes
Bug bounty hunting in Web3 isn't just about analyzing smart contracts for reentrancy or logic flaws. Sometimes, the biggest vulnerabilities hide in the off-chain infrastructure.
In this write-up, I'll share my experience of discovering a highly sensitive infrastructure misconfiguration in a prominent DeFi protocol (let's call it TargetX ). What started as a simple API scan escalated into uncovering a private simulation environment containing over $25 Million in manipulated assets, and how I had to prove my case when the triage team initially rejected it.
Phase 1: The Initial Recon and the Bypass
While analyzing TargetX's web applications, I noticed they were making requests to a custom RPC endpoint: https://rpc.target.com .
Out of curiosity, I sent a basic POST request to the root endpoint. As expected, it returned a 403 Forbidden / Gateway Error . The developers had clearly put a firewall or reverse proxy in front of it.
However, in the Web3 world, RPC endpoints often route traffic based on Chain IDs. I decided to fuzz the URL paths by appending standard EVM Chain IDs.
The Bypass:
Sending a request to https://rpc.target.com/1 (appending /1 for Ethereum Mainnet) bypassed the 403 restriction entirely! The endpoint responded with a valid 200 OK JSON-RPC response.
Phase 2: The $22 Million Discrepancy
Now that I had unauthenticated access to their internal node, I wanted to see what state this node was tracking. I targeted one of TargetX's core vault contracts ( 0xVaultAddress... ) and queried its balance. curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xVaultAddress...", "latest"],"id":1}' \
https://rpc.target.com/1
The Result: 0x22d68445673d07axxxx
Converting this hex to decimal revealed a staggering balance of ~10,282 ETH (worth around $25+ Million at the time).
But here was the catch: I cross-referenced this exact contract address on the real Ethereum Mainnet via Etherscan. The real balance was only ~2,599 ETH (around $7.7 Million).
Where did the extra $22 Million come from? ### Phase 3: Fingerprinting the Infrastructure
The balance mismatch was a massive red flag. Real public nodes mirror the exact state of the blockchain. This node was hallucinating funds. I needed to identify what backend technology TargetX was actually running.
I used the web3_clientVersion RPC method to fingerprint the node: curl -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' \
https://rpc.target.com/1
The Response: {"jsonrpc":"2.0","id":1,"result":"Tenderly/1.0"}
Bingo! The backend wasn't a standard Geth or Erigon node. It was a Tenderly Virtual Fork . TargetX had accidentally exposed their private, paid simulation and testing environment to the public internet without any API key authentication.
Phase 4: The Pushback from Triage
I quickly wrote up a detailed report explaining the exposed Tenderly fork, the information disclosure of internal EIP-1967 proxy slots, and the potential for infrastructure quota exhaustion.
A few hours later, I received a response from the triage team:
"Closed as Informative. This is just an erpc proxy routing to public nodes. The data you are fetching is public blockchain data. There is no security impact."
They completely missed the point. They assumed my results were just public Mainnet data. I needed a "Killer Proof" to demonstrate that this was a manipulatable simulation environment, not a read-only public proxy.
Phase 5: The "State Override" Nuke (Proving the Bug)
Public RPC proxies (like Infura, Alchemy, or generic public nodes) strictly prohibit unauthorized users from modifying the blockchain state. However, Tenderly simulation forks allow a powerful feature called State Overrides via the eth_call method.
I decided to perform a simulated hijacking of their Proxy Contract. I crafted a request to query the proxy's implementation address, but I injected a stateDiff parameter to artificially overwrite the EIP-1967 Logic Slot ( 0x360894... ) with a dummy address ( 0x1111... ). curl -X POST -H "Content-Type: application/json" \
--data '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[
{"to":"0xVaultAddress...", "data":"0xd781aaec"},
"latest",
{
"0xVaultAddress...": {
"stateDiff": {
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3caxxxxxxxxxx": "0x0000000000000000000000001111111111111111111111111111111111111111"
}
}
}
],
"id":1
}' \
https://rpc.target.com/1
The Result: {"jsonrpc":"2.0","id":1,"result":"0x"}
Checkmate. Because I overwrote the logic address with a non-existent contract ( 0x1111... ), the call returned 0x . If this had been a true public proxy as the triage team claimed, it would have rejected the stateDiff parameter entirely or returned the actual implementation address. The RPC processed my state override, definitively proving it was an active simulation environment.
The Resolution
I replied to the triage team with my final evidence:
The web3_clientVersion proving the Tenderly backend.
2. The $22M asset mismatch proving an artificial state.
3. The successful execution of a State Override proving simulation capabilities.
I politely explained that exposing a private development fork allows attackers to reverse-engineer unreleased protocol logic, perform dark-forest simulations on upcoming deployments, and exhaust their paid infrastructure quotas.
Shortly after, the team acknowledged the technical proof, reopened the ticket, and validated the vulnerability.
Takeaways for Web3 Bug Hunters
Always Fingerprint Your Nodes: Don't assume an RPC is just a standard Geth node. Use methods like web3_clientVersion to know exactly what you are talking to.
Look for State Discrepancies: Compare the data from the target's RPC against a public block explorer like Etherscan. Inconsistencies often reveal staging environments.
Don't Give Up on Triage: If you know your technical finding is correct, build an irrefutable Proof of Concept. The "State Override" technique is the ultimate way to prove you are inside a simulation fork.
Happy Hunting! 🐺
#Web3Security #BugBounty #Infosec #EthicalHacking #BlockchainSecurity #Ethereum #EVM #DeFiSecurity #SmartContracts #Tenderly #RPC
#web3 #bug-bounty #cybersecurity #ethereum #ethical-hacking
Reporting a Problem
Sometimes we have problems displaying some Medium posts.
If you have a problem that some images aren't loading - try using VPN. Probably you have problem with
access to Medium CDN (or fucking Cloudflare's bot detection algorithms are blocking you).