# Active Exploit Response

> Active Exploit Response

- Skill: `nickgallick/active-exploit-response` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nickgallick/active-exploit-response`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nickgallick/active-exploit-response/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: nickgallick (https://skillmd.com/u/nickgallick)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nickgallick/active-exploit-response

---

# Active Exploit Response

## The First 60 Minutes — Minute by Minute

### Minute 0-2: DETECT AND CONFIRM

```
Trigger sources (ranked by speed):
  1. Forta bot alert (fastest — sub-block detection)
  2. OpenZeppelin Defender Sentinel (block-level)
  3. Community member in Discord/Telegram saying "funds moving"
  4. You see it yourself on Etherscan

Confirm it's real — 90 seconds maximum:
  □ Open Etherscan → check attacker address balance
  □ Check protocol's contract balance: cast balance $CONTRACT --rpc-url $RPC
  □ Is the drain tx confirmed or still pending?
    - PENDING: you may be able to front-run the pause. Move NOW.
    - CONFIRMED: assess how many more txs are possible

CRITICAL: DO NOT post publicly. DO NOT tweet. DO NOT DM on Telegram.
Every second of silence buys time. Every leak accelerates the attack.

Open Signal group with core team ONLY (pre-created, don't make it now).
```

### Minute 2-5: PAUSE EVERYTHING

```bash
# Priority gas — cost is irrelevant right now
export GAS_PRICE=$(cast gas-price --rpc-url $RPC)
export PRIORITY_GAS=$(echo "$GAS_PRICE * 10" | bc)  # 10x current

# Pause main contract
cast send $CONTRACT "pause()" \
  --rpc-url $RPC --private-key $DEPLOYER_KEY \
  --gas-price $PRIORITY_GAS

# Pause each vault individually (don't assume one pause covers all)
for vault in $VAULT_1 $VAULT_2 $VAULT_3; do
  cast send $vault "pause()" \
    --rpc-url $RPC --private-key $DEPLOYER_KEY \
    --gas-price $PRIORITY_GAS &
done
wait

# Verify pause took effect
cast call $CONTRACT "paused()(bool)" --rpc-url $RPC
# Must return: true
```

```
IF YOU DON'T HAVE PAUSE FUNCTIONS:
  Option A: Set fees to 100% — makes txs unprofitable
    cast send $CONTRACT "setFee(uint256)" 10000 ...

  Option B: Set minimum deposit to MAX_UINT
    cast send $CONTRACT "setMinDeposit(uint256)" \
      115792089237316195423570985008687907853269984665640564039457584007913129639935 ...

  Option C: Revoke approvals the attacker is using
    # If attacker exploits a token approval:
    cast send $TOKEN "approve(address,uint256)" $CONTRACT 0 ...

IF SAFE MULTISIG CONTROLS PAUSE:
  You need threshold signatures. Call signers on the PHONE right now.
  Not Signal. Not Telegram. Voice call.
  Read them the Safe tx hash on the call. They verify on Ledger screen.
  This is why you have phone numbers for every signer saved offline.
```

### Minute 5-10: ASSESS THE DAMAGE

```bash
# How much has been taken?
cast balance $ATTACKER_ADDRESS --rpc-url $RPC

# Is the attack ongoing? (is attacker still sending txs?)
cast tx $ATTACKER_ADDRESS --rpc-url $RPC
# Or check on Etherscan — look at "from: $ATTACKER" pending txs

# Read the attack tx
cast tx $ATTACK_TX_HASH --rpc-url $RPC

# Decode the calldata to understand the vector
cast decode-calldata "functionSig(args)" $CALLDATA

# What's still at risk?
cast call $CONTRACT "totalAssets()(uint256)" --rpc-url $RPC

# Can the attack be repeated?
# If YES: pause is critical. If paused, funds are safe.
# If NO: remaining funds safe even without pause (one-time exploit)
```

```
Attack vector identification (read the exploit tx traces):

Flash loan + oracle: look for FlashLoan event followed by price feed update
Reentrancy: same contract called recursively in trace
Access control: unauthorized address calling restricted function
Logic error: incorrect math in borrow/liquidation calculation — check amounts in vs out
Oracle manipulation: price oracle returns value far from market price just before drain
```

### Minute 10-15: CONTACT SEAL 911

```
Seal 911 contact:
  Telegram bot:  t.me/seal_911_bot
  Website:       seal911.org
  Direct:        reach out to samczsun on Twitter/Telegram if known attack

Information to send:
  - Protocol name
  - Chain (Ethereum/Base/Arbitrum/etc.)
  - Contract addresses (comma-separated)
  - Attacker address
  - Attack transaction hash
  - Approximate funds at risk (still in contract)
  - Whether pause is active

What Seal 911 provides:
  □ White hat rescue: exploit same vuln to drain remaining funds to YOUR safe address first
  □ Flashbots coordination: private bundle submission — attacker can't see or front-run
  □ Cross-chain tracking if attacker bridges out
  □ MEV searcher network to block attacker txs

Also contact:
  - Known security researchers directly (pcaversaccio, 0xRajeev, cmichel)
  - Exchange security teams (Binance: security@binance.com, Coinbase: security@coinbase.com)
  - If on Base: contact Coinbase/Base team directly — they move fast
```

### Minute 15-30: WHITE HAT RESCUE (if needed)

```typescript
// If pause didn't work and funds still draining:
// Deploy a rescue contract that uses the SAME vulnerability

// DOCUMENT YOUR INTENT BEFORE DEPLOYING:
// Create a timestamped record: "We are deploying a rescue contract to recover
// user funds from our own protocol using the identified vulnerability.
// All recovered funds will be returned to users. Tx: 0x..."

// Use Flashbots to submit privately (attacker can't see or front-run)
import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle";

const flashbots = await FlashbotsBundleProvider.create(provider, authSigner);

const rescueTx = {
  to: RESCUE_CONTRACT_ADDRESS,
  data: rescueCalldata,
  gasLimit: 500_000,
  maxFeePerGas: ethers.parseUnits("200", "gwei"),
  maxPriorityFeePerGas: ethers.parseUnits("10", "gwei"),
};

const bundle = [{ signer: rescueSigner, transaction: rescueTx }];

// Submit to Flashbots — visible only to validators, not public mempool
const targetBlock = await provider.getBlockNumber() + 1;
const simulation = await flashbots.simulate(bundle, targetBlock);
if ("error" in simulation) throw new Error(simulation.error.message);

await flashbots.sendBundle(bundle, targetBlock);
```

### Minute 30-45: FIRST PUBLIC COMMUNICATION

```
Draft (copy this template):

"We are aware of a security incident affecting [Protocol Name].

As a precaution, all protocol functions have been paused.

[User funds currently in the protocol / LP positions] are [safe / being assessed].

We are working with leading security researchers to assess the situation.

We will provide a full update within [2 hours].

Do not interact with the protocol until further notice.

— The [Protocol] Team"

Post to (in this order):
  1. Official Discord — pin the message, disable public channels
  2. Twitter/X — from official account only
  3. Telegram — official channel only

DO NOT:
  ✗ Disclose the vulnerability (copycats hit other protocols)
  ✗ State exact amount lost (you'll be wrong and it erodes trust)
  ✗ Speculate on cause
  ✗ Blame anyone
  ✗ Promise full recovery before you know if it's possible
```

### Minute 45-60: ESTABLISH WAR ROOM

```
Roles — assign now, one person each:

  INCIDENT COMMANDER: [Name]
    - Makes all final decisions
    - No committee — one person calls the shots
    - Everyone else advises

  TECHNICAL LEAD: [Name]
    - Analyzes exploit mechanics
    - Develops fix
    - Coordinates with security researchers

  COMMUNICATIONS: [Name]
    - All public statements go through them
    - Responds to media, community
    - Nothing gets posted without their sign-off

  LEGAL: [Name or firm]
    - Law enforcement contact if needed
    - Bounty negotiations
    - User liability

War room channel: pre-created Signal group
Meeting cadence: every 30 minutes for first 6 hours, then hourly

Forensics to complete in this window:
  □ Full attack trace documented
  □ Root cause identified (not just "reentrancy" but specifically which function)
  □ All affected contract addresses listed
  □ Total funds lost confirmed
  □ Is fix identified?
  □ Who wrote the vulnerable code? (internal post-mortem, not public blame)
```

### Post-Incident: Negotiate Return

```
On-chain message to attacker (send 0 ETH with data in input field):

cast send $ATTACKER_ADDRESS \
  --value 0 \
  --data $(cast from-utf8 "We know the origin of the funds. Return 90% to $SAFE_ADDRESS within 48 hours and keep 10% as a bounty. We will not pursue legal action. After 48 hours we engage law enforcement and blockchain forensics.") \
  --rpc-url $RPC --private-key $DEPLOYER_KEY

Real examples where this worked:
  Euler Finance: $197M returned after negotiation
  Poly Network: $611M returned ("the biggest hack in DeFi history")
  Curve Finance: ~$73M, partial return

If no response in 48 hours:
  □ File FBI IC3 report: ic3.gov
  □ Engage Chainalysis or TRM Labs for formal forensics report
  □ Contact major CEX security teams with attacker address
  □ Some jurisdictions allow emergency court orders to freeze CEX accounts
```

## Pre-Incident Checklist (Do This Now)

```
□ Seal 911 contact saved in your phone (t.me/seal_911_bot)
□ All contract owners have phone numbers for each other
□ Pause functions on EVERY contract that holds value
□ Forta monitoring bot deployed and alerting
□ OpenZeppelin Defender Sentinel configured
□ War room Signal group pre-created with all core team
□ Legal counsel on retainer who understands crypto
□ Flashbots auth signer pre-funded and ready
□ Consider Nexus Mutual or InsurAce coverage
□ Incident commander pre-designated — no ambiguity
```

