Files
mysql-scanner/mysql-scanner/USAGE.md
2026-02-26 22:47:32 +00:00

5.3 KiB

MySQL Scanner - Usage Examples

Quick Start

Basic WordPress Scan

cd tools/go/mysql-scanner

# Using command-line flags
./mysql-scanner --host localhost --user wp_user --password secret --db wordpress

# Using environment variables
DB_HOST=localhost DB_USER=wp_user DB_PASSWORD=secret DB_NAME=wordpress ./mysql-scanner

Filter by Pattern Type

# Only scan for eval() and base64_decode()
./mysql-scanner --host localhost --user user --db mydb --patterns eval,base64

# Only scan for script tags and iframes
./mysql-scanner --host localhost --user user --db mydb --patterns script_tag,iframe_tag

# List all available patterns (check README.md)

JSON Output

# Output JSON to stdout
./mysql-scanner --host localhost --user user --db mydb --json

# Save JSON to file
./mysql-scanner --host localhost --user user --db mydb --json --output scan-results.json

# Pretty-print JSON with jq
./mysql-scanner --host localhost --user user --db mydb --json | jq '.'

Understanding the Output

Human-Readable Output

Connected to wp_user@localhost:3306/wordpress
Found 12 tables
Scanning table: wp_posts
  Scanning 4 text columns: [post_content post_excerpt post_title post_password]
Scanning table: wp_options
  Scanning 3 text columns: [option_value option_name autoload]

=== SCAN RESULTS ===
Database: wordpress
Tables scanned: 12
Findings: 3 total (High: 1, Medium: 2, Low: 0)

🔴 HIGH RISK (1)

  [high] wp_posts.post_content (ID: 42)
  Pattern: eval_function
  Match: eval(
  Snippet: Some text with <?php eval(base64_decode('SGVsbG8=')); ?> malicious code

🟡 MEDIUM RISK (2)
  ...

JSON Output

{
  "database": "wordpress",
  "tables_scanned": 12,
  "rows_scanned": 3,
  "findings": [
    {
      "table": "wp_posts",
      "column": "post_content",
      "row_id": "42",
      "risk_level": "high",
      "pattern": "eval_function",
      "match": "eval(",
      "snippet": "Some text with <?php eval(base64_decode('SGVsbG8=')); ?>"
    }
  ],
  "high_risk_count": 1,
  "medium_risk_count": 2,
  "low_risk_count": 0
}

Common Use Cases

Incident Response

When you suspect a WordPress compromise:

# Full scan of the database
./mysql-scanner --host localhost --user wp_user --password *** --db wordpress --json > incident-scan.json

# Check only high-risk patterns first
./mysql-scanner --host localhost --user wp_user --password *** --db wordpress --patterns eval,assert,base64_decode,exec,system

Periodic Security Audits

Set up a cron job for automated scanning:

#!/bin/bash
# /usr/local/bin/wordpress-malware-scan.sh

DATE=$(date +%Y-%m-%d)
OUTPUT_DIR="/var/log/malware-scans"
mkdir -p "$OUTPUT_DIR"

for DB in wordpress wordpress_blog wordpress_site2; do
    echo "Scanning $DB..."
    ./mysql-scanner --host localhost --user scanner_user --password *** \
        --db "$DB" --json --output "$OUTPUT_DIR/$DB-$DATE.json"
done

# Email if high-risk findings
HIGH_COUNT=$(jq '.high_risk_count' "$OUTPUT_DIR"/*-$DATE.json | awk '{s+=$1} END {print s}')
if [ "$HIGH_COUNT" -gt 0 ]; then
    echo "ALERT: $HIGH_COUNT high-risk malware findings detected" | \
        mail -s "WordPress Malware Scan Results" admin@example.com
fi

Development Testing

Scan development databases before production deployment:

# Scan staging database
./mysql-scanner --host staging-db.example.com --user dev_user --password *** \
    --db wordpress_staging --patterns script_tag,iframe_tag,javascript_protocol

WordPress-Specific Tables

The scanner automatically handles these common WordPress tables:

  • wp_posts - post_content, post_excerpt, post_title
  • wp_options - option_value (theme options, plugins settings)
  • wp_comments - comment_content
  • wp_commentmeta - meta_value
  • wp_postmeta - meta_value
  • wp_usermeta - meta_value

Troubleshooting

Connection Failed

Error: failed to connect to database: dial tcp 127.0.0.1:3306: connect: connection refused
  • Check that MySQL is running: systemctl status mysql
  • Verify host and port: --host localhost --port 3306
  • Check firewall rules

Access Denied

Error: Access denied for user 'wp_user'@'localhost'
  • Verify username and password
  • Ensure user has SELECT permissions on the database
  • Check host restrictions (localhost vs %)

No Text Columns Found

Some tables may only have numeric columns and will be skipped. This is normal.

Too Many False Positives

Some patterns like eval( may trigger on legitimate content. Use pattern filtering:

# Exclude false-positive patterns
./mysql-scanner --db mydb --patterns base64_decode,script_tag,iframe_tag

Security Best Practices

  1. Never commit scan results to version control - they may contain sensitive data
  2. Use read-only database accounts - Create a dedicated scanner user with SELECT only
  3. Secure scan output files - Set appropriate file permissions (chmod 600)
  4. Rotate scanner credentials - Change passwords regularly
  5. Monitor scan logs - Track who is running scans and when

Creating a Read-Only Scanner User

-- Create a scanner user with minimal permissions
CREATE USER 'scanner'@'localhost' IDENTIFIED BY 'strong_password_here';

-- Grant SELECT on all tables
GRANT SELECT ON wordpress.* TO 'scanner'@'localhost';

-- Flush privileges
FLUSH PRIVILEGES;

-- Verify
SHOW GRANTS FOR 'scanner'@'localhost';