Skip to content

Dradis Cheat Sheet

Overview

Dradis is an open-source collaboration and reporting platform designed for information security teams. It provides a centralized location for storing, organizing, and sharing security assessment findings, making it easier for teams to collaborate during penetration tests, vulnerability assessments, and security audits. Dradis helps streamline the reporting process by allowing multiple team members to contribute findings simultaneously and generate professional reports in various formats. The platform supports integration with popular security tools and provides a structured approach to managing security assessment data throughout the entire testing lifecycle.

⚠️ Important: Dradis contains sensitive security information and should be deployed in a secure environment with proper access controls, encryption, and backup procedures. Always follow your organization's data handling policies when using Dradis for security assessments.

Installation

Quick Start with Docker Compose

bash
# Create project directory
mkdir dradis-deployment && cd dradis-deployment

# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  dradis:
    image: dradis/dradis-ce:latest
    ports:
      - "3000:3000"
    environment:
      - RAILS_ENV=production
      - SECRET_KEY_BASE=your_secret_key_here_change_this
      - DRADIS_SETUP_PASSWORD=admin123
    volumes:
      - dradis_data:/opt/dradis-ce/shared
      - dradis_logs:/opt/dradis-ce/log
    restart: unless-stopped
    depends_on:
      - redis
      - postgres

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    restart: unless-stopped

  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=dradis_production
      - POSTGRES_USER=dradis
      - POSTGRES_PASSWORD=dradis_password_change_this
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  dradis_data:
  dradis_logs:
  redis_data:
  postgres_data:
EOF

# Generate secure secret key
SECRET_KEY=$(openssl rand -hex 64)
sed -i "s/your_secret_key_here_change_this/$SECRET_KEY/" docker-compose.yml

# Start Dradis
docker-compose up -d

# Check status
docker-compose ps

# View logs
docker-compose logs -f dradis

# Access Dradis at http://localhost:3000
echo "Dradis is available at: http://localhost:3000"
echo "Default credentials: admin / admin123"

Standalone Docker Installation

bash
# Pull latest Dradis image
docker pull dradis/dradis-ce:latest

# Run Dradis with SQLite (development/testing)
docker run -d \
  --name dradis \
  -p 3000:3000 \
  -e RAILS_ENV=production \
  -e SECRET_KEY_BASE=$(openssl rand -hex 64) \
  -e DRADIS_SETUP_PASSWORD=admin123 \
  -v dradis_data:/opt/dradis-ce/shared \
  dradis/dradis-ce:latest

# Check container status
docker ps | grep dradis

# View container logs
docker logs -f dradis

# Access container shell
docker exec -it dradis bash

# Stop and remove container
docker stop dradis && docker rm dradis

Manual Installation

Ubuntu/Debian Installation

bash
# Update system
sudo apt update && sudo apt upgrade -y

# Install dependencies
sudo apt install -y git curl build-essential libssl-dev libreadline-dev \
  zlib1g-dev libsqlite3-dev libxml2-dev libxslt1-dev libcurl4-openssl-dev \
  software-properties-common libffi-dev nodejs npm postgresql postgresql-contrib \
  redis-server

# Install Ruby via rbenv
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc

# Install Ruby 3.1.0
rbenv install 3.1.0
rbenv global 3.1.0

# Verify Ruby installation
ruby --version
gem --version

# Clone Dradis repository
git clone https://github.com/dradis/dradis-ce.git
cd dradis-ce

# Install bundler
gem install bundler

# Install dependencies
bundle install

# Setup database
bundle exec rake db:setup

# Start Dradis
bundle exec rails server -b 0.0.0.0 -p 3000

# Access Dradis at http://localhost:3000

CentOS/RHEL Installation

bash
# Install EPEL repository
sudo yum install -y epel-release

# Install dependencies
sudo yum groupinstall -y "Development Tools"
sudo yum install -y git curl openssl-devel readline-devel zlib-devel \
  sqlite-devel libxml2-devel libxslt-devel libcurl-devel nodejs npm \
  postgresql-server postgresql-contrib redis

# Initialize PostgreSQL
sudo postgresql-setup initdb
sudo systemctl enable postgresql redis
sudo systemctl start postgresql redis

# Install Ruby via rbenv
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc

# Install Ruby and continue with Dradis setup
rbenv install 3.1.0
rbenv global 3.1.0

# Clone and setup Dradis (same as Ubuntu)
git clone https://github.com/dradis/dradis-ce.git
cd dradis-ce
gem install bundler
bundle install
bundle exec rake db:setup
bundle exec rails server -b 0.0.0.0 -p 3000

macOS Installation

bash
# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install dependencies
brew install git ruby postgresql redis nodejs npm

# Start services
brew services start postgresql
brew services start redis

# Clone Dradis repository
git clone https://github.com/dradis/dradis-ce.git
cd dradis-ce

# Install bundler and dependencies
gem install bundler
bundle install

# Setup database
bundle exec rake db:setup

# Start Dradis
bundle exec rails server -b 0.0.0.0 -p 3000

Production Deployment

Nginx Reverse Proxy Configuration

bash
# Install Nginx
sudo apt install -y nginx

# Create Dradis site configuration
sudo tee /etc/nginx/sites-available/dradis << 'EOF'
upstream dradis {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    server_name dradis.company.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name dradis.company.com;

    ssl_certificate /etc/ssl/certs/dradis.crt;
    ssl_certificate_key /etc/ssl/private/dradis.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    client_max_body_size 100M;

    location / {
        proxy_pass http://dradis;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }

    location /cable {
        proxy_pass http://dradis;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
EOF

# Enable site
sudo ln -s /etc/nginx/sites-available/dradis /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Systemd Service Configuration

bash
# Create systemd service file
sudo tee /etc/systemd/system/dradis.service << 'EOF'
[Unit]
Description=Dradis Security Collaboration Platform
After=network.target postgresql.service redis.service
Requires=postgresql.service redis.service

[Service]
Type=simple
User=dradis
Group=dradis
WorkingDirectory=/opt/dradis-ce
Environment=RAILS_ENV=production
Environment=SECRET_KEY_BASE=your_secret_key_here
ExecStart=/home/dradis/.rbenv/shims/bundle exec rails server -b 127.0.0.1 -p 3000
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Create dradis user
sudo useradd -r -s /bin/bash -d /home/dradis -m dradis

# Move Dradis to /opt and set permissions
sudo mv dradis-ce /opt/
sudo chown -R dradis:dradis /opt/dradis-ce

# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable dradis
sudo systemctl start dradis

# Check service status
sudo systemctl status dradis

Basic Usage

Initial Setup and Configuration

bash
# Access Dradis web interface
# Navigate to http://localhost:3000

# First-time setup (via web interface)
# 1. Create admin account
# 2. Configure team settings
# 3. Set up project templates
# 4. Configure integrations

# Command line setup (alternative)
cd /opt/dradis-ce

# Create admin user
bundle exec rails console
> User.create!(email: 'admin@company.com', password: 'secure_password', admin: true)
> exit

# Reset admin password
bundle exec rake dradis:reset_password[admin@company.com]

# Check application status
bundle exec rails runner "puts 'Dradis is running: ' + (Rails.application.initialized? ? 'Yes' : 'No')"

Project Management

bash
# Create new project (via API)
curl -X POST http://localhost:3000/api/projects \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "project": {
      "name": "Acme Corp Penetration Test",
      "description": "Annual penetration test for Acme Corporation"
    }
  }'

# List projects
curl -X GET http://localhost:3000/api/projects \
  -H "Authorization: Token YOUR_API_TOKEN"

# Export project
curl -X GET http://localhost:3000/api/projects/1/export \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -o project_export.xml

# Import project
curl -X POST http://localhost:3000/api/projects/import \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -F "file=@project_export.xml"

Node and Issue Management

bash
# Create node (target/host)
curl -X POST http://localhost:3000/api/projects/1/nodes \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "node": {
      "label": "Web Server",
      "type_id": 1,
      "parent_id": null,
      "position": 1
    }
  }'

