opencode-skills-collection 4.0.43 → 4.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled-skills/.antigravity-install-manifest.json +47 -1
- package/bundled-skills/api-rate-limit-handler/SKILL.md +282 -0
- package/bundled-skills/api-security/SKILL.md +205 -0
- package/bundled-skills/api-security/references/jwt-oauth-testing.md +123 -0
- package/bundled-skills/api-security/references/rest-graphql-testing.md +137 -0
- package/bundled-skills/apk-reverse/SKILL.md +438 -0
- package/bundled-skills/apk-reverse/references/android-advanced.md +365 -0
- package/bundled-skills/apk-reverse/references/apk-security-checklist.md +230 -0
- package/bundled-skills/apk-reverse/references/frida-bypass-kit.md +70 -0
- package/bundled-skills/apk-reverse/references/frida-cookbook.md +472 -0
- package/bundled-skills/attack-chain/SKILL.md +185 -0
- package/bundled-skills/attack-chain/references/attack-playbooks.md +126 -0
- package/bundled-skills/attack-chain/references/evasion-cheatsheet.md +133 -0
- package/bundled-skills/attack-chain/references/lifecycle-checklist.md +37 -0
- package/bundled-skills/attack-chain/references/phases.md +490 -0
- package/bundled-skills/binary-diff/SKILL.md +320 -0
- package/bundled-skills/binary-diff/references/prompt-template.md +173 -0
- package/bundled-skills/browser-extension-reverse/SKILL.md +99 -0
- package/bundled-skills/browser-extension-reverse/references/extension-analysis.md +10 -0
- package/bundled-skills/case-review/SKILL.md +167 -0
- package/bundled-skills/cloud-k8s/SKILL.md +124 -0
- package/bundled-skills/cloud-k8s/references/k8s-cloud-checklist.md +16 -0
- package/bundled-skills/code-audit/SKILL.md +92 -0
- package/bundled-skills/code-audit/references/sast-review-checklist.md +10 -0
- package/bundled-skills/database-security/SKILL.md +81 -0
- package/bundled-skills/database-security/references/db-misconfig-checklist.md +9 -0
- package/bundled-skills/diagram-generator/SKILL.md +199 -0
- package/bundled-skills/diagram-generator/references/README.md +3 -0
- package/bundled-skills/diagram-generator/references/diagram-patterns.md +254 -0
- package/bundled-skills/digital-forensics/SKILL.md +93 -0
- package/bundled-skills/digital-forensics/references/forensics-triage.md +10 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +1 -1
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/sources/sources.md +9 -0
- package/bundled-skills/docs/users/aas-core.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +3 -3
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/docs-generator/SKILL.md +197 -0
- package/bundled-skills/docs-generator/references/security-report-templates.md +348 -0
- package/bundled-skills/docs-generator/references/templates.md +102 -0
- package/bundled-skills/docs-generator/references/vendor-report-rules.md +263 -0
- package/bundled-skills/dotnet-reverse/SKILL.md +197 -0
- package/bundled-skills/dotnet-reverse/references/common-workflow.md +171 -0
- package/bundled-skills/dotnet-reverse/references/obfuscators.md +145 -0
- package/bundled-skills/dotnet-reverse/references/sharp-tools.md +164 -0
- package/bundled-skills/edr-bypass-re/SKILL.md +248 -0
- package/bundled-skills/edr-bypass-re/references/hook-survey.md +226 -0
- package/bundled-skills/edr-bypass-re/references/telemetry-blinding.md +346 -0
- package/bundled-skills/edr-bypass-re/references/unhook-techniques.md +338 -0
- package/bundled-skills/email-security/SKILL.md +81 -0
- package/bundled-skills/email-security/references/email-auth-checklist.md +8 -0
- package/bundled-skills/firmware-pentest/SKILL.md +381 -0
- package/bundled-skills/firmware-pentest/references/emba-automated-analysis.md +192 -0
- package/bundled-skills/firmware-pentest/references/emulation-and-fuzz.md +337 -0
- package/bundled-skills/firmware-pentest/references/extraction-methodology.md +285 -0
- package/bundled-skills/ghidra-reverse/SKILL.md +98 -0
- package/bundled-skills/ghidra-reverse/references/ghidra-cheatsheet.md +12 -0
- package/bundled-skills/go-rust-reverse/SKILL.md +82 -0
- package/bundled-skills/go-rust-reverse/references/go-rust-notes.md +5 -0
- package/bundled-skills/hardware-security/SKILL.md +80 -0
- package/bundled-skills/hardware-security/references/debug-interface-triage.md +7 -0
- package/bundled-skills/ida-reverse/SKILL.md +401 -0
- package/bundled-skills/ida-reverse/references/LOCAL-SETUP.md +66 -0
- package/bundled-skills/ida-reverse/references/ida-mcp-cheatsheet.md +515 -0
- package/bundled-skills/identity-federation/SKILL.md +81 -0
- package/bundled-skills/identity-federation/references/sso-flow-checklist.md +9 -0
- package/bundled-skills/instructree/SKILL.md +94 -0
- package/bundled-skills/js-reverse/SKILL.md +239 -0
- package/bundled-skills/js-reverse/references/ast-deobfuscation.md +3 -0
- package/bundled-skills/js-reverse/references/automation-entry.md +12 -0
- package/bundled-skills/js-reverse/references/env-patching.md +6 -0
- package/bundled-skills/js-reverse/references/fallbacks.md +8 -0
- package/bundled-skills/js-reverse/references/instrumentation.md +9 -0
- package/bundled-skills/js-reverse/references/local-rebuild.md +11 -0
- package/bundled-skills/js-reverse/references/mcp-task-template.md +30 -0
- package/bundled-skills/js-reverse/references/node-env-rebuild.md +9 -0
- package/bundled-skills/js-reverse/references/output-contract.md +9 -0
- package/bundled-skills/js-reverse/references/task-artifacts.md +11 -0
- package/bundled-skills/js-reverse/references/task-input-template.md +11 -0
- package/bundled-skills/js-reverse/references/tool-defaults.md +7 -0
- package/bundled-skills/llm-security/SKILL.md +160 -0
- package/bundled-skills/llm-security/references/agent-obedience-engineering.md +243 -0
- package/bundled-skills/llm-security/references/agent-security-testing.md +116 -0
- package/bundled-skills/llm-security/references/owasp-llm-top10.md +48 -0
- package/bundled-skills/llm-security/references/prompt-injection-methodology.md +107 -0
- package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package-lock.json +4 -4
- package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package.json +1 -1
- package/bundled-skills/macos-reverse/SKILL.md +85 -0
- package/bundled-skills/macos-reverse/references/macho-triage.md +10 -0
- package/bundled-skills/malware-analysis/SKILL.md +311 -0
- package/bundled-skills/malware-analysis/references/anti-analysis-techniques.md +205 -0
- package/bundled-skills/malware-analysis/references/sandbox-orchestration.md +204 -0
- package/bundled-skills/malware-analysis/references/yara-sigma-rules.md +232 -0
- package/bundled-skills/mobile-reverse/SKILL.md +222 -0
- package/bundled-skills/mobile-reverse/references/anti-detection-bypass.md +182 -0
- package/bundled-skills/mobile-reverse/references/frida-objection-deep.md +218 -0
- package/bundled-skills/mobile-reverse/references/ios-reverse-guide.md +177 -0
- package/bundled-skills/muapi-media/SKILL.md +311 -0
- package/bundled-skills/ot-ics/SKILL.md +117 -0
- package/bundled-skills/ot-ics/references/ot-safe-assessment.md +10 -0
- package/bundled-skills/patch-diff-exploit/SKILL.md +278 -0
- package/bundled-skills/patch-diff-exploit/references/diff-tools-comparison.md +271 -0
- package/bundled-skills/patch-diff-exploit/references/patch-tuesday-workflow.md +253 -0
- package/bundled-skills/patch-diff-exploit/references/root-cause-and-poc.md +198 -0
- package/bundled-skills/pentest-tools/SKILL.md +346 -0
- package/bundled-skills/pentest-tools/references/ai-pentest-agents.md +148 -0
- package/bundled-skills/pentest-tools/references/ai-pentesting-landscape-2026.md +73 -0
- package/bundled-skills/pentest-tools/references/automation-loop-pattern.md +153 -0
- package/bundled-skills/pentest-tools/references/awesome-pentest-digest.md +175 -0
- package/bundled-skills/pentest-tools/references/burpsuite-mcp-guide.md +769 -0
- package/bundled-skills/pentest-tools/references/client-side-lab-playbook.md +155 -0
- package/bundled-skills/pentest-tools/references/kali-mcp-ecosystem.md +119 -0
- package/bundled-skills/pentest-tools/references/msf-protocol.md +169 -0
- package/bundled-skills/pentest-tools/references/network-attack-defense.md +350 -0
- package/bundled-skills/pentest-tools/references/nuclei-guide-2026.md +157 -0
- package/bundled-skills/pentest-tools/references/payloads.md +32 -0
- package/bundled-skills/pentest-tools/references/pentest-ai-agents-matrix.md +117 -0
- package/bundled-skills/pentest-tools/references/pentest-loop.md +270 -0
- package/bundled-skills/pentest-tools/references/recon-pipeline.md +154 -0
- package/bundled-skills/pentest-tools/references/templates/findings.md +21 -0
- package/bundled-skills/pentest-tools/references/templates/progress.md +17 -0
- package/bundled-skills/pentest-tools/references/templates/rules.md +35 -0
- package/bundled-skills/pentest-tools/references/templates/scope.md +29 -0
- package/bundled-skills/pentest-tools/references/templates/task_plan.md +27 -0
- package/bundled-skills/pentest-tools/references/web-attack-cheatsheet.md +387 -0
- package/bundled-skills/pentest-tools/src-hunter/SKILL.md +243 -0
- package/bundled-skills/pentest-tools/src-hunter/references/README.en.md +115 -0
- package/bundled-skills/pentest-tools/src-hunter/references/README.md +148 -0
- package/bundled-skills/pentest-tools/src-hunter/references/dictionaries/00-index.md +44 -0
- package/bundled-skills/pentest-tools/src-hunter/references/dictionaries/chinese-srcfingerprints.md +515 -0
- package/bundled-skills/pentest-tools/src-hunter/references/dictionaries/default-credentials-cn.md +274 -0
- package/bundled-skills/pentest-tools/src-hunter/references/industry/00-index.md +66 -0
- package/bundled-skills/pentest-tools/src-hunter/references/industry/banking-finance.md +338 -0
- package/bundled-skills/pentest-tools/src-hunter/references/industry/telecom-isp.md +315 -0
- package/bundled-skills/pentest-tools/src-hunter/references/methodology/00-index.md +68 -0
- package/bundled-skills/pentest-tools/src-hunter/references/methodology/01-attack-priority.md +143 -0
- package/bundled-skills/pentest-tools/src-hunter/references/methodology/02-bypass-toolkit.md +357 -0
- package/bundled-skills/pentest-tools/src-hunter/references/methodology/03-evidence-discipline.md +205 -0
- package/bundled-skills/pentest-tools/src-hunter/references/methodology/04-control-gap-hunting.md +238 -0
- package/bundled-skills/pentest-tools/src-hunter/references/methodology/05-srctimebox-priority.md +161 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet/adcs/346/224/273/345/207/273.md +254 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet/exchange/346/224/273/345/207/273.md +254 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet/sharepoint/346/224/273/345/207/273.md +113 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//344/277/241/346/201/257/346/224/266/351/233/206.md +947 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//345/205/215/346/235/200/344/270/216/350/247/204/351/201/277.md +780 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//345/207/255/350/257/201/347/252/203/345/217/226.md +1259 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//345/237/237/346/270/227/351/200/217/346/224/273/345/207/273.md +753 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//346/235/203/351/231/220/346/217/220/345/215/207.md +819 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//346/235/203/351/231/220/347/273/264/346/214/201.md +577 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//346/250/252/345/220/221/347/247/273/345/212/250.md +838 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/intranet//351/232/247/351/201/223/344/273/243/347/220/206.md +604 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/ai/345/256/211/345/205/250.md +698 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/api/345/256/211/345/205/250.md +1935 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/csrf/350/267/250/347/253/231/350/257/267/346/261/202/344/274/252/351/200/240.md +952 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/jwt/345/256/211/345/205/250.md +496 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/lfi-rfi/346/226/207/344/273/266/345/214/205/345/220/253.md +1365 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/rce/350/277/234/347/250/213/344/273/243/347/240/201/346/211/247/350/241/214.md +1329 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/sql-nosql/346/263/250/345/205/245.md +1924 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/ssrf/346/234/215/345/212/241/347/253/257/350/257/267/346/261/202/344/274/252/351/200/240.md +1256 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/ssti/346/250/241/346/235/277/346/263/250/345/205/245.md +1151 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/websocket/345/256/211/345/205/250.md +487 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/xss/350/267/250/347/253/231/350/204/232/346/234/254.md +1465 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web/xxe/345/256/236/344/275/223/346/263/250/345/205/245.md +815 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//344/270/232/345/212/241/351/200/273/350/276/221/346/274/217/346/264/236.md +594 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//344/272/221/345/256/211/345/205/250/346/274/217/346/264/236.md +561 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//344/276/233/345/272/224/351/223/276/346/224/273/345/207/273.md +399 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//345/216/237/345/236/213/351/223/276/346/261/241/346/237/223.md +401 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//345/274/200/346/224/276/351/207/215/345/256/232/345/220/221.md +396 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//346/226/207/344/273/266/346/274/217/346/264/236.md +0 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//346/241/206/346/236/266/346/274/217/346/264/236.md +2304 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//347/202/271/345/207/273/345/212/253/346/214/201.md +339 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//347/274/223/345/255/230/344/270/216cdn/345/256/211/345/205/250.md +497 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//350/256/244/350/257/201/346/274/217/346/264/236.md +1778 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/by-category/web//350/257/267/346/261/202/350/265/260/347/247/201.md +854 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/index.md +69 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools/web/346/270/227/351/200/217.md +662 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools/windows/346/270/227/351/200/217.md +100 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//344/277/241/346/201/257/346/224/266/351/233/206.md +852 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/206/205/347/275/221/346/270/227/351/200/217.md +873 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/207/255/350/257/201/347/252/203/345/217/226.md +186 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/237/237/346/270/227/351/200/217.md +50 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//345/257/206/347/240/201/346/224/273/345/207/273.md +462 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//346/235/203/351/231/220/346/217/220/345/215/207.md +168 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//346/274/217/346/264/236/345/210/251/347/224/250.md +445 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//347/263/273/347/273/237/345/221/275/344/273/244.md +410 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//347/272/242/351/230/237/345/267/245/345/205/267.md +64 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//347/274/226/347/240/201/350/247/243/347/240/201.md +226 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/tools//351/232/247/351/201/223/344/273/243/347/220/206.md +84 -0
- package/bundled-skills/pentest-tools/src-hunter/references/payloader/waf-bypass.md +6504 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/00-index.md +57 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/api-rest.md +2050 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/arbitrary-x-authz.md +481 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/dos.md +615 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/file-upload.md +1365 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/graphql.md +253 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/http-smuggling.md +924 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/info-disclosure.md +432 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/intranet-postexp.md +4845 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/llm-prompt-injection.md +1394 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/logic-flaws.md +1796 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/mobile.md +397 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/oauth-saml-jwt.md +2504 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/path-traversal.md +1297 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/race-conditions.md +207 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/rce.md +4829 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/sqli.md +1620 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/ssrf-cache-host.md +2098 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/unauth-access.md +330 -0
- package/bundled-skills/pentest-tools/src-hunter/references/playbooks/xss.md +1159 -0
- package/bundled-skills/pentest-tools/src-hunter/references/templates/report-submission.md +346 -0
- package/bundled-skills/pentest-tools/src-hunter/references/tools/mcp-jshook.md +174 -0
- package/bundled-skills/protocol-reverse/SKILL.md +108 -0
- package/bundled-skills/protocol-reverse/references/protocol-workflow.md +29 -0
- package/bundled-skills/pwn-chain/SKILL.md +209 -0
- package/bundled-skills/pwn-chain/references/heap-pwn.md +283 -0
- package/bundled-skills/pwn-chain/references/kernel-pwn.md +370 -0
- package/bundled-skills/pwn-chain/references/stack-pwn.md +312 -0
- package/bundled-skills/radare2/SKILL.md +460 -0
- package/bundled-skills/radare2/references/cheatsheet.md +129 -0
- package/bundled-skills/radio-sdr/SKILL.md +77 -0
- package/bundled-skills/radio-sdr/references/sdr-lab-rules.md +6 -0
- package/bundled-skills/reverse-browser-automation/SKILL.md +249 -0
- package/bundled-skills/reverse-browser-automation/references/playwright-cheatsheet.md +425 -0
- package/bundled-skills/reverse-engineering/SKILL.md +213 -0
- package/bundled-skills/reverse-engineering/dsl-vm-reverse/SKILL.md +388 -0
- package/bundled-skills/reverse-engineering/references/ai-assisted-re.md +149 -0
- package/bundled-skills/reverse-engineering/references/anti-analysis.md +836 -0
- package/bundled-skills/reverse-engineering/references/awesome-re-resources.md +135 -0
- package/bundled-skills/reverse-engineering/references/crypto-decode-tools.md +220 -0
- package/bundled-skills/reverse-engineering/references/elf-analysis.md +296 -0
- package/bundled-skills/reverse-engineering/references/field-notes.md +540 -0
- package/bundled-skills/reverse-engineering/references/go-reverse.md +240 -0
- package/bundled-skills/reverse-engineering/references/kernel-driver-reverse.md +298 -0
- package/bundled-skills/reverse-engineering/references/languages-compiled.md +587 -0
- package/bundled-skills/reverse-engineering/references/languages-platforms.md +486 -0
- package/bundled-skills/reverse-engineering/references/languages.md +499 -0
- package/bundled-skills/reverse-engineering/references/nonpe-format-cookbook.md +301 -0
- package/bundled-skills/reverse-engineering/references/ollvm-deobfuscation.md +501 -0
- package/bundled-skills/reverse-engineering/references/patterns-ctf-2.md +397 -0
- package/bundled-skills/reverse-engineering/references/patterns-ctf-3.md +719 -0
- package/bundled-skills/reverse-engineering/references/patterns-ctf.md +532 -0
- package/bundled-skills/reverse-engineering/references/patterns.md +801 -0
- package/bundled-skills/reverse-engineering/references/platforms-hardware.md +304 -0
- package/bundled-skills/reverse-engineering/references/platforms.md +442 -0
- package/bundled-skills/reverse-engineering/references/re-agent-workflow.md +240 -0
- package/bundled-skills/reverse-engineering/references/tools-advanced.md +822 -0
- package/bundled-skills/reverse-engineering/references/tools-dynamic.md +846 -0
- package/bundled-skills/reverse-engineering/references/tools.md +546 -0
- package/bundled-skills/supply-chain-security/SKILL.md +180 -0
- package/bundled-skills/supply-chain-security/references/cicd-pipeline-security.md +137 -0
- package/bundled-skills/supply-chain-security/references/sbom-sca-methodology.md +74 -0
- package/bundled-skills/thick-client/SKILL.md +104 -0
- package/bundled-skills/thick-client/references/thick-client-checklist.md +9 -0
- package/bundled-skills/threat-hunting/SKILL.md +94 -0
- package/bundled-skills/threat-hunting/references/hunting-loop.md +5 -0
- package/bundled-skills/threat-intelligence/SKILL.md +176 -0
- package/bundled-skills/threat-intelligence/references/x-public-intelligence.md +93 -0
- package/bundled-skills/tree-ring-memory/SKILL.md +29 -9
- package/bundled-skills/wifi-wireless/SKILL.md +80 -0
- package/bundled-skills/wifi-wireless/references/wireless-lab-rules.md +6 -0
- package/bundled-skills/windows-ad/SKILL.md +109 -0
- package/bundled-skills/windows-ad/references/ad-attack-paths.md +12 -0
- package/package.json +1 -1
- package/skills_index.json +1214 -2
|
@@ -0,0 +1,846 @@
|
|
|
1
|
+
# CTF Reverse - Dynamic Analysis Tools
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Frida (Dynamic Instrumentation)](#frida-dynamic-instrumentation)
|
|
5
|
+
- [Installation](#installation)
|
|
6
|
+
- [Basic Function Hooking](#basic-function-hooking)
|
|
7
|
+
- [Anti-Debug Bypass](#anti-debug-bypass)
|
|
8
|
+
- [Memory Scanning and Patching](#memory-scanning-and-patching)
|
|
9
|
+
- [Function Replacement](#function-replacement)
|
|
10
|
+
- [Tracing and Stalker](#tracing-and-stalker)
|
|
11
|
+
- [r2frida (Radare2 + Frida Integration)](#r2frida-radare2--frida-integration)
|
|
12
|
+
- [Frida for Android/iOS](#frida-for-androidios)
|
|
13
|
+
- [Frida Memoization for Recursive Function Speedup (hxp CTF 2017)](#frida-memoization-for-recursive-function-speedup-hxp-ctf-2017)
|
|
14
|
+
- [angr (Symbolic Execution)](#angr-symbolic-execution)
|
|
15
|
+
- [angr Installation](#angr-installation)
|
|
16
|
+
- [Basic Path Exploration](#basic-path-exploration)
|
|
17
|
+
- [Symbolic Input with Constraints](#symbolic-input-with-constraints)
|
|
18
|
+
- [Hook Functions to Simplify Analysis](#hook-functions-to-simplify-analysis)
|
|
19
|
+
- [Exploring from Specific Address](#exploring-from-specific-address)
|
|
20
|
+
- [Common Patterns and Tips](#common-patterns-and-tips)
|
|
21
|
+
- [Dealing with Path Explosion](#dealing-with-path-explosion)
|
|
22
|
+
- [angr CFG Recovery](#angr-cfg-recovery)
|
|
23
|
+
- [lldb (LLVM Debugger)](#lldb-llvm-debugger)
|
|
24
|
+
- [Basic Commands](#basic-commands)
|
|
25
|
+
- [Scripting (Python)](#scripting-python)
|
|
26
|
+
- [x64dbg (Windows Debugger)](#x64dbg-windows-debugger)
|
|
27
|
+
- [Key Features](#key-features)
|
|
28
|
+
- [Scripting](#scripting)
|
|
29
|
+
- [Common CTF Workflow](#common-ctf-workflow)
|
|
30
|
+
- [Qiling Framework (Cross-Platform Emulation)](#qiling-framework-cross-platform-emulation)
|
|
31
|
+
- [Qiling Installation](#qiling-installation)
|
|
32
|
+
- [Basic Usage](#basic-usage)
|
|
33
|
+
- [Anti-Debug Bypass via Emulation](#anti-debug-bypass-via-emulation)
|
|
34
|
+
- [Input Fuzzing with Qiling](#input-fuzzing-with-qiling)
|
|
35
|
+
- [Triton (Dynamic Symbolic Execution)](#triton-dynamic-symbolic-execution)
|
|
36
|
+
- [Intel Pin Instruction-Counting Side Channel (Hackover CTF 2015)](#intel-pin-instruction-counting-side-channel-hackover-ctf-2015)
|
|
37
|
+
- [Intel Pin Instruction Counting with Genetic Algorithm (hxp CTF 2017)](#intel-pin-instruction-counting-with-genetic-algorithm-hxp-ctf-2017)
|
|
38
|
+
- [Opcode-Only Trace Reconstruction (0CTF 2016)](#opcode-only-trace-reconstruction-0ctf-2016)
|
|
39
|
+
- [LD_PRELOAD time() Freeze for Deterministic Analysis (EKOPARTY 2017)](#ld_preload-time-freeze-for-deterministic-analysis-ekoparty-2017)
|
|
40
|
+
- [LD_PRELOAD memcmp Side-Channel for Byte-by-Byte Bruteforce (Blaze CTF 2018)](#ld_preload-memcmp-side-channel-for-byte-by-byte-bruteforce-blaze-ctf-2018)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Frida (Dynamic Instrumentation)
|
|
45
|
+
|
|
46
|
+
Frida injects JavaScript into running processes for real-time hooking, tracing, and modification. Essential for anti-debug bypass, runtime inspection, and mobile RE.
|
|
47
|
+
|
|
48
|
+
### Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install frida-tools frida
|
|
52
|
+
# Verify
|
|
53
|
+
frida --version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Basic Function Hooking
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// hook.js — intercept a function and log arguments/return value
|
|
60
|
+
Interceptor.attach(Module.findExportByName(null, "strcmp"), {
|
|
61
|
+
onEnter: function(args) {
|
|
62
|
+
this.arg0 = Memory.readUtf8String(args[0]);
|
|
63
|
+
this.arg1 = Memory.readUtf8String(args[1]);
|
|
64
|
+
console.log(`strcmp("${this.arg0}", "${this.arg1}")`);
|
|
65
|
+
},
|
|
66
|
+
onLeave: function(retval) {
|
|
67
|
+
console.log(` → ${retval}`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Attach to running process
|
|
74
|
+
frida -p $(pidof binary) -l hook.js
|
|
75
|
+
|
|
76
|
+
# Spawn and instrument from start
|
|
77
|
+
frida -f ./binary -l hook.js --no-pause
|
|
78
|
+
|
|
79
|
+
# One-liner: hook strcmp and dump comparisons
|
|
80
|
+
frida -f ./binary --no-pause -e '
|
|
81
|
+
Interceptor.attach(Module.findExportByName(null, "strcmp"), {
|
|
82
|
+
onEnter(args) {
|
|
83
|
+
console.log("strcmp:", Memory.readUtf8String(args[0]), Memory.readUtf8String(args[1]));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Anti-Debug Bypass
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
// Bypass ptrace(PTRACE_TRACEME) — returns 0 (success) without calling
|
|
93
|
+
Interceptor.attach(Module.findExportByName(null, "ptrace"), {
|
|
94
|
+
onEnter: function(args) {
|
|
95
|
+
this.request = args[0].toInt32();
|
|
96
|
+
},
|
|
97
|
+
onLeave: function(retval) {
|
|
98
|
+
if (this.request === 0) { // PTRACE_TRACEME
|
|
99
|
+
retval.replace(ptr(0));
|
|
100
|
+
console.log("[*] ptrace(TRACEME) bypassed");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Bypass IsDebuggerPresent (Windows)
|
|
106
|
+
var isDbg = Module.findExportByName("kernel32.dll", "IsDebuggerPresent");
|
|
107
|
+
Interceptor.attach(isDbg, {
|
|
108
|
+
onLeave: function(retval) {
|
|
109
|
+
retval.replace(ptr(0));
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Bypass timing checks — hook clock_gettime to return constant
|
|
114
|
+
Interceptor.attach(Module.findExportByName(null, "clock_gettime"), {
|
|
115
|
+
onLeave: function(retval) {
|
|
116
|
+
// Force constant timestamp to defeat timing checks
|
|
117
|
+
var ts = this.context.rsi || this.context.x1; // x86 or ARM
|
|
118
|
+
Memory.writeU64(ts, 0); // tv_sec
|
|
119
|
+
Memory.writeU64(ts.add(8), 0); // tv_nsec
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Memory Scanning and Patching
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// Scan for flag pattern in memory
|
|
128
|
+
Process.enumerateRanges('r--').forEach(function(range) {
|
|
129
|
+
Memory.scan(range.base, range.size, "66 6c 61 67 7b", { // "flag{"
|
|
130
|
+
onMatch: function(address, size) {
|
|
131
|
+
console.log("[FLAG] Found at:", address, Memory.readUtf8String(address, 64));
|
|
132
|
+
},
|
|
133
|
+
onComplete: function() {}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Patch instruction (NOP out a check)
|
|
138
|
+
var addr = Module.findBaseAddress("binary").add(0x1234);
|
|
139
|
+
Memory.patchCode(addr, 2, function(code) {
|
|
140
|
+
var writer = new X86Writer(code, { pc: addr });
|
|
141
|
+
writer.putNop();
|
|
142
|
+
writer.putNop();
|
|
143
|
+
writer.flush();
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Function Replacement
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// Replace a validation function to always return true
|
|
151
|
+
var checkFlag = Module.findExportByName(null, "check_flag");
|
|
152
|
+
Interceptor.replace(checkFlag, new NativeCallback(function(input) {
|
|
153
|
+
console.log("[*] check_flag called with:", Memory.readUtf8String(input));
|
|
154
|
+
return 1; // always valid
|
|
155
|
+
}, 'int', ['pointer']));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Tracing and Stalker
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
// Trace all calls in a function (Stalker — instruction-level tracing)
|
|
162
|
+
var targetAddr = Module.findExportByName(null, "main");
|
|
163
|
+
Stalker.follow(Process.getCurrentThreadId(), {
|
|
164
|
+
transform: function(iterator) {
|
|
165
|
+
var instruction;
|
|
166
|
+
while ((instruction = iterator.next()) !== null) {
|
|
167
|
+
if (instruction.mnemonic === "call") {
|
|
168
|
+
iterator.putCallout(function(context) {
|
|
169
|
+
console.log("CALL at", context.pc, "→", ptr(context.pc).readPointer());
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
iterator.keep();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### r2frida (Radare2 + Frida Integration)
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Attach radare2 to process via Frida
|
|
182
|
+
r2 frida://spawn/./binary
|
|
183
|
+
|
|
184
|
+
# r2frida commands
|
|
185
|
+
\ii # List imports
|
|
186
|
+
\il # List loaded modules
|
|
187
|
+
\dt strcmp # Trace strcmp calls
|
|
188
|
+
\dc # Continue execution
|
|
189
|
+
\dm # List memory maps
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Frida for Android/iOS
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Android (requires rooted device or Frida server)
|
|
196
|
+
adb push frida-server /data/local/tmp/
|
|
197
|
+
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"
|
|
198
|
+
|
|
199
|
+
# Hook Android Java methods
|
|
200
|
+
frida -U -f com.example.app -l hook_android.js --no-pause
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// hook_android.js — hook Java method
|
|
205
|
+
Java.perform(function() {
|
|
206
|
+
var MainActivity = Java.use("com.example.app.MainActivity");
|
|
207
|
+
MainActivity.checkPassword.implementation = function(input) {
|
|
208
|
+
console.log("[*] checkPassword called with:", input);
|
|
209
|
+
var result = this.checkPassword(input);
|
|
210
|
+
console.log("[*] Result:", result);
|
|
211
|
+
return result;
|
|
212
|
+
};
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Key insight:** Frida excels where static analysis fails — obfuscated code, packed binaries, and runtime-generated data. Hook comparison functions (`strcmp`, `memcmp`, custom validators) to extract expected values without reversing the algorithm. Use `Interceptor.attach` for observation, `Interceptor.replace` for modification.
|
|
217
|
+
|
|
218
|
+
**When to use:** Anti-debugging bypass, extracting runtime-computed keys, hooking crypto functions to dump plaintext, mobile app analysis, packed binary inspection.
|
|
219
|
+
|
|
220
|
+
### Frida Memoization for Recursive Function Speedup (hxp CTF 2017)
|
|
221
|
+
|
|
222
|
+
Hook a recursive function with Frida, memoize results, and replay cached values to skip redundant computation. Fibonacci-like recursive challenges with exponential complexity become instant with memoization.
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
// memo_hook.js — memoize a recursive function to skip redundant calls
|
|
226
|
+
var memo = {};
|
|
227
|
+
var funcAddr = ptr("0x400abc"); // Address of the recursive function
|
|
228
|
+
var retAddr = ptr("0x400def"); // Address of the function's ret instruction
|
|
229
|
+
|
|
230
|
+
Interceptor.attach(funcAddr, {
|
|
231
|
+
onEnter: function(args) {
|
|
232
|
+
this.key = args[0].toInt32();
|
|
233
|
+
if (memo[this.key] !== undefined) {
|
|
234
|
+
// Skip computation entirely: set return value and jump to ret
|
|
235
|
+
this.context.rax = memo[this.key];
|
|
236
|
+
this.context.rip = retAddr;
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
onLeave: function(retval) {
|
|
240
|
+
// Cache the result for future calls with the same argument
|
|
241
|
+
memo[this.key] = retval.toInt32();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Usage
|
|
248
|
+
frida -f ./binary -l memo_hook.js --no-pause
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
For multi-argument functions, build a composite key:
|
|
252
|
+
```javascript
|
|
253
|
+
Interceptor.attach(funcAddr, {
|
|
254
|
+
onEnter: function(args) {
|
|
255
|
+
this.key = args[0].toInt32() + "," + args[1].toInt32();
|
|
256
|
+
if (memo[this.key] !== undefined) {
|
|
257
|
+
this.context.rax = memo[this.key];
|
|
258
|
+
this.context.rip = retAddr;
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
onLeave: function(retval) {
|
|
262
|
+
memo[this.key] = retval.toInt32();
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Key insight:** Frida's `Interceptor` can both read and modify register state, allowing you to skip function execution entirely by setting `rax` (return value) and `rip` (to the `ret` instruction). This works on any recursive function where the same arguments produce the same result. Exponential-time recursive computations (Fibonacci, Ackermann, tree traversals) become linear with memoization.
|
|
268
|
+
|
|
269
|
+
**References:** hxp CTF 2017
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## angr (Symbolic Execution)
|
|
274
|
+
|
|
275
|
+
angr automatically explores program paths to find inputs satisfying constraints. Solves many flag-checking binaries in minutes that take hours manually.
|
|
276
|
+
|
|
277
|
+
### angr Installation
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
pip install angr
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Basic Path Exploration
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
import angr
|
|
287
|
+
import claripy
|
|
288
|
+
|
|
289
|
+
# Load binary
|
|
290
|
+
proj = angr.Project('./binary', auto_load_libs=False)
|
|
291
|
+
|
|
292
|
+
# Find address of "Correct!" print, avoid "Wrong!" print
|
|
293
|
+
# Get these from disassembly (objdump -d or Ghidra)
|
|
294
|
+
FIND_ADDR = 0x401234 # Address of success path
|
|
295
|
+
AVOID_ADDR = 0x401256 # Address of failure path
|
|
296
|
+
|
|
297
|
+
# Create simulation manager and explore
|
|
298
|
+
simgr = proj.factory.simgr()
|
|
299
|
+
simgr.explore(find=FIND_ADDR, avoid=AVOID_ADDR)
|
|
300
|
+
|
|
301
|
+
if simgr.found:
|
|
302
|
+
found = simgr.found[0]
|
|
303
|
+
# Get stdin that reaches the target
|
|
304
|
+
print("Flag:", found.posix.dumps(0)) # fd 0 = stdin
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Symbolic Input with Constraints
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
import angr
|
|
311
|
+
import claripy
|
|
312
|
+
|
|
313
|
+
proj = angr.Project('./binary', auto_load_libs=False)
|
|
314
|
+
|
|
315
|
+
# Create symbolic input (e.g., 32-byte flag)
|
|
316
|
+
flag_len = 32
|
|
317
|
+
flag_chars = [claripy.BVS(f'flag_{i}', 8) for i in range(flag_len)]
|
|
318
|
+
flag = claripy.Concat(*flag_chars + [claripy.BVV(b'\n')])
|
|
319
|
+
|
|
320
|
+
# Constrain to printable ASCII
|
|
321
|
+
state = proj.factory.entry_state(stdin=flag)
|
|
322
|
+
for c in flag_chars:
|
|
323
|
+
state.solver.add(c >= 0x20)
|
|
324
|
+
state.solver.add(c <= 0x7e)
|
|
325
|
+
|
|
326
|
+
# Constrain known prefix: "flag{"
|
|
327
|
+
state.solver.add(flag_chars[0] == ord('f'))
|
|
328
|
+
state.solver.add(flag_chars[1] == ord('l'))
|
|
329
|
+
state.solver.add(flag_chars[2] == ord('a'))
|
|
330
|
+
state.solver.add(flag_chars[3] == ord('g'))
|
|
331
|
+
state.solver.add(flag_chars[4] == ord('{'))
|
|
332
|
+
state.solver.add(flag_chars[flag_len-1] == ord('}'))
|
|
333
|
+
|
|
334
|
+
simgr = proj.factory.simgr(state)
|
|
335
|
+
simgr.explore(find=0x401234, avoid=0x401256)
|
|
336
|
+
|
|
337
|
+
if simgr.found:
|
|
338
|
+
found = simgr.found[0]
|
|
339
|
+
result = found.solver.eval(flag, cast_to=bytes)
|
|
340
|
+
print("Flag:", result.decode())
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Hook Functions to Simplify Analysis
|
|
344
|
+
|
|
345
|
+
```python
|
|
346
|
+
import angr
|
|
347
|
+
|
|
348
|
+
proj = angr.Project('./binary', auto_load_libs=False)
|
|
349
|
+
|
|
350
|
+
# Hook printf to avoid path explosion in I/O
|
|
351
|
+
@proj.hook(0x401100, length=5) # Address of call to printf
|
|
352
|
+
def skip_printf(state):
|
|
353
|
+
pass # Do nothing, just skip
|
|
354
|
+
|
|
355
|
+
# Hook sleep/anti-debug functions
|
|
356
|
+
@proj.hook(0x401050, length=5) # Address of call to sleep
|
|
357
|
+
def skip_sleep(state):
|
|
358
|
+
pass
|
|
359
|
+
|
|
360
|
+
# Replace a function with a summary
|
|
361
|
+
class AlwaysSucceed(angr.SimProcedure):
|
|
362
|
+
def run(self):
|
|
363
|
+
return 1
|
|
364
|
+
|
|
365
|
+
proj.hook_symbol('check_license', AlwaysSucceed())
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Exploring from Specific Address
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
# Start from middle of function (skip initialization)
|
|
372
|
+
state = proj.factory.blank_state(addr=0x401200)
|
|
373
|
+
|
|
374
|
+
# Set up registers/memory manually
|
|
375
|
+
state.regs.rdi = 0x600000 # Pointer to input buffer
|
|
376
|
+
state.memory.store(0x600000, b"AAAA" + b"\x00" * 28)
|
|
377
|
+
|
|
378
|
+
simgr = proj.factory.simgr(state)
|
|
379
|
+
simgr.explore(find=0x401300, avoid=0x401350)
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Common Patterns and Tips
|
|
383
|
+
|
|
384
|
+
```python
|
|
385
|
+
# Pattern 1: argv-based input
|
|
386
|
+
state = proj.factory.entry_state(args=['./binary', flag_sym])
|
|
387
|
+
|
|
388
|
+
# Pattern 2: Multiple find/avoid addresses
|
|
389
|
+
simgr.explore(
|
|
390
|
+
find=[0x401234, 0x401300], # Any success path
|
|
391
|
+
avoid=[0x401256, 0x401400] # All failure paths
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
# Pattern 3: Find by output string (no address needed)
|
|
395
|
+
def is_successful(state):
|
|
396
|
+
stdout = state.posix.dumps(1) # fd 1 = stdout
|
|
397
|
+
return b"Correct" in stdout
|
|
398
|
+
|
|
399
|
+
def should_avoid(state):
|
|
400
|
+
stdout = state.posix.dumps(1)
|
|
401
|
+
return b"Wrong" in stdout
|
|
402
|
+
|
|
403
|
+
simgr.explore(find=is_successful, avoid=should_avoid)
|
|
404
|
+
|
|
405
|
+
# Pattern 4: Timeout protection
|
|
406
|
+
simgr.explore(find=0x401234, avoid=0x401256, num_find=1)
|
|
407
|
+
# Or use exploration techniques:
|
|
408
|
+
simgr.use_technique(angr.exploration_techniques.DFS()) # Depth-first
|
|
409
|
+
simgr.use_technique(angr.exploration_techniques.LengthLimiter(max_length=500))
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Dealing with Path Explosion
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
# Use DFS instead of BFS (default) for flag checkers
|
|
416
|
+
simgr.use_technique(angr.exploration_techniques.DFS())
|
|
417
|
+
|
|
418
|
+
# Limit symbolic memory operations
|
|
419
|
+
state.options.add(angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY)
|
|
420
|
+
state.options.add(angr.options.ZERO_FILL_UNCONSTRAINED_REGISTERS)
|
|
421
|
+
|
|
422
|
+
# Hook expensive functions (crypto, hashing) to avoid explosion
|
|
423
|
+
import hashlib
|
|
424
|
+
class SHA256Hook(angr.SimProcedure):
|
|
425
|
+
def run(self, data, length, output):
|
|
426
|
+
# Concretize input and compute hash
|
|
427
|
+
concrete_data = self.state.solver.eval(
|
|
428
|
+
self.state.memory.load(data, self.state.solver.eval(length)),
|
|
429
|
+
cast_to=bytes
|
|
430
|
+
)
|
|
431
|
+
h = hashlib.sha256(concrete_data).digest()
|
|
432
|
+
self.state.memory.store(output, h)
|
|
433
|
+
|
|
434
|
+
proj.hook_symbol('SHA256', SHA256Hook())
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### angr CFG Recovery
|
|
438
|
+
|
|
439
|
+
```python
|
|
440
|
+
# Control flow graph for understanding structure
|
|
441
|
+
cfg = proj.analyses.CFGFast()
|
|
442
|
+
print(f"Functions found: {len(cfg.functions)}")
|
|
443
|
+
|
|
444
|
+
# Find main
|
|
445
|
+
for addr, func in cfg.functions.items():
|
|
446
|
+
if func.name == 'main':
|
|
447
|
+
print(f"main at {addr:#x}")
|
|
448
|
+
break
|
|
449
|
+
|
|
450
|
+
# Cross-references
|
|
451
|
+
node = cfg.model.get_any_node(0x401234)
|
|
452
|
+
print("Predecessors:", [hex(p.addr) for p in cfg.model.get_predecessors(node)])
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
**Key insight:** angr works best on flag-checker binaries with clear success/failure paths. For complex binaries, hook expensive functions (crypto, I/O) and use DFS exploration. Start with the simplest approach (just find/avoid addresses) before adding constraints. If angr is slow, constrain input to printable ASCII and add known prefix.
|
|
456
|
+
|
|
457
|
+
**When to use:** Flag validators with branching logic, maze/path-finding binaries, constraint-heavy checks, automated binary analysis. Less effective for: heavy crypto, floating-point math, complex heap operations.
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## lldb (LLVM Debugger)
|
|
462
|
+
|
|
463
|
+
Primary debugger for macOS/iOS. Also works on Linux. Preferred for Swift/Objective-C and Apple platform binaries.
|
|
464
|
+
|
|
465
|
+
### Basic Commands
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
lldb ./binary
|
|
469
|
+
(lldb) run # Run program
|
|
470
|
+
(lldb) b main # Breakpoint on main
|
|
471
|
+
(lldb) b 0x401234 # Breakpoint at address
|
|
472
|
+
(lldb) breakpoint set -r "check.*" # Regex breakpoint
|
|
473
|
+
(lldb) c # Continue
|
|
474
|
+
(lldb) si # Step instruction
|
|
475
|
+
(lldb) ni # Next instruction
|
|
476
|
+
(lldb) register read # Show all registers
|
|
477
|
+
(lldb) register write rax 0 # Modify register
|
|
478
|
+
(lldb) memory read 0x401000 -c 32 # Read 32 bytes
|
|
479
|
+
(lldb) x/s $rsi # Examine string (GDB-style)
|
|
480
|
+
(lldb) dis -n main # Disassemble function
|
|
481
|
+
(lldb) image list # Loaded modules + base addresses
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Scripting (Python)
|
|
485
|
+
|
|
486
|
+
```python
|
|
487
|
+
# lldb Python scripting
|
|
488
|
+
import lldb
|
|
489
|
+
|
|
490
|
+
def hook_strcmp(debugger, command, result, internal_dict):
|
|
491
|
+
target = debugger.GetSelectedTarget()
|
|
492
|
+
process = target.GetProcess()
|
|
493
|
+
thread = process.GetSelectedThread()
|
|
494
|
+
frame = thread.GetSelectedFrame()
|
|
495
|
+
arg0 = frame.FindRegister("rdi").GetValueAsUnsigned()
|
|
496
|
+
arg1 = frame.FindRegister("rsi").GetValueAsUnsigned()
|
|
497
|
+
s0 = process.ReadCStringFromMemory(arg0, 256, lldb.SBError())
|
|
498
|
+
s1 = process.ReadCStringFromMemory(arg1, 256, lldb.SBError())
|
|
499
|
+
print(f'strcmp("{s0}", "{s1}")')
|
|
500
|
+
|
|
501
|
+
# Register in lldb: command script add -f script.hook_strcmp hook_strcmp
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**Key insight:** Use lldb for macOS binaries (Mach-O), iOS apps, and when GDB isn't available. `image list` gives ASLR slide for PIE binaries. Scripting API is more structured than GDB's.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## x64dbg (Windows Debugger)
|
|
509
|
+
|
|
510
|
+
Open-source Windows debugger with modern UI. Alternative to OllyDbg/WinDbg for Windows RE challenges.
|
|
511
|
+
|
|
512
|
+
### Key Features
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
# Launch
|
|
516
|
+
x64dbg.exe binary.exe # 64-bit
|
|
517
|
+
x32dbg.exe binary.exe # 32-bit
|
|
518
|
+
|
|
519
|
+
# Essential shortcuts
|
|
520
|
+
F2 → Toggle breakpoint
|
|
521
|
+
F7 → Step into
|
|
522
|
+
F8 → Step over
|
|
523
|
+
F9 → Run
|
|
524
|
+
Ctrl+G → Go to address
|
|
525
|
+
Ctrl+F → Find pattern in memory
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Scripting
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
# x64dbg command line
|
|
532
|
+
bp 0x401234 # Breakpoint
|
|
533
|
+
SetBPX 0x401234, 0, "log {s:utf8@[esp+4]}" # Log string arg on hit
|
|
534
|
+
run # Continue
|
|
535
|
+
StepOver # Step over
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Common CTF Workflow
|
|
539
|
+
|
|
540
|
+
1. Set breakpoint on `GetWindowTextA`/`MessageBoxA` for GUI crackers
|
|
541
|
+
2. Trace back from success/failure message
|
|
542
|
+
3. Use **Scylla** plugin for IAT reconstruction on packed binaries
|
|
543
|
+
4. **Snowman** decompiler plugin for quick pseudo-C
|
|
544
|
+
|
|
545
|
+
**Key insight:** x64dbg has built-in pattern scanning, hardware breakpoints, and conditional logging. For Windows CTF binaries, it's often faster than IDA/Ghidra for dynamic analysis. Use the **xAnalyzer** plugin for automatic function argument annotation.
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## Qiling Framework (Cross-Platform Emulation)
|
|
550
|
+
|
|
551
|
+
Qiling emulates binaries with OS-level support (syscalls, filesystem, registry). Built on Unicorn but adds the OS layer that Unicorn lacks.
|
|
552
|
+
|
|
553
|
+
### Qiling Installation
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
pip install qiling
|
|
557
|
+
# Download rootfs for target OS:
|
|
558
|
+
git clone https://github.com/qilingframework/rootfs
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Basic Usage
|
|
562
|
+
|
|
563
|
+
```python
|
|
564
|
+
from qiling import Qiling
|
|
565
|
+
from qiling.const import QL_VERBOSE
|
|
566
|
+
|
|
567
|
+
# Linux ELF emulation
|
|
568
|
+
ql = Qiling(["./binary", "arg1"], "rootfs/x8664_linux",
|
|
569
|
+
verbose=QL_VERBOSE.DEFAULT)
|
|
570
|
+
ql.run()
|
|
571
|
+
|
|
572
|
+
# Windows PE emulation (no Windows needed!)
|
|
573
|
+
ql = Qiling(["rootfs/x86_windows/bin/binary.exe"], "rootfs/x86_windows")
|
|
574
|
+
ql.run()
|
|
575
|
+
|
|
576
|
+
# ARM/MIPS emulation (IoT firmware)
|
|
577
|
+
ql = Qiling(["rootfs/arm_linux/bin/binary"], "rootfs/arm_linux")
|
|
578
|
+
ql.run()
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Anti-Debug Bypass via Emulation
|
|
582
|
+
|
|
583
|
+
```python
|
|
584
|
+
from qiling import Qiling
|
|
585
|
+
|
|
586
|
+
ql = Qiling(["./binary"], "rootfs/x8664_linux")
|
|
587
|
+
|
|
588
|
+
# Hook ptrace syscall — return 0 (success)
|
|
589
|
+
def hook_ptrace(ql, ptrace_request, pid, addr, data):
|
|
590
|
+
ql.log.info("ptrace bypassed")
|
|
591
|
+
return 0
|
|
592
|
+
|
|
593
|
+
ql.os.set_syscall("ptrace", hook_ptrace)
|
|
594
|
+
|
|
595
|
+
# Hook specific address (e.g., anti-VM check)
|
|
596
|
+
def skip_check(ql):
|
|
597
|
+
ql.arch.regs.rax = 0 # Force success
|
|
598
|
+
ql.log.info(f"Skipped check at {ql.arch.regs.rip:#x}")
|
|
599
|
+
|
|
600
|
+
ql.hook_address(skip_check, 0x401234)
|
|
601
|
+
|
|
602
|
+
ql.run()
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Input Fuzzing with Qiling
|
|
606
|
+
|
|
607
|
+
```python
|
|
608
|
+
# Emulate binary with different inputs to find flag
|
|
609
|
+
import string
|
|
610
|
+
from qiling import Qiling
|
|
611
|
+
|
|
612
|
+
def test_input(candidate):
|
|
613
|
+
ql = Qiling(["./binary"], "rootfs/x8664_linux",
|
|
614
|
+
verbose=QL_VERBOSE.DISABLED, stdin=candidate.encode())
|
|
615
|
+
ql.run()
|
|
616
|
+
return ql.os.stdout.read()
|
|
617
|
+
|
|
618
|
+
for ch in string.printable:
|
|
619
|
+
output = test_input("flag{" + ch)
|
|
620
|
+
if b"Correct" in output:
|
|
621
|
+
print(f"Found: {ch}")
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
**Advantages over GDB/Frida:**
|
|
625
|
+
- No debugger artifacts (bypasses all anti-debug by default)
|
|
626
|
+
- Cross-platform without hardware (ARM, MIPS, RISC-V on x86 host)
|
|
627
|
+
- Scriptable with Python (faster iteration than GDB)
|
|
628
|
+
- Snapshot/restore for brute-forcing
|
|
629
|
+
|
|
630
|
+
**Key insight:** Qiling emulates the entire OS layer (syscalls, filesystem, registry), not just the CPU. This means anti-debug checks like `ptrace(TRACEME)` naturally return success without patching, and you can analyze ARM/MIPS binaries on an x86 host without QEMU or real hardware.
|
|
631
|
+
|
|
632
|
+
**When to use:** Foreign architecture binaries, IoT firmware, heavy anti-debug, automated testing of many inputs.
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
## Triton (Dynamic Symbolic Execution)
|
|
637
|
+
|
|
638
|
+
See [tools-advanced.md](tools-advanced.md#triton-dynamic-symbolic-execution) for full Triton reference. Quick usage:
|
|
639
|
+
|
|
640
|
+
```python
|
|
641
|
+
from triton import *
|
|
642
|
+
|
|
643
|
+
ctx = TritonContext(ARCH.X86_64)
|
|
644
|
+
|
|
645
|
+
# Symbolize input buffer
|
|
646
|
+
for i in range(32):
|
|
647
|
+
ctx.symbolizeMemory(MemoryAccess(0x600000 + i, CPUSIZE.BYTE), f"flag_{i}")
|
|
648
|
+
|
|
649
|
+
# Process instructions and collect constraints
|
|
650
|
+
# At comparison point, solve for flag
|
|
651
|
+
model = ctx.getModel(ctx.getPathConstraintsAst())
|
|
652
|
+
flag = ''.join(chr(v.getValue()) for _, v in sorted(model.items()))
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
**Key insight:** Triton excels at single-path DSE (Dynamic Symbolic Execution) where angr's path explosion is a problem. Feed it a concrete execution trace, symbolize specific inputs, and solve for constraints at comparison points. Faster than angr for linear code paths with known execution flow.
|
|
656
|
+
|
|
657
|
+
**Best for:** Single-path symbolic execution, deobfuscation, taint analysis. Faster than angr for linear code paths.
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Intel Pin Instruction-Counting Side Channel (Hackover CTF 2015)
|
|
662
|
+
|
|
663
|
+
**Pattern:** Brute-force input character-by-character against a binary using Intel Pin's `inscount0` tool. Each correct character causes deeper execution (more instructions) in the comparison logic.
|
|
664
|
+
|
|
665
|
+
```python
|
|
666
|
+
import string
|
|
667
|
+
from subprocess import Popen, PIPE
|
|
668
|
+
|
|
669
|
+
pin = './pin'
|
|
670
|
+
tool = './source/tools/ManualExamples/obj-ia32/inscount0.so'
|
|
671
|
+
binary = './target'
|
|
672
|
+
|
|
673
|
+
key = ''
|
|
674
|
+
while True:
|
|
675
|
+
best_count, best_char = 0, ''
|
|
676
|
+
for c in string.printable:
|
|
677
|
+
cmd = [pin, '-injection', 'child', '-t', tool, '--', binary]
|
|
678
|
+
p = Popen(cmd, stdout=PIPE, stdin=PIPE, stderr=PIPE)
|
|
679
|
+
p.communicate((key + c + '\n').encode())
|
|
680
|
+
with open('inscount.out') as f:
|
|
681
|
+
count = int(f.read().split()[-1])
|
|
682
|
+
if count > best_count:
|
|
683
|
+
best_count, best_char = count, c
|
|
684
|
+
key += best_char
|
|
685
|
+
print(f"Found: {key}")
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
**Key insight:** Movfuscated binaries (compiled with `movfuscator`) expand every instruction into sequences of `mov` operations, making static analysis impractical. However, character-by-character comparison still creates measurable instruction count differences. Pin's `inscount0.so` counts total executed instructions — the correct character at each position causes ~1000+ more instructions (proceeding further in the comparison). Also works for obfuscated binaries with sequential input checks.
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
### Intel Pin Instruction Counting with Genetic Algorithm (hxp CTF 2017)
|
|
693
|
+
|
|
694
|
+
For self-modifying code that decrypts the next chunk only after each character check passes, standard character-by-character Pin counting fails because the search space is too large and characters may interact. Use a genetic algorithm instead to explore the input space more efficiently.
|
|
695
|
+
|
|
696
|
+
```python
|
|
697
|
+
import subprocess
|
|
698
|
+
import random
|
|
699
|
+
import string
|
|
700
|
+
|
|
701
|
+
PIN_PATH = '/tmp/pin-3.5/pin'
|
|
702
|
+
TOOL_PATH = 'source/tools/ManualExamples/obj-intel64/inscount0.so'
|
|
703
|
+
|
|
704
|
+
def fitness(candidate):
|
|
705
|
+
"""Run binary under Pin and return instruction count as fitness."""
|
|
706
|
+
proc = subprocess.Popen(
|
|
707
|
+
[PIN_PATH, '-t', TOOL_PATH, '--', './binary'],
|
|
708
|
+
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
709
|
+
stdout, stderr = proc.communicate(candidate.encode())
|
|
710
|
+
# inscount0 writes count to stderr or inscount.out
|
|
711
|
+
try:
|
|
712
|
+
with open('inscount.out') as f:
|
|
713
|
+
return int(f.read().split()[-1])
|
|
714
|
+
except:
|
|
715
|
+
return 0
|
|
716
|
+
|
|
717
|
+
def mutate(individual, rate=0.1):
|
|
718
|
+
"""Randomly mutate characters in the individual."""
|
|
719
|
+
result = list(individual)
|
|
720
|
+
for i in range(len(result)):
|
|
721
|
+
if random.random() < rate:
|
|
722
|
+
result[i] = random.choice(string.printable[:62])
|
|
723
|
+
return result
|
|
724
|
+
|
|
725
|
+
# Genetic algorithm parameters
|
|
726
|
+
FLAG_LEN = 40
|
|
727
|
+
POP_SIZE = 100
|
|
728
|
+
SURVIVORS = 20
|
|
729
|
+
|
|
730
|
+
# Initialize random population
|
|
731
|
+
population = [random.choices(string.printable[:62], k=FLAG_LEN) for _ in range(POP_SIZE)]
|
|
732
|
+
|
|
733
|
+
for generation in range(10000):
|
|
734
|
+
# Score each individual by instruction count
|
|
735
|
+
scored = [(fitness(''.join(p)), p) for p in population]
|
|
736
|
+
scored.sort(reverse=True)
|
|
737
|
+
best_score, best_individual = scored[0]
|
|
738
|
+
print(f"Gen {generation}: {best_score} {''.join(best_individual)}")
|
|
739
|
+
|
|
740
|
+
# Keep top survivors, mutate to refill population
|
|
741
|
+
survivors = [s[1] for s in scored[:SURVIVORS]]
|
|
742
|
+
population = survivors + [mutate(random.choice(survivors)) for _ in range(POP_SIZE - SURVIVORS)]
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
**Modified Pin for Go binaries (table-lookup flag checking):**
|
|
746
|
+
When standard `inscount` fails because counter increments don't correlate with correctness (e.g., table-lookup comparison), modify Pin's icount tool to only count executions at the success-branch address. Brute-force character-by-character with this targeted counter:
|
|
747
|
+
```cpp
|
|
748
|
+
// Modified inscount0.cpp — count only executions of a specific address
|
|
749
|
+
static ADDRINT target_addr = 0x401234; // success-branch address
|
|
750
|
+
static UINT64 target_count = 0;
|
|
751
|
+
|
|
752
|
+
VOID CountAtTarget(ADDRINT ip) {
|
|
753
|
+
if (ip == target_addr) target_count++;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
VOID Instruction(INS ins, VOID *v) {
|
|
757
|
+
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)CountAtTarget,
|
|
758
|
+
IARG_INST_PTR, IARG_END);
|
|
759
|
+
}
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
**Key insight:** When each correct character unlocks a new code section (self-modifying or multi-stage decryption), instruction count increases monotonically with correctness. A genetic algorithm explores the input space more efficiently than character-by-character brute-force because it can discover multiple correct characters simultaneously. Converges in approximately 30 minutes for 40-character flags. For table-lookup comparisons where total instruction count doesn't correlate, target a specific branch address instead.
|
|
763
|
+
|
|
764
|
+
**References:** hxp CTF 2017
|
|
765
|
+
|
|
766
|
+
---
|
|
767
|
+
|
|
768
|
+
## Opcode-Only Trace Reconstruction (0CTF 2016)
|
|
769
|
+
|
|
770
|
+
Given an execution trace with only opcodes (no register/memory values), reconstruct the program: sort/dedup trace by address, split into basic blocks, annotate functions. Sorting algorithms are particularly vulnerable -- branch decisions leak element ordering.
|
|
771
|
+
|
|
772
|
+
**Approach:**
|
|
773
|
+
1. Sort trace entries by address, deduplicate to recover code layout
|
|
774
|
+
2. Identify basic block boundaries (jumps, calls, returns)
|
|
775
|
+
3. Map branch taken/not-taken decisions from trace order
|
|
776
|
+
4. For sorting algorithms, partition comparisons reveal relative ordering of all input elements
|
|
777
|
+
|
|
778
|
+
**Key insight:** Execution traces without data values still leak information through branch decisions. Quicksort partition comparisons reveal which element is greater/lesser at each step, enabling full recovery of the sorted input from branch direction alone.
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
|
|
782
|
+
## LD_PRELOAD time() Freeze for Deterministic Analysis (EKOPARTY 2017)
|
|
783
|
+
|
|
784
|
+
Override `time()` via LD_PRELOAD to return a constant value, freezing any timestamp-seeded PRNG. Once the binary's cipher becomes deterministic, brute-force each output byte without understanding the VM or cipher internals.
|
|
785
|
+
|
|
786
|
+
```c
|
|
787
|
+
// freeze_time.c — compile: gcc -shared -fPIC -o freeze.so freeze_time.c
|
|
788
|
+
#include <time.h>
|
|
789
|
+
|
|
790
|
+
time_t time(time_t *t) {
|
|
791
|
+
if (t) *t = 1234567890;
|
|
792
|
+
return 1234567890;
|
|
793
|
+
}
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
# Build and use:
|
|
798
|
+
gcc -shared -fPIC -o freeze.so freeze_time.c
|
|
799
|
+
LD_PRELOAD=./freeze.so ./binary
|
|
800
|
+
|
|
801
|
+
# Byte-at-a-time oracle: run with frozen time, try each candidate byte,
|
|
802
|
+
# observe output — correct byte produces expected output character.
|
|
803
|
+
for byte in $(seq 0 255); do
|
|
804
|
+
output=$(echo -n "$(printf '\x%02x' $byte)" | LD_PRELOAD=./freeze.so ./binary)
|
|
805
|
+
# Check output against known/expected
|
|
806
|
+
done
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
If `srand()` or `rand()` is also involved, override `rand()` too:
|
|
810
|
+
```c
|
|
811
|
+
int rand(void) { return 42; }
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
**Key insight:** LD_PRELOAD function interception freezes non-determinism sources (time, rand). Once deterministic, even complex VMs become tractable byte-at-a-time oracles.
|
|
815
|
+
|
|
816
|
+
**References:** EKOPARTY CTF 2017
|
|
817
|
+
|
|
818
|
+
---
|
|
819
|
+
|
|
820
|
+
### LD_PRELOAD memcmp Side-Channel for Byte-by-Byte Bruteforce (Blaze CTF 2018)
|
|
821
|
+
|
|
822
|
+
**Pattern:** Replace `memcmp` with an LD_PRELOAD library that returns the number of matching bytes instead of the standard -1/0/1 result. This converts any memcmp-based validation into a byte-by-byte oracle. Automate with GDB Python scripting to bruteforce each character position.
|
|
823
|
+
|
|
824
|
+
```c
|
|
825
|
+
// memcmp_hook.c - compile: gcc -shared -fPIC -o hook.so memcmp_hook.c
|
|
826
|
+
int memcmp(const char *s1, const char *s2, int n) {
|
|
827
|
+
int cnt = 0;
|
|
828
|
+
for (int i = 0; i < n; ++i) {
|
|
829
|
+
if (s1[i] == s2[i]) cnt++;
|
|
830
|
+
else break;
|
|
831
|
+
}
|
|
832
|
+
return cnt;
|
|
833
|
+
}
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
```bash
|
|
837
|
+
# Use with GDB: LD_PRELOAD=./hook.so gdb ./binary
|
|
838
|
+
# Set breakpoint after memcmp, read return value to count matching bytes
|
|
839
|
+
# Iterate characters at each position to find the one that increases count
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
**Key insight:** Replacing memcmp via LD_PRELOAD to return match count converts any comparison-based validation into a byte-by-byte oracle. Combined with GDB scripting, this automates bruteforce of password/flag checks without reversing the validation algorithm.
|
|
843
|
+
|
|
844
|
+
**Detection:** Binary uses `memcmp` or `strcmp` for flag validation (visible in `ltrace` output or import table). The comparison function is called with user input and a computed/stored expected value.
|
|
845
|
+
|
|
846
|
+
**References:** Blaze CTF 2018
|