SKANF
SKANF is a static and symbolic analysis tool that finds asset-management vulnerabilities in closed-source or obfuscated EVM smart contracts by fetching deployed bytecode from a JSON-RPC endpoint and locating attacker-reachable sensitive external calls (e.g. ERC-20 transfer/transferFrom/approve on tokens like USDT or WBTC). Beyond detection, it includes an exploit-generation phase that symbolically synthesizes calldata satisfying a verified vulnerability's preconditions and replays it against a forked EVM to confirm real balance changes. It builds on custom forks of the greed symbolic execution engine and the Gigahorse decompiler, and accompanies the ACM CCS 2026 paper "Insecurity Through Obscurity: Veiled Vulnerabilities in Closed-Source Contracts."
What it is
SKANF ships as a Docker image (dockerofsyang/skanf:latest) with a two-phase pipeline: a detection phase that reports attacker-reachable sensitive external calls, and an exploit phase that synthesizes and replays calldata. This document covers what the summary omits — how to actually run it, the two analysis modes, and its hard dependency on an Ethereum RPC endpoint.
How it works
The detection phase reads a deployed contract's bytecode fetched over JSON-RPC and emits a JSON file listing verified and unverified vulnerable calls. The exploit generator then reads output_eval_baseline.json, walks the verified array, symbolically generates calldata satisfying each call's preconditions, and replays it against a forked EVM to confirm balance changes. Successful exploits land in Exploits/<contract>.<block>.json.
Two modes exist: eval_baseline (pure symbolic) and eval_concolic (seeded symbolic, where the seed comes from a historical transaction via --hash).
Preconditions
- A reachable Ethereum JSON-RPC endpoint.
WEB3_PROVIDERmust be set; if unset or unreachable, SKANF raises aRuntimeErrorat startup naming the offending URL. An archive node is recommended for analyses at older blocks; Tenderly's free plan suffices for basic testing. - Source build needs custom forks of greed and Gigahorse installed first (their
setup.shhandles the toolchain), thenpip install -r requirements.txt. The Dockerfile provisions Ubuntu 20.04, Miniconda + Python 3.10, Soufflé 2.4, and clones thegreed-skanffork at build time.
What to do
Pull and enter the container:
docker pull dockerofsyang/skanf:latest
export WEB3_PROVIDER="https://ethereum-mainnet.gateway.tenderly.co/<YOUR_TENDERLY_NODE_ACCESS_KEY>"
export NETWORK=ETH
export SKANF_IMAGE=dockerofsyang/skanf:latest
docker run --rm -it --network host \
-e WEB3_PROVIDER="$WEB3_PROVIDER" \
-e NETWORK="$NETWORK" \
"$SKANF_IMAGE" \
bashRun the detection phase in either mode:
# Pure symbolic, baseline output filename
python3 main.py --address 0xABC... --block 20000000 --mode eval_baseline
# Seeded symbolic, seed from a historical transaction
python3 main.py --address 0xABC... --block 20000000 \
--hash 0xdef... --mode eval_concolic--network host is Linux-only and needed only when the container must reach an RPC node on localhost:8545. On macOS/Windows, omit it and pass a remote RPC URL. See quickstart.md for on-disk layout and the schema of every output file.
Caveats
Detection output separates verified from unverified calls; the exploit phase only acts on the verified array, so unverified findings are not auto-confirmed. Confirmation is empirical — it depends on observing balance changes against a forked EVM at the specified block.
Organisations named here
- ACM CCS 2026
- Insecurity Through Obscurity: Veiled Vulnerabilities in Closed-Source Contracts
- Soufflé
Technologies named here
- Closed-source / obfuscated EVM smart contracts
- SKANF
- greed
- Gigahorse
- Soufflé 2.4
- Tenderly
- Docker
- Ethereum
- Solidity
- Python
Techniques named here
- Static + symbolic analysis of EVM bytecode
- Automated exploit calldata synthesis
- Pure symbolic execution
- Seeded symbolic execution
Related in AppSec
Flowise MCP Security Bypass Enables RCE
Inside an Oracle Database SQL Injection Attack | Huntress
OASIS