# Create issue
curl -X POST http://localhost:3000/api/projects/1/issues \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "issue": {
      "title": "SQL Injection Vulnerability",
      "text": "A SQL injection vulnerability was identified in the login form..."
    }
  }'

# Create evidence (link issue to node)
curl -X POST http://localhost:3000/api/projects/1/nodes/1/evidence \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "evidence": {
      "issue_id": 1,
      "content": "Evidence of SQL injection on login form..."
    }
  }'

# List issues
curl -X GET http://localhost:3000/api/projects/1/issues \
  -H "Authorization: Token YOUR_API_TOKEN"

# Update issue
curl -X PUT http://localhost:3000/api/projects/1/issues/1 \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "issue": {
      "title": "Critical SQL Injection Vulnerability",
      "text": "Updated description with additional details..."
    }
  }'

Report Generation

bash
# Generate HTML report
curl -X POST http://localhost:3000/api/projects/1/reports \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "report": {
      "template": "html_export",
      "format": "html"
    }
  }' \
  -o report.html

# Generate PDF report
curl -X POST http://localhost:3000/api/projects/1/reports \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "report": {
      "template": "word_export",
      "format": "pdf"
    }
  }' \
  -o report.pdf

# Generate Word document
curl -X POST http://localhost:3000/api/projects/1/reports \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "report": {
      "template": "word_export",
      "format": "docx"
    }
  }' \
  -o report.docx

# Generate Excel report
curl -X POST http://localhost:3000/api/projects/1/reports \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -d '{
    "report": {
      "template": "excel_export",
      "format": "xlsx"
    }
  }' \
  -o report.xlsx

Advanced Configuration

Custom Templates

bash
# Create custom report template directory
mkdir -p /opt/dradis-ce/templates/reports/custom_template

# Create template configuration
cat > /opt/dradis-ce/templates/reports/custom_template/template.yml << 'EOF'
name: Custom Penetration Test Report
description: Custom template for penetration testing reports
author: Security Team
version: 1.0

sections:
  - executive_summary
  - methodology
  - findings
  - recommendations
  - appendices

formats:
  - html
  - pdf
  - docx
EOF

