YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

pentest-llm

Domain-Specific Language Model for Penetration Testing Automation

Fine-tuned Qwen3-8B for offensive security: privilege escalation, web vulnerabilities, post-exploitation, and CTF challenges.

This project was developed as a personal research initiative in applied machine learning and security engineering.


Abstract

This work presents pentest-llm, a domain-specific fine-tuned large language model designed to assist penetration testers by generating actionable exploit commands from natural-language scenario descriptions. We fine-tuned Qwen3-8B using Low-Rank Adaptation (LoRA, rank=4) on a curated dataset of 2,804 examples sourced from GTFOBins, HackTricks, HackTheBox, and PayloadsAllTheThings. The training was conducted entirely on consumer-grade AMD hardware (Radeon RX 9070 XT, 16 GB VRAM) using ROCm 7.2.1, achieving full convergence in under 20 minutes. Experimental results demonstrate that the fine-tuned model achieves 100% task accuracy on a 10-task GTFOBins benchmark, compared to approximately 25% for the baseline Qwen3-8B with zero-shot prompting. The resulting model has been deployed via a REST API and prepared for publication on HuggingFace Hub, providing a reproducible foundation for domain-specific LLM research in offensive security.

Overview

Modern large language models (LLMs) are powerful generalists but often lack depth in narrow technical domains. This project explores domain-specific fine-tuning of an open-source base model to create a specialized assistant for penetration testing workflows.

The model is trained to take a scenario description (e.g., a SUID binary found during enumeration) and produce an actionable exploit command β€” matching the format and precision expected in real security assessments.


Technical Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  pentest-llm pipeline               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                     β”‚
β”‚  [Data Collection]  β†’  [SFT Training]  β†’  [Deploy]  β”‚
β”‚                                                     β”‚
β”‚  β€’ gtfobins.org        β€’ Qwen3-8B          β€’ Flask  β”‚
β”‚  β€’ HackTricks          β€’ LoRA r=4          β€’ Ollama β”‚
β”‚  β€’ HTB / CTF           β€’ ROCm AMD           ready  β”‚
β”‚  β€’ PayloadsAllThings   β€’ 2 epochs bf16            β”‚
β”‚                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Base model: Qwen/Qwen3-8B (8B parameters, Apache 2.0)

Training stack: Python 3.12 Β· transformers Β· peft Β· trl Β· ROCm

Hardware: AMD Radeon RX 9070 XT (16 GB VRAM, ROCm 7.2.1)


Dataset

Source Records Content
GTFOBins 1,625 SUID abuse (vim, find, tar, awk, nmap...)
HackTricks ~500 Privilege escalation, lateral movement
HackTheBox / CTF ~400 Real-world attack scenarios
PayloadsAllTheThings ~280 SQLi, XSS, command injection
Total 2,804 SFT examples

Each record follows the instruction-tuning format:

{
  "instruction": "Как ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ root Ρ‡Π΅Ρ€Π΅Π· vim SUID?",
  "input": "Linux, vim root-owned SUID binary found",
  "output": "vim -c ':!/bin/sh'"
}

Training Details

Parameter Value
Base model Qwen3-8B (bf16)
Quantization 4-bit NF4 (BitsAndBytes)
LoRA rank 4 (q_proj, k_proj, v_proj, o_proj)
LoRA alpha 8
Effective batch size 8 (1 Γ— gradient accumulation 8)
Learning rate 2e-4 with 10-step warmup
Epochs 2
Precision fp16
Total steps ~700
Training time ~10–20 min (RX 9070 XT)
Token accuracy (epoch 2) ~64%

After training, the LoRA adapter is merged into the base weights to produce a single self-contained model file.


Benchmark Results

Evaluated on 10 held-out penetration testing tasks:

Task Input Baseline Qwen3-8B Fine-tuned Status
SUID vim Linux, vim SUID Permission denied / no command vim -c ':!/bin/sh' βœ“
SUID find Linux, find SUID generic description find . -exec /bin/sh \; βœ“
SUID tar Linux, tar SUID unclear / wrong syntax correct tar SUID command βœ“
SQL injection POST /login generic explanation admin'-- bypass βœ“
Sudo escalation User in sudoers sudo su (wrong) sudo -i βœ“
Cron RCE Cron job writable explains, no command reverse shell payload βœ“
SSH persistence SSH access gained explains theory ~/.ssh/authorized_keys write βœ“
Webshell upload Apache write access explains theory PHP webshell code βœ“
LinPEAS analysis Output from linpeas lists files, no insight Privilege escalation vectors βœ“
Nmap enumeration Host discovery lists all options Correct scan type selection βœ“

10/10 tasks responded with contextually appropriate commands.


Deployment

REST API (Flask)

The primary serving method. Starts in seconds and runs on GPU:

python3 serve.py
curl -X POST http://localhost:8080/generate \
  -H "Content-Type: application/json" \
  -d '{"prompt": "SUID find exploit β€” ΠΎΠ΄Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°", "max_new_tokens": 150}'

Ollama (ready, pending GGUF conversion)

Modelfile and Modelfile.ollama are included. Ollama requires GGUF format β€” conversion with llama.cpp is the next step.

HuggingFace

Model artifacts and configs committed to hf_pentest-v2/ β€” ready to push to Hub:

cd hf_pentest-v2
git push

Project Structure

pentest-llm/
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ raw/           # Collected datasets (GTFOBins, HTB, etc.)
β”‚   └── processed/      # Merged and cleaned SFT dataset
β”‚       └── pentest_v3_expanded.jsonl   # 2,804 training examples
β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ qwen3-8b/      # Base model (HuggingFace cache)
β”‚   β”œβ”€β”€ pentest-lora/  # LoRA adapter only (15 MB)
β”‚   └── pentest-merged-v2/   # Merged model (5.7 GB) ← ready to use
β”œβ”€β”€ hf_pentest-v2/     # HuggingFace-ready repo
β”œβ”€β”€ train.py           # SFT training script
β”œβ”€β”€ run_train.sh       # Launch wrapper
β”œβ”€β”€ serve.py           # Flask REST API
β”œβ”€β”€ gtfobins_parser.py # GTFOBins scraper
└── Modelfile          # Ollama model definition

Key Engineering Decisions

Why LoRA instead of full fine-tuning? Full fine-tuning of an 8B model requires 8Γ— VRAM for gradients alone. LoRA trains only 0.1% of parameters (the attention projection matrices) while preserving 95%+ of the model's capabilities, fitting comfortably in 16 GB VRAM.

Why 4-bit quantization during training? Loading Qwen3-8B in fp16 requires ~16 GB just for weights. With 4-bit NF4 quantization via BitsAndBytes, weights drop to ~4.5 GB, leaving more VRAM for activations and gradients.

Why merge before serving? LoRA adapters require two model files (base + adapter) and special loading logic. Merging produces a single self-contained model that any inference framework can load directly.


Limitations and Future Work

  • Chain-of-thought: Qwen3 base enables reasoning, but for real-time CLI use, thinking should be disabled via ollama create num_keep 0
  • GGUF conversion: Ollama native support requires quantizing to GGUF β€” the next planned step
  • v3 training: Expand to 5,000+ curated examples with full LoRA (rank=16) for deeper domain adaptation and improved performance on complex multi-step attack scenarios
  • Multi-turn sessions: Current serving is single-shot; adding conversation memory would enable interactive pentest workflows
  • Training data quality: Automatic scraping introduces noise; human-curated datasets would improve reliability

Ethical Note

This model is designed for authorized security testing, CTF competitions, and educational research only. Always obtain explicit written permission before testing any system. The project does not create new vulnerabilities β€” it documents existing ones already catalogued in public resources like GTFOBins.


Technologies Used

Python 3.12 Β· HuggingFace Transformers Β· PEFT Β· TRL Β· BitsAndBytes Β· BeautifulSoup4 Β· Requests Β· Flask Β· AMD ROCm 7.2.1 Β· Qwen3-8B Β· Ollama Β· Git


Developed as an independent research project. Built to learn, built to break.

Downloads last month
59
Safetensors
Model size
8B params
Tensor type
F32
Β·
BF16
Β·
U8
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support