Hardening Gophish: Implementing AES-256-GCM Database Encryption in Anglerphish
嗯,用户让我总结这篇文章的内容,控制在一百个字以内,而且不需要特定的开头。我先快速浏览一下文章,发现主要讲的是Anglerphish在GoPhish的基础上添加了AES-256-GCM加密,保护敏感数据。 文章提到了加密的四个类别:SMTP密码、SMS配置、IMAP密码和事件详情。设计上使用环境变量激活加密,还支持回滚和迁移。这些信息需要简洁地表达出来。 我需要确保总结涵盖主要点:加密技术、保护的数据类型、设计特点以及如何使用。同时要控制在100字以内,所以得精简语言。 可能的结构是先说明Anglerphish添加了什么,然后列出保护的数据类型,接着提到设计上的特点如环境变量和迁移选项。最后强调安全提升但需结合其他措施。 这样组织起来应该能准确传达文章的核心内容。 </think> Anglerphish为GoPhish添加了可选的AES-256-GCM加密功能,保护SMTP、SMS、IMAP密码及捕获的用户数据。加密通过环境变量激活,支持回滚和迁移,提升了数据安全性但需结合服务器安全和密钥管理使用。 2026-4-19 03:12:4 Author: infosecwriteups.com(查看原文) 阅读量:27 收藏

George Petropoulos

Press enter or click to view image in full size

Introduction

One of the key shortcomings in GoPhish is that, aside from user account passwords (which are properly hashed), the rest of the sensitive data is stored in plaintext. If an attacker gains access to the SQLite or MySQL database —whether through a server breach, an exposed backup, or an insider threat — all of this information becomes immediately readable.

This includes SMTP and IMAP credentials, as well as the captured data of simulation targets. In the Anglerphish fork, this also extends to SMS provider API keys.

Anglerphish addresses this by introducing optional application-layer AES-256-GCM encryption for all sensitive fields. This article covers the design, what it protects, how to use it, and a quick deployment checklist.

What Gets Encrypted in Anglerphish

Encryption covers four categories of sensitive data stored in the database:

SMTP (Sending Profiles)

  • password: SMTP server password

SMS (SMS Profiles)

  • provider_config: Twilio Account SID/Auth Token, Vonage API Key/Secret

IMAP Configuration

  • password: IMAP server password

Events

  • details: captured details from phishing targets (not only credentials)

The last category is the most critical. During a phishing simulation, when a target submits their credentials on a landing page, those credentials end up in the events table (along with other metadata like IP addresses). Without encryption, anyone with database access can view all captured information in plaintext.

Design Decisions

Why AES-256-GCM?

AES-256-GCM provides both confidentiality and integrity (authenticated encryption) and is widely considered a modern standard. It is natively supported by Go’s standard library, requiring no external dependencies. It is also highly performant, making encryption and decryption effectively negligible for small data such as credentials and API keys. However, it must be used carefully, particularly with regard to nonce uniqueness.

Each encrypted value uses a unique nonce, stored alongside the ciphertext.

Opt-In via Environment Variable

Encryption is activated by setting a single environment variable:

ANGLERPHISH_ENCRYPTION_KEY=<your-base64url-encoded-key>

If the variable isn’t set, the application works exactly as before — plaintext in, plaintext out. No breaking changes, no forced migrations. This was a deliberate choice: encryption should enhance security without disrupting existing deployments.

Versioned Encrypted Format

Every encrypted value is stored with a recognizable prefix:

ENC:v1:<base64 nonce>:<base64 ciphertext>

This gives us several advantages:

  • Detection — The system can immediately determine whether a value is encrypted or plaintext by checking for the ENC:v1: prefix.
  • Coexistence — Encrypted and plaintext values can exist side-by-side during gradual migration.
  • Future-proofing — New formats (e.g., ENC:v2:) can be introduced without breaking existing data.

Transparent to the Application

Encryption and decryption happen automatically through database hooks. When a record is saved, sensitive fields are encrypted on the fly. When a record is read, they're decrypted transparently. The rest of the codebase — controllers, API handlers, templates — never needs to know encryption exists.

Failure Handling

The system prioritizes availability over strict enforcement. If encryption fails, the data is written in plaintext and a warning is logged, rather than crashing the application. Similarly, if decryption fails (e.g., due to a missing or incorrect key), the system logs a warning and returns the stored value without modification.

Get George Petropoulos’s stories in your inbox

Join Medium for free to get updates from this writer.

Remember me for faster sign in

This is a deliberate tradeoff: in an operational phishing simulation, a hard failure at runtime may be more disruptive than temporarily storing a value unencrypted.

Backward Compatibility

One of the core design goals was zero disruption for existing users:

  • No encryption key set → Application behaves exactly as before (plaintext everywhere)
  • Key set, but data is plaintext → Values are returned as-is (no prefix detected)
  • Key set, data is encrypted → Data is decrypted normally
  • Already-encrypted value saved again → Detected via prefix and not re-encrypted
  • Wrong key for encrypted data → Decryption fails gracefully; application continues running
  • Mixed encrypted/plaintext data → Fully supported; each value is handled independently

This means you can enable encryption at any time, migrate gradually, and even reverse the migration if needed. There’s no point of no return.

How to Use Database Encryption

Step 1: Generate an Encryption Key

./gophish --generate-encryption-key

# Output:
# ANGLERPHISH_ENCRYPTION_KEY=BaekNXL8PWAcGT4k9MTmKrBAqilaMaTJ4eHET565aHM=