# Create HTML template
cat > /opt/dradis-ce/templates/reports/custom_template/template.html.erb << 'EOF'
<!DOCTYPE html>
<html>
<head>
    <title><%= @project.name %> - Security Assessment Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .header { text-align: center; margin-bottom: 40px; }
        .section { margin: 30px 0; }
        .finding { margin: 20px 0; padding: 15px; border-left: 4px solid #ccc; }
        .critical { border-left-color: #d32f2f; }
        .high { border-left-color: #f57c00; }
        .medium { border-left-color: #fbc02d; }
        .low { border-left-color: #388e3c; }
        .info { border-left-color: #1976d2; }
    </style>
</head>
<body>
    <div class="header">
        <h1><%= @project.name %></h1>
        <h2>Security Assessment Report</h2>
        <p>Generated on: <%= Date.current.strftime("%B %d, %Y") %></p>
    </div>

    <div class="section">
        <h2>Executive Summary</h2>
        <p>This report presents the findings of the security assessment conducted for <%= @project.name %>.</p>
        
        <h3>Summary of Findings</h3>
        <ul>
            <li>Critical: <%= @issues.select { |i| i.severity == 'Critical' }.count %></li>
            <li>High: <%= @issues.select { |i| i.severity == 'High' }.count %></li>
            <li>Medium: <%= @issues.select { |i| i.severity == 'Medium' }.count %></li>
            <li>Low: <%= @issues.select { |i| i.severity == 'Low' }.count %></li>
        </ul>
    </div>

    <div class="section">
        <h2>Detailed Findings</h2>
        <% @issues.each do |issue| %>
            <div class="finding <%= issue.severity.downcase %>">
                <h3><%= issue.title %></h3>
                <p><strong>Severity:</strong> <%= issue.severity %></p>
                <div><%= simple_format(issue.text) %></div>
                
                <% if issue.evidence.any? %>
                    <h4>Evidence</h4>
                    <% issue.evidence.each do |evidence| %>
                        <div><%= simple_format(evidence.content) %></div>
                    <% end %>
                <% end %>
            </div>
        <% end %>
    </div>

    <div class="section">
        <h2>Recommendations</h2>
        <p>Based on the findings, the following recommendations are provided:</p>
        <ol>
            <li>Address all critical and high severity vulnerabilities immediately</li>
            <li>Implement a regular security testing program</li>
            <li>Provide security awareness training to development teams</li>
            <li>Establish secure coding practices and guidelines</li>
        </ol>
    </div>
</body>
</html>
EOF

# Restart Dradis to load new template
sudo systemctl restart dradis

Plugin Configuration

bash
# Configure Nmap plugin
cat > /opt/dradis-ce/config/plugins/nmap.yml << 'EOF'
enabled: true
settings:
  default_node_type: "Host"
  create_services: true
  create_os_info: true
  import_screenshots: true
EOF

# Configure Nessus plugin
cat > /opt/dradis-ce/config/plugins/nessus.yml << 'EOF'
enabled: true
settings:
  default_node_type: "Host"
  create_services: true
  severity_mapping:
    "Critical": "Critical"
    "High": "High"
    "Medium": "Medium"
    "Low": "Low"
    "Info": "Info"
EOF

# Configure Burp Suite plugin
cat > /opt/dradis-ce/config/plugins/burp.yml << 'EOF'
enabled: true
settings:
  default_node_type: "Web Application"
  import_requests: true
  import_responses: true
  severity_mapping:
    "High": "High"
    "Medium": "Medium"
    "Low": "Low"
    "Information": "Info"
EOF

# Restart Dradis to apply plugin configuration
sudo systemctl restart dradis

Database Configuration

bash
# Configure PostgreSQL for production
sudo -u postgres psql << 'EOF'
CREATE DATABASE dradis_production;
CREATE USER dradis WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE dradis_production TO dradis;
\q
EOF

# Update database configuration
cat > /opt/dradis-ce/config/database.yml << 'EOF'
production:
  adapter: postgresql
  encoding: unicode
  database: dradis_production
  pool: 5
  username: dradis
  password: secure_password
  host: localhost
  port: 5432
EOF

# Run database migrations
cd /opt/dradis-ce
RAILS_ENV=production bundle exec rake db:migrate

# Create database backup script
cat > /opt/dradis-ce/scripts/backup_database.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/opt/dradis-backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/dradis_backup_$DATE.sql"

mkdir -p "$BACKUP_DIR"

pg_dump -h localhost -U dradis -d dradis_production > "$BACKUP_FILE"

# Compress backup
gzip "$BACKUP_FILE"

# Keep only last 30 days of backups
find "$BACKUP_DIR" -name "dradis_backup_*.sql.gz" -mtime +30 -delete

echo "Database backup completed: ${BACKUP_FILE}.gz"
EOF

chmod +x /opt/dradis-ce/scripts/backup_database.sh

# Schedule daily backups
echo "0 2 * * * /opt/dradis-ce/scripts/backup_database.sh" | sudo crontab -u dradis -

Automation Scripts

Comprehensive Project Setup Script

bash
#!/bin/bash
# Comprehensive Dradis project setup and management script

DRADIS_URL="${DRADIS_URL:-http://localhost:3000}"
API_TOKEN="$1"
PROJECT_NAME="$2"
PROJECT_DESCRIPTION="$3"

if [ -z "$API_TOKEN" ] || [ -z "$PROJECT_NAME" ]; then
    echo "Usage: $0 <api_token> <project_name> [project_description]"
    echo "Example: $0 abc123token 'Acme Corp Pentest' 'Annual penetration test'"
    exit 1
fi

# Function to make API calls
api_call() {
    local method="$1"
    local endpoint="$2"
    local data="$3"
    local output_file="$4"
    
    local curl_args=(
        -X "$method"
        -H "Authorization: Token $API_TOKEN"
        -H "Content-Type: application/json"
        -s
    )
    
    if [ -n "$data" ]; then
        curl_args+=(-d "$data")
    fi
    
    if [ -n "$output_file" ]; then
        curl_args+=(-o "$output_file")
    fi
    
    curl "${curl_args[@]}" "$DRADIS_URL$endpoint"
}

# Function to create project
create_project() {
    local name="$1"
    local description="$2"
    
    echo "[+] Creating project: $name"
    
    local project_data=$(cat << EOF
{
    "project": {
        "name": "$name",
        "description": "$description"
    }
}
EOF
)
    
    local response=$(api_call "POST" "/api/projects" "$project_data")
    local project_id=$(echo "$response" | jq -r '.id')
    
    if [ "$project_id" != "null" ] && [ -n "$project_id" ]; then
        echo "  [+] Project created with ID: $project_id"
        echo "$project_id"
    else
        echo "  [-] Failed to create project"
        echo "  Response: $response"
        return 1
    fi
}

# Function to create standard node structure
create_node_structure() {
    local project_id="$1"
    
    echo "[+] Creating standard node structure"
    
    # Create main categories
    local categories=(
        "External Network:1"
        "Internal Network:2"
        "Web Applications:3"
        "Wireless Networks:4"
        "Physical Security:5"
    )
    
    for category in "${categories[@]}"; do
        local name=$(echo "$category" | cut -d':' -f1)
        local position=$(echo "$category" | cut -d':' -f2)
        
        local node_data=$(cat << EOF
{
    "node": {
        "label": "$name",
        "type_id": 1,
        "parent_id": null,
        "position": $position
    }
}
EOF
)
        
        local response=$(api_call "POST" "/api/projects/$project_id/nodes" "$node_data")
        local node_id=$(echo "$response" | jq -r '.id')
        
        if [ "$node_id" != "null" ] && [ -n "$node_id" ]; then
            echo "  [+] Created category node: $name (ID: $node_id)"
        else
            echo "  [-] Failed to create category node: $name"
        fi
    done
}

# Function to create standard issue templates
create_issue_templates() {
    local project_id="$1"
    
    echo "[+] Creating standard issue templates"
    
    # Define standard vulnerability templates
    local templates=(
        "SQL Injection:Critical:A SQL injection vulnerability allows attackers to manipulate database queries..."
        "Cross-Site Scripting (XSS):High:A cross-site scripting vulnerability allows attackers to inject malicious scripts..."
        "Insecure Direct Object Reference:Medium:The application allows direct access to objects based on user input..."
        "Information Disclosure:Low:Sensitive information is disclosed to unauthorized users..."
        "Missing Security Headers:Info:Security headers are missing or misconfigured..."
    )
    
    for template in "${templates[@]}"; do
        local title=$(echo "$template" | cut -d':' -f1)
        local severity=$(echo "$template" | cut -d':' -f2)
        local description=$(echo "$template" | cut -d':' -f3)
        
        local issue_data=$(cat << EOF
{
    "issue": {
        "title": "$title",
        "text": "## Description\n\n$description\n\n## Impact\n\n[Describe the potential impact]\n\n## Recommendation\n\n[Provide remediation steps]\n\n## References\n\n[Add relevant references]",
        "severity": "$severity"
    }
}
EOF
)
        
        local response=$(api_call "POST" "/api/projects/$project_id/issues" "$issue_data")
        local issue_id=$(echo "$response" | jq -r '.id')
        
        if [ "$issue_id" != "null" ] && [ -n "$issue_id" ]; then
            echo "  [+] Created issue template: $title (ID: $issue_id)"
        else
            echo "  [-] Failed to create issue template: $title"
        fi
    done
}

# Function to import tool results
import_tool_results() {
    local project_id="$1"
    local tool_type="$2"
    local file_path="$3"
    
    echo "[+] Importing $tool_type results from $file_path"
    
    if [ ! -f "$file_path" ]; then
        echo "  [-] File not found: $file_path"
        return 1
    fi
    
    # Upload file and import
    local response=$(curl -X POST \
        -H "Authorization: Token $API_TOKEN" \
        -F "file=@$file_path" \
        -F "plugin=$tool_type" \
        "$DRADIS_URL/api/projects/$project_id/import")
    
    if echo "$response" | grep -q "success"; then
        echo "  [+] Successfully imported $tool_type results"
    else
        echo "  [-] Failed to import $tool_type results"
        echo "  Response: $response"
    fi
}

# Function to generate reports
generate_reports() {
    local project_id="$1"
    local output_dir="$2"
    
    echo "[+] Generating reports"
    
    mkdir -p "$output_dir"
    
    # Generate different report formats
    local formats=("html" "pdf" "docx" "xlsx")
    
    for format in "${formats[@]}"; do
        echo "  [+] Generating $format report"
        
        local report_data=$(cat << EOF
{
    "report": {
        "template": "default_export",
        "format": "$format"
    }
}
EOF
)
        
        api_call "POST" "/api/projects/$project_id/reports" "$report_data" "$output_dir/report.$format"
        
        if [ -f "$output_dir/report.$format" ]; then
            echo "    [+] $format report saved: $output_dir/report.$format"
        else
            echo "    [-] Failed to generate $format report"
        fi
    done
}

# Function to backup project
backup_project() {
    local project_id="$1"
    local backup_dir="$2"
    
    echo "[+] Backing up project"
    
    mkdir -p "$backup_dir"
    
    local backup_file="$backup_dir/project_${project_id}_backup_$(date +%Y%m%d_%H%M%S).xml"
    
    api_call "GET" "/api/projects/$project_id/export" "" "$backup_file"
    
    if [ -f "$backup_file" ]; then
        echo "  [+] Project backup saved: $backup_file"
        
        # Compress backup
        gzip "$backup_file"
        echo "  [+] Backup compressed: ${backup_file}.gz"
    else
        echo "  [-] Failed to backup project"
    fi
}

# Function to setup team collaboration
setup_team_collaboration() {
    local project_id="$1"
    
    echo "[+] Setting up team collaboration"
    
    # Create team roles and assignments (this would typically be done via web interface)
    echo "  [!] Team collaboration setup should be completed via web interface:"
    echo "      1. Navigate to $DRADIS_URL/projects/$project_id/team"
    echo "      2. Add team members and assign roles"
    echo "      3. Configure notification settings"
    echo "      4. Set up review workflows"
}

# Function to create project dashboard
create_project_dashboard() {
    local project_id="$1"
    local output_file="$2"
    
    echo "[+] Creating project dashboard"
    
    # Get project statistics
    local project_info=$(api_call "GET" "/api/projects/$project_id")
    local issues=$(api_call "GET" "/api/projects/$project_id/issues")
    local nodes=$(api_call "GET" "/api/projects/$project_id/nodes")
    
    # Generate dashboard HTML
    cat > "$output_file" << EOF
<!DOCTYPE html>
<html>
<head>
    <title>Project Dashboard - $PROJECT_NAME</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .header { background-color: #f0f0f0; padding: 20px; border-radius: 5px; }
        .section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
        .stats { display: flex; justify-content: space-around; }
        .stat { text-align: center; padding: 10px; }
        .stat h3 { margin: 0; font-size: 2em; }
        .critical { color: #d32f2f; }
        .high { color: #f57c00; }
        .medium { color: #fbc02d; }
        .low { color: #388e3c; }
        .info { color: #1976d2; }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <div class="header">
        <h1>📊 Project Dashboard</h1>
        <p><strong>Project:</strong> $PROJECT_NAME</p>
        <p><strong>Generated:</strong> $(date)</p>
        <p><strong>Dradis URL:</strong> <a href="$DRADIS_URL/projects/$project_id">$DRADIS_URL/projects/$project_id</a></p>
    </div>
    
    <div class="section">
        <h2>📈 Project Statistics</h2>
        <div class="stats">
            <div class="stat">
                <h3>$(echo "$issues" | jq length)</h3>
                <p>Total Issues</p>
            </div>
            <div class="stat">
                <h3>$(echo "$nodes" | jq length)</h3>
                <p>Total Nodes</p>
            </div>
            <div class="stat critical">
                <h3>$(echo "$issues" | jq '[.[] | select(.severity == "Critical")] | length')</h3>
                <p>Critical</p>
            </div>
            <div class="stat high">
                <h3>$(echo "$issues" | jq '[.[] | select(.severity == "High")] | length')</h3>
                <p>High</p>
            </div>
            <div class="stat medium">
                <h3>$(echo "$issues" | jq '[.[] | select(.severity == "Medium")] | length')</h3>
                <p>Medium</p>
            </div>
            <div class="stat low">
                <h3>$(echo "$issues" | jq '[.[] | select(.severity == "Low")] | length')</h3>
                <p>Low</p>
            </div>
        </div>
    </div>
    
    <div class="section">
        <h2>🎯 Recent Issues</h2>
        <table style="width: 100%; border-collapse: collapse;">
            <tr style="background-color: #f2f2f2;">
                <th style="border: 1px solid #ddd; padding: 8px;">Title</th>
                <th style="border: 1px solid #ddd; padding: 8px;">Severity</th>
                <th style="border: 1px solid #ddd; padding: 8px;">Created</th>
            </tr>
EOF
    
    # Add recent issues to dashboard
    echo "$issues" | jq -r '.[] | [.title, .severity, .created_at] | @csv' | head -10 | while IFS=',' read -r title severity created; do
        title=$(echo "$title" | tr -d '"')
        severity=$(echo "$severity" | tr -d '"')
        created=$(echo "$created" | tr -d '"')
        
        cat >> "$output_file" << EOF
            <tr>
                <td style="border: 1px solid #ddd; padding: 8px;">$title</td>
                <td style="border: 1px solid #ddd; padding: 8px;" class="$(echo $severity | tr '[:upper:]' '[:lower:]')">$severity</td>
                <td style="border: 1px solid #ddd; padding: 8px;">$created</td>
            </tr>
EOF
    done
    
    cat >> "$output_file" << EOF
        </table>
    </div>
    
    <div class="section">
        <h2>🔗 Quick Links</h2>
        <ul>
            <li><a href="$DRADIS_URL/projects/$project_id">Project Overview</a></li>
            <li><a href="$DRADIS_URL/projects/$project_id/issues">Issues</a></li>
            <li><a href="$DRADIS_URL/projects/$project_id/nodes">Nodes</a></li>
            <li><a href="$DRADIS_URL/projects/$project_id/reports">Reports</a></li>
            <li><a href="$DRADIS_URL/projects/$project_id/team">Team</a></li>
        </ul>
    </div>
</body>
</html>
EOF
    
    echo "  [+] Project dashboard created: $output_file"
}

# Main execution
echo "[+] Dradis Project Setup and Management"
echo "======================================="

# Check if jq is available
if ! command -v jq &> /dev/null; then
    echo "[-] jq is required but not installed. Please install jq."
    exit 1
fi

# Test API connection
echo "[+] Testing API connection"
response=$(api_call "GET" "/api/projects")
if echo "$response" | jq . &> /dev/null; then
    echo "  [+] API connection successful"
else
    echo "  [-] API connection failed"
    echo "  Response: $response"
    exit 1
fi

# Create project
PROJECT_ID=$(create_project "$PROJECT_NAME" "$PROJECT_DESCRIPTION")
if [ -z "$PROJECT_ID" ]; then
    echo "[-] Failed to create project. Exiting."
    exit 1
fi

# Setup project structure
create_node_structure "$PROJECT_ID"
create_issue_templates "$PROJECT_ID"

# Create output directory
OUTPUT_DIR="dradis_project_${PROJECT_ID}_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"

# Generate initial reports
generate_reports "$PROJECT_ID" "$OUTPUT_DIR/reports"

# Create project dashboard
create_project_dashboard "$PROJECT_ID" "$OUTPUT_DIR/dashboard.html"

# Backup project
backup_project "$PROJECT_ID" "$OUTPUT_DIR/backups"

# Setup team collaboration
setup_team_collaboration "$PROJECT_ID"

echo ""
echo "[+] Project setup completed successfully!"
echo "========================================"
echo "Project ID: $PROJECT_ID"
echo "Project URL: $DRADIS_URL/projects/$PROJECT_ID"
echo "Output Directory: $OUTPUT_DIR"
echo "Dashboard: $OUTPUT_DIR/dashboard.html"
echo ""
echo "Next Steps:"
echo "1. Add team members via web interface"
echo "2. Import tool results using: $0 import <tool_type> <file_path>"
echo "3. Begin collaborative testing and documentation"
echo "4. Generate final reports when assessment is complete"

Tool Integration Script

bash
#!/bin/bash
# Dradis tool integration and import script

DRADIS_URL="${DRADIS_URL:-http://localhost:3000}"
API_TOKEN="$1"
PROJECT_ID="$2"
TOOL_TYPE="$3"
FILE_PATH="$4"

if [ -z "$API_TOKEN" ] || [ -z "$PROJECT_ID" ] || [ -z "$TOOL_TYPE" ] || [ -z "$FILE_PATH" ]; then
    echo "Usage: $0 <api_token> <project_id> <tool_type> <file_path>"
    echo ""
    echo "Supported tool types:"
    echo "  nmap          - Nmap XML output"
    echo "  nessus        - Nessus .nessus files"
    echo "  burp          - Burp Suite XML export"
    echo "  zap           - OWASP ZAP XML report"
    echo "  nikto         - Nikto XML output"
    echo "  openvas       - OpenVAS XML report"
    echo "  qualys        - Qualys XML export"
    echo "  nexpose       - Nexpose XML export"
    echo "  metasploit    - Metasploit XML export"
    echo ""
    echo "Example: $0 abc123token 1 nmap scan_results.xml"
    exit 1
fi

# Function to validate file format
validate_file() {
    local tool="$1"
    local file="$2"
    
    if [ ! -f "$file" ]; then
        echo "[-] File not found: $file"
        return 1
    fi
    
    case "$tool" in
        "nmap")
            if ! grep -q "nmaprun" "$file"; then
                echo "[-] Invalid Nmap XML format"
                return 1
            fi
            ;;
        "nessus")
            if ! grep -q "NessusClientData" "$file"; then
                echo "[-] Invalid Nessus format"
                return 1
            fi
            ;;
        "burp")
            if ! grep -q "issues" "$file"; then
                echo "[-] Invalid Burp Suite XML format"
                return 1
            fi
            ;;
        "zap")
            if ! grep -q "OWASPZAPReport" "$file"; then
                echo "[-] Invalid OWASP ZAP XML format"
                return 1
            fi
            ;;
        *)
            echo "[!] File format validation not implemented for $tool"
            ;;
    esac
    
    echo "[+] File format validation passed"
    return 0
}

# Function to preprocess files
preprocess_file() {
    local tool="$1"
    local file="$2"
    local output_file="$3"
    
    case "$tool" in
        "nmap")
            # Clean up Nmap XML for better parsing
            sed 's/&/&amp;/g' "$file" > "$output_file"
            ;;
        "nikto")
            # Convert Nikto CSV to XML if needed
            if grep -q "," "$file"; then
                echo "[+] Converting Nikto CSV to XML format"
                python3 << EOF
import csv
import xml.etree.ElementTree as ET

root = ET.Element("nikto")
with open("$file", 'r') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        item = ET.SubElement(root, "item")
        for key, value in row.items():
            elem = ET.SubElement(item, key.replace(' ', '_').lower())
            elem.text = value

tree = ET.ElementTree(root)
tree.write("$output_file", encoding='utf-8', xml_declaration=True)
EOF
            else
                cp "$file" "$output_file"
            fi
            ;;
        *)
            cp "$file" "$output_file"
            ;;
    esac
}

# Function to import file
import_file() {
    local project_id="$1"
    local tool="$2"
    local file="$3"
    
    echo "[+] Importing $tool results into project $project_id"
    
    local response=$(curl -X POST \
        -H "Authorization: Token $API_TOKEN" \
        -F "file=@$file" \
        -F "plugin=$tool" \
        -s \
        "$DRADIS_URL/api/projects/$project_id/import")
    
    if echo "$response" | grep -q "success\|imported"; then
        echo "  [+] Successfully imported $tool results"
        
        # Extract import statistics if available
        if command -v jq &> /dev/null && echo "$response" | jq . &> /dev/null; then
            local nodes_created=$(echo "$response" | jq -r '.nodes_created // 0')
            local issues_created=$(echo "$response" | jq -r '.issues_created // 0')
            local evidence_created=$(echo "$response" | jq -r '.evidence_created // 0')
            
            echo "    - Nodes created: $nodes_created"
            echo "    - Issues created: $issues_created"
            echo "    - Evidence created: $evidence_created"
        fi
    else
        echo "  [-] Failed to import $tool results"
        echo "  Response: $response"
        return 1
    fi
}

# Function to post-process imported data
post_process_import() {
    local project_id="$1"
    local tool="$2"
    
    echo "[+] Post-processing imported data"
    
    case "$tool" in
        "nmap")
            # Tag Nmap-imported nodes
            echo "  [+] Tagging Nmap-imported nodes"
            ;;
        "nessus")
            # Categorize Nessus findings by severity
            echo "  [+] Categorizing Nessus findings"
            ;;
        "burp")
            # Group Burp findings by vulnerability type
            echo "  [+] Grouping Burp findings"
            ;;
        *)
            echo "  [!] No post-processing defined for $tool"
            ;;
    esac
}

