一键导入
crypto-recon-signing
Specialist agent for detecting ALL API request signing patterns in downloaded JS files. Highest value target. Part of crypto-recon pipeline.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Specialist agent for detecting ALL API request signing patterns in downloaded JS files. Highest value target. Part of crypto-recon pipeline.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Download all JS/WASM/CSS assets from a target URL using cloudscraper. Saves to output/[domain]/. Called by crypto-recon-orchestrator.
Specialist for EVM blockchain cryptography — EIP-712, personal_sign, ABI encoding, keccak256, ethers.js/wagmi/viem/web3.js. EVM chains only (Ethereum, Polygon, BSC, Arbitrum, etc.). For non-EVM use crypto-recon-web3-solana, crypto-recon-web3-cosmos, or crypto-recon-web3-starknet.
Verifies reconstructed APK signing logic against live app traffic. Uses HAR test vectors or ADB+mitmproxy. Extends crypto-recon-debugging for Android context.
Specialist for finding ALL cryptography in decompiled Android APK — Java source (jadx) and Smali bytecode (apktool). Covers OkHttp interceptors, Retrofit, HMAC, AES, MD5, custom signing, ProGuard-obfuscated code.
Master orchestrator for Android APK reverse engineering. Fully autonomous — decompiles APK, spawns 11 parallel specialists, collects findings, writes report, reconstructs Python code. No intermediate stops. Accepts .apk/.apkm/.xapk + optional HAR.
Builds a complete, clean, standalone Python script for a full API flow (login, register, place bet, etc). Accepts input from reconstruct_*.py files AND from APK flow mappers (Retrofit catalog, auth chain trace, API endpoint list). Called automatically after analysis — no user prompting needed. Uses superpowers executing-plans and verification-before-completion.
| name | crypto-recon-signing |
| description | Specialist agent for detecting ALL API request signing patterns in downloaded JS files. Highest value target. Part of crypto-recon pipeline. |
js-signing-patterns.md — All JS signing pattern families (sort+hash, HMAC, AES body, RSA field) with grep commandsjava-signing-patterns.md — Android OkHttp interceptor patterns, header injection, Retrofit, BuildConfig extractionFind every request signing mechanism — the code that generates signature, sign, token, nonce, or authentication parameters attached to API requests. This is the highest-value target because reconstructing it enables full API replication.
The canonical signing pattern (many variations exist):
// CANONICAL PATTERN — many variations of this exist
function generateSign(params) {
const nonce = uuid() // 1. random nonce
const ts = Date.now() // 2. timestamp
const filtered = filterNull(params) // 3. filter empty
const sorted = sortKeys(filtered) // 4. sort keys
const canonical = JSON.stringify(sorted) // 5. serialize
const signature = md5(canonical).toUpperCase()// 6. hash
return { nonce, ts, signature } // 7. return
}
function.*[Ss]ign.*\(
function.*[Ss]ignature.*\(
function.*[Gg]enerate.*[Ss]ign
function.*[Bb]uild.*[Ss]ign
function.*[Cc]reate.*[Ss]ign
function.*[Mm]ake.*[Ss]ign
function.*[Cc]ompose.*[Ss]ign
function.*[Cc]alc.*[Ss]ign
function.*[Cc]ompute.*[Ss]ign
function.*getSign\(
function.*makeToken\(
function.*buildAuth\(
function.*authHeader\(
function.*requestSign\(
function.*apiSign\(
Variable assignments:
sign\s*[:=]
signature\s*[:=]
token\s*[:=]
auth\s*[:=]
Object.keys(.*).sort(
Object.entries(.*).sort(
keys.sort(
params.sort(
[...Object.keys].sort(
Array.from(Object.keys).sort(
sorted = {}
sorted_params
sortedParams
filter(.*null
filter(.*undefined
filter(.*''
filter(.*""
val !== null
val !== undefined
val !== ''
Object.keys.*forEach.*if.*val
JSON.stringify(.*sort
qs.stringify(.*sort
queryString.*sort
Object.entries.*sort.*map.*join
keys.sort.*map.*\${k}=\${v}.*join
uuid(), uuidv4(), uuid.v4()
Math.random().toString(36)
Math.random()*.*Math.floor
crypto.randomBytes(
crypto.getRandomValues(
nanoid(
Date.now().toString(36)
random\s*[:=]
nonce\s*[:=]
randomStr\s*[:=]
Date.now()
Math.floor(Date.now()/1000) ← unix seconds
parseInt(Date.now()/1000)
new Date().getTime()
Math.floor(new Date()/1000)
timestamp\s*[:=]
ts\s*[:=]
t\s*[:=].*Date
headers\[.*sign
headers\[.*signature
headers\[.*token
headers\[.*auth
headers\[.*nonce
params.signature
params.sign
params.token
params.auth
url.*\?.*sign=
url.*\?.*signature=
axios.interceptors.request
request.interceptors
Interceptors wrap ALL API calls — finding crypto here means you've found the universal signing logic:
// Axios interceptor — ALWAYS search for these
axios.interceptors.request.use(config => {
config.headers['X-Sign'] = generateSign(config.data)
return config
})
// Fetch wrapper
function request(url, options) {
const sign = buildSign(options.body)
return fetch(url, {
...options,
headers: { ...options.headers, 'Authorization': sign }
})
}
Search explicitly for:
axios.interceptors.request
instance.interceptors.request
interceptors.request.use
request.use(config
fetch.*headers.*sign
fetch.*headers.*auth
fetch.*headers.*token
Locate the signing function — use the patterns above
Extract the complete signing logic — including ALL helper functions it calls:
sortParams(x) → extract sortParams toofilterEmpty(x) → extract filterEmpty tooMap the exact parameter flow:
API caller passes: { userId: "123", amount: "100", extra: null }
↓
Filter step: remove null/"" → { userId: "123", amount: "100" }
↓
Sort step: sort keys alpha → { amount: "100", userId: "123" }
↓
Add random: add nonce field → { amount: "100", nonce: "abc", userId: "123" }
↓
Serialize: JSON.stringify → '{"amount":"100","nonce":"abc","userId":"123"}'
↓
Hash: md5(str).upper() → "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6"
↓
Result: return { nonce, signature, timestamp }
Identify every field excluded from signing — these are the "exclude" lists:
const exclude = ['signature', 'track', '[appSpecificField]'] // ← extract verbatim from JS
Document the full exclude list verbatim.
Find the separator/format — how is canonical string built?
JSON.stringify(obj, null, 0) — no spacesJSON.stringify(obj, null, 2) — pretty printed (unusual)key=value&key2=value2 — query string formatkey:value,key2:value2 — custom formatCheck timestamp precision:
Date.now() → 13-digitMath.floor(Date.now()/1000) → 10-digitVerify output format — what exactly gets sent:
full md5 hex (32 chars)
upper md5 hex (32 chars)
first 16 chars of sha256
base64 of hmac-sha256
etc.
API SIGNING FINDINGS
====================
[SG1] MD5 Request Signing — HIGH
File: common.modules-6d4292d1.js
Line: 2847
Function: generateSignParams(data)
Called at: axios.interceptors.request.use (line 1100)
Algorithm: MD5, uppercase, full 32 chars
Nonce: uuid().hex → added as data["random"]
Timestamp: int(time.time()) → returned separately
Steps:
1. Add random nonce to data["random"]
2. Exclude keys: ["signature", "track", "[appSpecificField]"] ← copy verbatim from JS
3. Exclude null/empty string values
4. Sort remaining keys alphabetically
5. JSON.stringify with no spaces, ensure_ascii=False
6. MD5(canonical_string).hexdigest().upper()[:32]
7. Return (nonce, signature, timestamp)
HTTP injection:
→ request body: { ...params, random, signature, timestamp }
Callers: [callerFunc]:1203, [callerFunc]:3401, [callerFunc]:5102
Full function code:
[include verbatim JS code here]