Save this key securely — and be sure not to lose it!

Step 2: Set the Environment Variable

# Linux/Mac
export ANGLERPHISH_ENCRYPTION_KEY=BaekNXL8PWAcGT4k9MTmKrBAqilaMaTJ4eHET565aHM=

# Windows CMD
set ANGLERPHISH_ENCRYPTION_KEY=BaekNXL8PWAcGT4k9MTmKrBAqilaMaTJ4eHET565aHM=

# Windows PowerShell
$env:ANGLERPHISH_ENCRYPTION_KEY="BaekNXL8PWAcGT4k9MTmKrBAqilaMaTJ4eHET565aHM="

Step 3: Migrate Existing Data

If you have an existing database with plaintext fields, migrate them to an encrypted state:

./gophish --migrate-encryption

# Output:
# Migrating plaintext fields to encrypted...
# SMTP passwords: 5 encrypted, 0 skipped
# SMS provider configs: 3 encrypted, 0 skipped
# IMAP passwords: 2 encrypted, 0 skipped
# Event details (captured data): 12 encrypted, 0 skipped
# Migration complete!

Note 1: Encrypted data can coexist with plaintext. If this step is skipped, only newly created or updated data will be encrypted, while existing data will remain in plaintext.

Note 2: The events table also includes entries such as Email Sent and Campaign Created. These entries do not contain sensitive details, which is why they appear as skipped in the screenshot.

Step 4: Run Normally

./gophish

# Output includes: "Database encryption is enabled"

Press enter or click to view image in full size

From this point on, all new data is automatically encrypted when saved and decrypted when read. No configuration changes needed beyond the environment variable.

Available Commands

Anglerphish provides a set of CLI commands for managing encryption. Below is a quick reference:

# ============ KEY MANAGEMENT ============
./gophish --generate-encryption-key
# Outputs: ANGLERPHISH_ENCRYPTION_KEY=BaekNXL8P...

# ============ MIGRATION ============
./gophish --migrate-encryption # Encrypt all plaintext fields
./gophish --migrate-decryption # Reverse - decrypt back to plaintext
./gophish --migrate-encryption --dry-run # Preview without changes
./gophish --migrate-decryption --dry-run # Preview without changes

# ============ STATUS ============
./gophish --encryption-status
# Shows: Encryption Enabled: Yes/No
# SMTP Passwords: 5 encrypted, 2 plaintext
# SMS Configs: 3 encrypted, 0 plaintext
# IMAP Passwords: 1 encrypted, 1 plaintext
# Event Details: 12 encrypted, 0 plaintext

# ============ NORMAL OPERATION ============
./gophish
# Runs normally - encryption auto-detected from env var

Deployment Checklist

Before deploying encryption in production, follow this indicative checklist:

Enable Encryption

When using environment variables, the encryption key must be set on every restart unless persisted. If Anglerphish starts without the encryption key and finds encrypted values in the database, read operations on those fields will fail gracefully — the application will continue running but sensitive fields will be unreadable until the key is restored.

Example in Linux/Mac:

# 1. BACKUP YOUR DATABASE FIRST!
cp gophish.db gophish.db.backup

# 2. Generate a strong encryption key
./gophish --generate-encryption-key
# Save this key securely — DON'T LOSE IT!

# 3. Set the encryption key
export ANGLERPHISH_ENCRYPTION_KEY="your-generated-key"

# 4. Preview what will be encrypted (no changes made)
./gophish --migrate-encryption --dry-run

# 5. Run the actual migration
./gophish --migrate-encryption

# 6. Verify the migration worked
./gophish --encryption-status

Note: Avoid setting sensitive values directly in the shell when possible, as they may be recorded in shell history. Prefer using environment files or secret management systems in production.

Persisting the Key

Store the encryption key in a dedicated environment file with root-only access — this keeps the key out of config files, command history, and source control, while ensuring it persists across reboots.

Linux (systemd service):

# Create a secure secrets file
sudo mkdir -p /etc/anglerphish
echo "ANGLERPHISH_ENCRYPTION_KEY=your-generated-key" | sudo tee /etc/anglerphish/secrets.env
sudo chmod 600 /etc/anglerphish/secrets.env
sudo chown root:root /etc/anglerphish/secrets.env
# /etc/systemd/system/anglerphish.service
[Service]
EnvironmentFile=/etc/anglerphish/secrets.env
ExecStart=/opt/anglerphish/gophish

⚠️ NEVER LOSE THE ENCRYPTION KEY! ⚠️

If the encryption key is lost, all encrypted data becomes permanently unrecoverable.

Conclusion

Application-layer encryption in Anglerphish closes a gap that GoPhish originally left open: data at rest was only as secure as the database file itself. Adding optional AES-256-GCM changes that. Even if someone gets hold of a backup or a raw database dump, the sensitive data inside it is no longer immediately usable.

That said, this doesn’t solve security on its own.

If an attacker has access to the running server, or your keys are poorly managed, encryption won’t save you. It simply raises the bar for a specific class of attack — offline access to stolen data.

Think of it as containment, not prevention.

Used properly, this layer makes database exposure far less damaging. But it still depends on the basics: locked-down servers, controlled access, and careful handling of encryption keys.


文章来源: https://infosecwriteups.com/hardening-gophish-implementing-aes-256-gcm-database-encryption-in-anglerphish-735617ec8849?source=rss----7b722bfd1b8d---4
如有侵权请联系:admin#unsafe.sh