# Function to generate import summary
generate_import_summary() {
    local project_id="$1"
    local tool="$2"
    local file="$3"
    local output_file="$4"
    
    echo "[+] Generating import summary"
    
    cat > "$output_file" << EOF
# Dradis Import Summary

## Import Details
- **Tool:** $tool
- **Source File:** $file
- **Project ID:** $project_id
- **Import Date:** $(date)
- **File Size:** $(du -h "$file" | cut -f1)

## Import Results
EOF
    
    # Get current project statistics
    local project_info=$(curl -X GET \
        -H "Authorization: Token $API_TOKEN" \
        -s \
        "$DRADIS_URL/api/projects/$project_id")
    
    local issues=$(curl -X GET \
        -H "Authorization: Token $API_TOKEN" \
        -s \
        "$DRADIS_URL/api/projects/$project_id/issues")
    
    local nodes=$(curl -X GET \
        -H "Authorization: Token $API_TOKEN" \
        -s \
        "$DRADIS_URL/api/projects/$project_id/nodes")
    
    if command -v jq &> /dev/null; then
        cat >> "$output_file" << EOF

### Current Project Statistics
- **Total Issues:** $(echo "$issues" | jq length)
- **Total Nodes:** $(echo "$nodes" | jq length)
- **Critical Issues:** $(echo "$issues" | jq '[.[] | select(.severity == "Critical")] | length')
- **High Issues:** $(echo "$issues" | jq '[.[] | select(.severity == "High")] | length')
- **Medium Issues:** $(echo "$issues" | jq '[.[] | select(.severity == "Medium")] | length')
- **Low Issues:** $(echo "$issues" | jq '[.[] | select(.severity == "Low")] | length')

### Recent Issues (Last 10)
EOF
        
        echo "$issues" | jq -r '.[-10:] | .[] | "- **" + .title + "** (" + .severity + ")"' >> "$output_file"
    fi
    
    cat >> "$output_file" << EOF

## Next Steps
1. Review imported findings for accuracy
2. Merge duplicate issues if necessary
3. Add additional evidence and context
4. Assign issues to team members for verification
5. Update issue descriptions and recommendations

## Links
- [Project Overview]($DRADIS_URL/projects/$project_id)
- [Issues]($DRADIS_URL/projects/$project_id/issues)
- [Nodes]($DRADIS_URL/projects/$project_id/nodes)
EOF
    
    echo "  [+] Import summary generated: $output_file"
}

