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.
Each record follows the instruction-tuning format:
json
1{2"instruction":"Как получить root через vim SUID?",3"input":"Linux, vim root-owned SUID binary found",4"output":"vim -c ':!/bin/sh'"5}
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
bash
1curl -X POST http://localhost:8080/generate \2 -H "Content-Type: application/json"\3 -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:
bash
1cd hf_pentest-v2
2git 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.