// Documentation
Everything you need to know about vuln-pkg
# Overview
vuln-pkg is a package manager for deliberately-vulnerable applications used in security training and penetration testing. Think of it as npm install but for security labs.
Browse a catalog of intentionally vulnerable apps, pick one, and have it running in seconds with a clean URL. Whether you're practicing for OSCP, running a CTF, or teaching a security workshop, vuln-pkg eliminates the friction of setting up vulnerable environments.
Key Features
- •Zero-config DNS via sslip.io - works immediately without any local DNS setup
- •Traefik reverse proxy for clean subdomain URLs (e.g.,
http://dvwa.127.0.0.1.sslip.io) - •Simple CLI to list, search, install, run, stop, and remove vulnerable apps
- •Multiple apps running simultaneously
- •Custom packages - build your own vulnerable labs from Dockerfiles or Git repositories
- •JSON output for automation
# Installation
## Requirements
- ✓Docker (running)
## Quick Install - Linux/macOS (Recommended)
This will automatically detect your OS and architecture, download the latest release, and install it to /usr/local/bin (or ~/.local/bin if you don't have write access).
Install Options
## Windows Install
This installs vuln-pkg to %LOCALAPPDATA%\vuln-pkg.
Windows Install Options
## Download from Releases
Download pre-built binaries from the GitHub Releases page.
Available binaries:
vuln-pkg-linux-x86_64.tar.gz- Linux x86_64 (static binary)vuln-pkg-linux-aarch64.tar.gz- Linux ARM64vuln-pkg-darwin-x86_64.tar.gz- macOS Intelvuln-pkg-darwin-aarch64.tar.gz- macOS Apple Siliconvuln-pkg-windows-x86_64.zip- Windows x86_64
## Build from Source
Requires the Rust toolchain.
# Quick Start
# Commands
## list
List all available vulnerable applications from the manifest.
## search
Search for applications by name, description, or tags.
The search is case-insensitive and matches against application name, description text, and tags (CVEs, vulnerability types, etc.).
## install
Pull the Docker image for an application without starting it.
## run
Start a vulnerable application. This will:
- Pull the Docker image if needed
- Create the vuln-pkg Docker network
- Start Traefik reverse proxy (if not already running)
- Create and start the application container
## stop
Stop a running application without removing it.
## remove
Stop and remove an application container.
## rebuild
Rebuild a custom application (dockerfile or git type). Useful when you've updated the Dockerfile or want to pull the latest changes from a git repository.
Note: This command only works with custom packages (type: dockerfile or type: git). For prebuilt packages, use remove --purge followed by install.
## status
Show the status of all managed applications.
## manifest
Manage manifests - view information, list accepted manifests, or forget previously accepted ones.
# Global Options
| Option | Description |
|---|---|
--json | Output in JSON format for automation |
-y, --yes | Auto-accept new manifests without prompting (for scripting) |
--manifest-url <URL> | Custom manifest URL (default: official vuln-pkg manifest) |
--resolve-address <IP> | IP address for hostname resolution (default: 127.0.0.1) |
--domain <DOMAIN> | Custom domain suffix (e.g., lab.local) |
--https | Enable HTTPS with self-signed certificates |
# How It Works
## Zero-Config DNS
By default, vuln-pkg uses sslip.io for DNS resolution. sslip.io is a free service that resolves any hostname containing an IP address to that IP:
dvwa.127.0.0.1.sslip.io→ 127.0.0.1webgoat.192.168.1.100.sslip.io→ 192.168.1.100
## Custom Domain (Advanced)
If you prefer cleaner URLs like dvwa.lab.local, you can use the --domain flag:
This requires setting up local DNS resolution (e.g., dnsmasq, /etc/hosts, or systemd-resolved) to point *.lab.local to 127.0.0.1.
## Traefik Reverse Proxy
vuln-pkg uses Traefik as a reverse proxy to route requests to the correct container based on the hostname. This enables:
- • Clean subdomain-based URLs without port numbers
- • Multiple apps running simultaneously on port 80
- • Optional HTTPS support
When apps are running, the Traefik dashboard is available at http://traefik.127.0.0.1.sslip.io
## Multi-Port Applications
Applications with multiple ports get additional subdomains:
- First port:
<app>.<domain> - Additional ports:
<app>-<port>.<domain>
## Manifest Trust
When you use a manifest for the first time, vuln-pkg will display information about it and ask you to accept or reject it:
════════════════════════════════════════════════════════════
NEW MANIFEST
════════════════════════════════════════════════════════════
URL: https://example.com/manifest.yml
Author: Security Lab Team
Email: security@example.com
Website: https://github.com/example/vuln-lab
About: Custom vulnerable apps for internal training
Contains 5 application(s) available:
- custom-sqli
- custom-xss
...
════════════════════════════════════════════════════════════
⚠ This manifest has not been accepted before.
Review the information above and decide whether to trust it.
Accept this manifest? [y/N/show]:Options:
- • y/yes - Accept the manifest and remember the choice
- • n/no (or just Enter) - Reject and abort
- • show - Display the full manifest YAML for inspection
Once accepted, the manifest is remembered. Use -y flag to auto-accept for scripting:
# Manifest Format
vuln-pkg reads application definitions from a YAML manifest. A manifest contains metadata about the author and a list of applications.
## Manifest Metadata
Every manifest should include metadata to help users identify and trust it:
meta: author: "Security Lab Team" email: "security@example.com" url: "https://github.com/example/vuln-lab" description: "Custom vulnerable apps for internal training" apps: # ... application definitions
## Prebuilt Packages (Default)
Pull and run existing Docker images from registries:
apps:
- name: dvwa
version: "1.0"
image: vulnerables/web-dvwa:latest
description: Damn Vulnerable Web Application
ports:
- 80
tags:
- CVE-2021-12345
env:
- MYSQL_ROOT_PASSWORD=root## Dockerfile Packages
Build custom images from inline Dockerfiles or remote URLs:
apps:
# Inline Dockerfile
- name: custom-sqli-lab
version: "1.0"
type: dockerfile
dockerfile: |
FROM php:8.0-apache
RUN docker-php-ext-install mysqli pdo pdo_mysql
COPY vuln-app/ /var/www/html/
EXPOSE 80
ports: [80]
tags:
- SQL-Injection
description: Custom SQL injection lab
# Remote Dockerfile
- name: remote-vuln-app
version: "1.0"
type: dockerfile
dockerfile_url: https://example.com/Dockerfile
context_url: https://example.com/context.tar.gz
ports: [8080]## Git Packages
Clone a repository and build from its Dockerfile:
apps:
- name: git-vuln-lab
version: "1.0"
type: git
repo: https://github.com/user/vulnerable-app.git
ref: main # Branch, tag, or commit
dockerfile_path: ./Dockerfile # Optional
ports: [3000]
tags:
- Custom
description: Build from git repository## Fields Reference
| Field | Required | Description |
|---|---|---|
name | Yes | Unique identifier for the app |
version | Yes | Version string |
type | No | Package type: prebuilt (default), dockerfile, or git |
ports | Yes | List of container ports to expose |
tags | No | Tags for categorization (CVEs, vulnerability types) |
description | No | Human-readable description |
env | No | Environment variables |
# Examples
## Run Multiple Apps
## Custom Manifest
## Remote Access
If running vuln-pkg on a remote server accessible at 192.168.1.100:
## Enable HTTPS
## Scripting with Auto-Accept
# Troubleshooting
## Cannot connect to Docker
Ensure Docker is running:
## App not accessible
- Check the app is running:
vuln-pkg status - Verify Traefik is running:
docker ps | grep vuln-pkg-traefik - Check the Traefik dashboard for routing issues
- Ensure you have internet connectivity (for sslip.io DNS)
## Port 80/443 already in use
Stop any services using port 80 or 443 (e.g., nginx, apache) before running vuln-pkg, as Traefik needs these ports.
## Container starts but app doesn't load
Some apps take time to initialize. Check container logs:
Security Notice
This tool manages intentionally vulnerable containers for educational purposes. Never expose these containers to untrusted networks. When using --resolve-address with a public IP, ensure proper network segmentation. The Traefik dashboard is exposed without authentication by default.