# Main execution
echo "[+] Dradis Tool Integration"
echo "==========================="

# Validate file
if ! validate_file "$TOOL_TYPE" "$FILE_PATH"; then
    exit 1
fi

# Create temporary directory for processing
TEMP_DIR=$(mktemp -d)
PROCESSED_FILE="$TEMP_DIR/processed_$(basename "$FILE_PATH")"

# Preprocess file
preprocess_file "$TOOL_TYPE" "$FILE_PATH" "$PROCESSED_FILE"

# Import file
if import_file "$PROJECT_ID" "$TOOL_TYPE" "$PROCESSED_FILE"; then
    # Post-process imported data
    post_process_import "$PROJECT_ID" "$TOOL_TYPE"
    
    # Generate import summary
    SUMMARY_FILE="dradis_import_summary_$(date +%Y%m%d_%H%M%S).md"
    generate_import_summary "$PROJECT_ID" "$TOOL_TYPE" "$FILE_PATH" "$SUMMARY_FILE"
    
    echo ""
    echo "[+] Import completed successfully!"
    echo "================================="
    echo "Project URL: $DRADIS_URL/projects/$PROJECT_ID"
    echo "Import Summary: $SUMMARY_FILE"
    echo ""
    echo "Recommended next steps:"
    echo "1. Review imported findings in Dradis web interface"
    echo "2. Verify and validate imported data"
    echo "3. Add additional context and evidence"
    echo "4. Assign findings to team members"
else
    echo "[-] Import failed"
    exit 1
fi

# Cleanup
rm -rf "$TEMP_DIR"

Report Automation Script

bash
#!/bin/bash
# Automated report generation and distribution script

DRADIS_URL="${DRADIS_URL:-http://localhost:3000}"
API_TOKEN="$1"
PROJECT_ID="$2"
REPORT_TYPE="${3:-all}"
OUTPUT_DIR="${4:-reports_$(date +%Y%m%d_%H%M%S)}"

if [ -z "$API_TOKEN" ] || [ -z "$PROJECT_ID" ]; then
    echo "Usage: $0 <api_token> <project_id> [report_type] [output_dir]"
    echo ""
    echo "Report types:"
    echo "  all           - Generate all report formats"
    echo "  executive     - Executive summary only"
    echo "  technical     - Technical details only"
    echo "  html          - HTML format only"
    echo "  pdf           - PDF format only"
    echo "  docx          - Word document only"
    echo "  xlsx          - Excel spreadsheet only"
    echo ""
    echo "Example: $0 abc123token 1 all ./reports"
    exit 1
fi

# Function to generate report
generate_report() {
    local project_id="$1"
    local template="$2"
    local format="$3"
    local output_file="$4"
    
    echo "[+] Generating $format report with $template template"
    
    local report_data=$(cat << EOF
{
    "report": {
        "template": "$template",
        "format": "$format"
    }
}
EOF
)
    
    local response=$(curl -X POST \
        -H "Authorization: Token $API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$report_data" \
        -s \
        -o "$output_file" \
        -w "%{http_code}" \
        "$DRADIS_URL/api/projects/$project_id/reports")
    
    if [ "$response" = "200" ] && [ -f "$output_file" ] && [ -s "$output_file" ]; then
        echo "  [+] Report generated successfully: $output_file"
        return 0
    else
        echo "  [-] Failed to generate report (HTTP: $response)"
        return 1
    fi
}

# Function to customize report content
customize_report() {
    local project_id="$1"
    local template_type="$2"
    local output_file="$3"
    
    echo "[+] Customizing $template_type report"
    
    # Get project data
    local project_info=$(curl -X GET \
        -H "Authorization: Token $API_TOKEN" \
        -s \
        "$DRADIS_URL/api/projects/$project_id")
    
    local issues=$(curl -X GET \
        -H "Authorization: Token $API_TOKEN" \
        -s \
        "$DRADIS_URL/api/projects/$project_id/issues")
    
    if ! command -v jq &> /dev/null; then
        echo "  [!] jq not available, skipping customization"
        return 0
    fi
    
    local project_name=$(echo "$project_info" | jq -r '.name')
    local total_issues=$(echo "$issues" | jq length)
    local critical_count=$(echo "$issues" | jq '[.[] | select(.severity == "Critical")] | length')
    local high_count=$(echo "$issues" | jq '[.[] | select(.severity == "High")] | length')
    
    case "$template_type" in
        "executive")
            # Create executive summary
            cat > "$output_file" << EOF
# Executive Summary - $project_name

## Assessment Overview
This security assessment identified **$total_issues** total findings, including **$critical_count** critical and **$high_count** high severity vulnerabilities.

## Key Findings
$(echo "$issues" | jq -r '.[] | select(.severity == "Critical" or .severity == "High") | "- **" + .title + "** (" + .severity + ")"' | head -5)

## Risk Assessment
$(if [ "$critical_count" -gt 0 ]; then echo "🔴 **CRITICAL RISK** - Immediate action required"; elif [ "$high_count" -gt 0 ]; then echo "🟠 **HIGH RISK** - Action required within 24-48 hours"; else echo "🟡 **MODERATE RISK** - Address findings in next release cycle"; fi)

## Recommendations
1. Address all critical and high severity vulnerabilities immediately
2. Implement security controls to prevent similar issues
3. Conduct regular security assessments
4. Provide security training to development teams

*Generated on $(date)*
EOF
            ;;
        "technical")
            # Create technical details
            cat > "$output_file" << EOF
# Technical Assessment Report - $project_name

## Methodology
This assessment was conducted using industry-standard penetration testing methodologies.

## Detailed Findings

EOF
            echo "$issues" | jq -r '.[] | "### " + .title + "\n\n**Severity:** " + .severity + "\n\n" + .text + "\n\n---\n"' >> "$output_file"
            ;;
    esac
    
    echo "  [+] Custom report created: $output_file"
}

# Function to add watermarks and branding
add_branding() {
    local file="$1"
    local format="$2"
    
    echo "[+] Adding branding to $format report"
    
    case "$format" in
        "pdf")
            # Add watermark to PDF (requires pdftk or similar)
            if command -v pdftk &> /dev/null; then
                echo "  [+] Adding PDF watermark"
                # pdftk "$file" background watermark.pdf output "${file%.pdf}_branded.pdf"
            else
                echo "  [!] pdftk not available, skipping PDF branding"
            fi
            ;;
        "html")
            # Add CSS branding to HTML
            if [ -f "$file" ]; then
                sed -i '/<\/head>/i\
<style>\
.header::before { content: "CONFIDENTIAL - Internal Use Only"; color: red; font-weight: bold; }\
.footer::after { content: "Generated by Security Team - $(date)"; font-size: 0.8em; color: #666; }\
</style>' "$file"
                echo "  [+] HTML branding added"
            fi
            ;;
    esac
}

# Function to encrypt sensitive reports
encrypt_report() {
    local file="$1"
    local password="$2"
    
    echo "[+] Encrypting report: $(basename "$file")"
    
    if command -v gpg &> /dev/null; then
        # Encrypt with GPG
        gpg --symmetric --cipher-algo AES256 --compress-algo 1 --s2k-mode 3 \
            --s2k-digest-algo SHA512 --s2k-count 65536 --quiet \
            --passphrase "$password" --batch --yes "$file"
        
        if [ -f "${file}.gpg" ]; then
            echo "  [+] Report encrypted: ${file}.gpg"
            rm "$file"  # Remove unencrypted version
        fi
    elif command -v openssl &> /dev/null; then
        # Encrypt with OpenSSL
        openssl enc -aes-256-cbc -salt -in "$file" -out "${file}.enc" -pass pass:"$password"
        
        if [ -f "${file}.enc" ]; then
            echo "  [+] Report encrypted: ${file}.enc"
            rm "$file"  # Remove unencrypted version
        fi
    else
        echo "  [!] No encryption tools available"
    fi
}

# Function to distribute reports
distribute_reports() {
    local output_dir="$1"
    local project_id="$2"
    
    echo "[+] Distributing reports"
    
    # Create distribution package
    local package_name="security_assessment_reports_$(date +%Y%m%d_%H%M%S).tar.gz"
    tar -czf "$package_name" -C "$(dirname "$output_dir")" "$(basename "$output_dir")"
    
    echo "  [+] Distribution package created: $package_name"
    
    # Send via email (if configured)
    if command -v mail &> /dev/null && [ -n "$REPORT_EMAIL" ]; then
        echo "Sending security assessment reports for project $project_id" | \
            mail -s "Security Assessment Reports - $(date)" \
                 -a "$package_name" \
                 "$REPORT_EMAIL"
        echo "  [+] Reports sent via email to: $REPORT_EMAIL"
    fi
    
    # Upload to secure storage (example with AWS S3)
    if command -v aws &> /dev/null && [ -n "$S3_BUCKET" ]; then
        aws s3 cp "$package_name" "s3://$S3_BUCKET/security-reports/"
        echo "  [+] Reports uploaded to S3: s3://$S3_BUCKET/security-reports/$package_name"
    fi
    
    # Create secure download link
    if [ -n "$SECURE_UPLOAD_URL" ]; then
        curl -X POST \
            -F "file=@$package_name" \
            -F "expires=7d" \
            "$SECURE_UPLOAD_URL" > download_link.txt
        echo "  [+] Secure download link created: $(cat download_link.txt)"
    fi
}

# Function to create report index
create_report_index() {
    local output_dir="$1"
    local project_id="$2"
    
    echo "[+] Creating report index"
    
    local index_file="$output_dir/index.html"
    
    cat > "$index_file" << EOF
<!DOCTYPE html>
<html>
<head>
    <title>Security Assessment Reports</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .header { text-align: center; margin-bottom: 40px; }
        .reports { margin: 20px 0; }
        .report-item { margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
        .download-btn { background-color: #007bff; color: white; padding: 8px 16px; text-decoration: none; border-radius: 4px; }
        .download-btn:hover { background-color: #0056b3; }
    </style>
</head>
<body>
    <div class="header">
        <h1>🔒 Security Assessment Reports</h1>
        <p><strong>Project ID:</strong> $project_id</p>
        <p><strong>Generated:</strong> $(date)</p>
    </div>
    
    <div class="reports">
        <h2>📄 Available Reports</h2>
EOF
    
    # List all generated reports
    for report_file in "$output_dir"/*.{html,pdf,docx,xlsx,md} 2>/dev/null; do
        if [ -f "$report_file" ]; then
            local filename=$(basename "$report_file")
            local filesize=$(du -h "$report_file" | cut -f1)
            
            cat >> "$index_file" << EOF
        <div class="report-item">
            <strong>$filename</strong> ($filesize)
            <a href="$filename" class="download-btn">Download</a>
        </div>
EOF
        fi
    done
    
    cat >> "$index_file" << EOF
    </div>
    
    <div class="reports">
        <h2>📊 Report Summary</h2>
        <p>This package contains comprehensive security assessment reports in multiple formats:</p>
        <ul>
            <li><strong>HTML:</strong> Interactive web-based reports</li>
            <li><strong>PDF:</strong> Printable documents for distribution</li>
            <li><strong>Word:</strong> Editable documents for customization</li>
            <li><strong>Excel:</strong> Data analysis and tracking</li>
            <li><strong>Markdown:</strong> Version-controlled documentation</li>
        </ul>
    </div>
    
    <div class="reports">
        <h2>🔐 Security Notice</h2>
        <p><strong>CONFIDENTIAL:</strong> These reports contain sensitive security information and should be handled according to your organization's data classification policies.</p>
    </div>
</body>
</html>
EOF
    
    echo "  [+] Report index created: $index_file"
}

# Main execution
echo "[+] Dradis Report Automation"
echo "============================"

# Create output directory
mkdir -p "$OUTPUT_DIR"

# Generate reports based on type
case "$REPORT_TYPE" in
    "all")
        echo "[+] Generating all report formats"
        generate_report "$PROJECT_ID" "default_export" "html" "$OUTPUT_DIR/security_report.html"
        generate_report "$PROJECT_ID" "default_export" "pdf" "$OUTPUT_DIR/security_report.pdf"
        generate_report "$PROJECT_ID" "word_export" "docx" "$OUTPUT_DIR/security_report.docx"
        generate_report "$PROJECT_ID" "excel_export" "xlsx" "$OUTPUT_DIR/security_report.xlsx"
        customize_report "$PROJECT_ID" "executive" "$OUTPUT_DIR/executive_summary.md"
        customize_report "$PROJECT_ID" "technical" "$OUTPUT_DIR/technical_details.md"
        ;;
    "executive")
        echo "[+] Generating executive reports"
        customize_report "$PROJECT_ID" "executive" "$OUTPUT_DIR/executive_summary.md"
        generate_report "$PROJECT_ID" "executive_export" "pdf" "$OUTPUT_DIR/executive_summary.pdf"
        ;;
    "technical")
        echo "[+] Generating technical reports"
        customize_report "$PROJECT_ID" "technical" "$OUTPUT_DIR/technical_details.md"
        generate_report "$PROJECT_ID" "default_export" "html" "$OUTPUT_DIR/technical_report.html"
        ;;
    "html")
        generate_report "$PROJECT_ID" "default_export" "html" "$OUTPUT_DIR/security_report.html"
        ;;
    "pdf")
        generate_report "$PROJECT_ID" "default_export" "pdf" "$OUTPUT_DIR/security_report.pdf"
        ;;
    "docx")
        generate_report "$PROJECT_ID" "word_export" "docx" "$OUTPUT_DIR/security_report.docx"
        ;;
    "xlsx")
        generate_report "$PROJECT_ID" "excel_export" "xlsx" "$OUTPUT_DIR/security_report.xlsx"
        ;;
    *)
        echo "[-] Unknown report type: $REPORT_TYPE"
        exit 1
        ;;
esac

# Add branding to reports
for report_file in "$OUTPUT_DIR"/*.{html,pdf} 2>/dev/null; do
    if [ -f "$report_file" ]; then
        add_branding "$report_file" "${report_file##*.}"
    fi
done

# Encrypt sensitive reports (if password provided)
if [ -n "$REPORT_PASSWORD" ]; then
    for report_file in "$OUTPUT_DIR"/*.{pdf,docx} 2>/dev/null; do
        if [ -f "$report_file" ]; then
            encrypt_report "$report_file" "$REPORT_PASSWORD"
        fi
    done
fi

# Create report index
create_report_index "$OUTPUT_DIR" "$PROJECT_ID"

# Distribute reports
distribute_reports "$OUTPUT_DIR" "$PROJECT_ID"

echo ""
echo "[+] Report generation completed successfully!"
echo "==========================================="
echo "Output Directory: $OUTPUT_DIR"
echo "Report Index: $OUTPUT_DIR/index.html"
echo ""
echo "Generated Reports:"
ls -la "$OUTPUT_DIR"
echo ""
echo "Next Steps:"
echo "1. Review generated reports for accuracy"
echo "2. Customize reports as needed"
echo "3. Distribute to stakeholders"
echo "4. Archive reports securely"

Integration with Security Tools

Nmap Integration

bash
# Import Nmap results
nmap -sS -sV -O -A target.com -oX nmap_results.xml
curl -X POST -H "Authorization: Token $API_TOKEN" \
  -F "file=@nmap_results.xml" -F "plugin=nmap" \
  http://localhost:3000/api/projects/1/import

Nessus Integration

bash
# Export Nessus scan and import
curl -X POST -H "Authorization: Token $API_TOKEN" \
  -F "file=@nessus_scan.nessus" -F "plugin=nessus" \
  http://localhost:3000/api/projects/1/import

Burp Suite Integration

bash
# Export Burp findings and import
curl -X POST -H "Authorization: Token $API_TOKEN" \
  -F "file=@burp_findings.xml" -F "plugin=burp" \
  http://localhost:3000/api/projects/1/import

OWASP ZAP Integration

bash
# Import ZAP results
curl -X POST -H "Authorization: Token $API_TOKEN" \
  -F "file=@zap_report.xml" -F "plugin=zap" \
  http://localhost:3000/api/projects/1/import

Troubleshooting

Common Issues

Database Connection Problems

bash
# Check database status
sudo systemctl status postgresql

# Reset database
cd /opt/dradis-ce
RAILS_ENV=production bundle exec rake db:reset

# Check database configuration
cat config/database.yml

Memory Issues

bash
# Increase Ruby memory limit
export RUBY_GC_HEAP_INIT_SLOTS=1000000
export RUBY_GC_HEAP_FREE_SLOTS=500000
export RUBY_GC_HEAP_GROWTH_FACTOR=1.1

# Monitor memory usage
ps aux | grep rails

Performance Optimization

bash
# Enable Redis caching
sudo systemctl start redis
sudo systemctl enable redis

# Configure Rails caching
echo "config.cache_store = :redis_cache_store" >> config/environments/production.rb

# Optimize database
sudo -u postgres psql dradis_production -c "VACUUM ANALYZE;"

SSL/TLS Configuration

bash
# Generate self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout dradis.key -out dradis.crt -days 365 -nodes

# Configure SSL in Nginx
ssl_certificate /etc/ssl/certs/dradis.crt;
ssl_certificate_key /etc/ssl/private/dradis.key;

Backup and Recovery

bash
# Backup Dradis data
pg_dump -h localhost -U dradis dradis_production > dradis_backup.sql
tar -czf dradis_files_backup.tar.gz /opt/dradis-ce/shared

# Restore from backup
sudo -u postgres psql -c "DROP DATABASE dradis_production;"
sudo -u postgres psql -c "CREATE DATABASE dradis_production;"
psql -h localhost -U dradis dradis_production < dradis_backup.sql
tar -xzf dradis_files_backup.tar.gz -C /

Resources


This cheat sheet provides a comprehensive reference for using Dradis for security assessment collaboration and reporting. Always ensure you have proper authorization before conducting security assessments and follow your organization's data handling policies when using Dradis.