GoPhish Lab: Simulating a Phishing Campaign End-to-End
Setting up GoPhish, crafting convincing lure emails, building credential-capture landing pages, and what the data tells you about human vulnerability.
Scope: This is the walkthrough from my own lab, run against mailboxes I control. GoPhish is for authorised simulations only on infrastructure you own or have explicit written permission to test — never send phishing to people without consent.
Phishing is the most reliable initial-access vector there is, so if you want to understand it — offensively or defensively — you need to run it in a controlled environment and see the actual numbers. GoPhish is the standard open-source framework for that: it handles senders, target groups, email templates, landing pages, and tracking, and it gives you a dashboard that shows exactly how people respond.
I ran this entirely on Kali, against mailboxes I control. Here's how the pieces fit together.
What You Need
Before touching GoPhish, line up the plumbing:
- →A domain you own. Don't use your real primary domain — that defeats the realism. Buy a lookalike or throwaway registered to your lab.
- →A sending IP that isn't blacklisted. Residential IPs and most cloud ranges go straight to spam. This is the single biggest reason simulations fail.
- →An SMTP relay. Brevo, AWS SES, or SendGrid handle reputation so your mail actually lands. GoPhish connects to it as a smart host.
- →DNS records on the sending domain: SPF, DKIM, DMARC — the same trio from my mail-server post. If you skip these, everything you send is flagged and your results are meaningless.
If the sending infrastructure is weak, the campaign data tells you about your IP reputation, not human behaviour. Get delivery right first.
Deploying GoPhish on Kali
Grab the latest release from the GitHub page rather than trusting an APT package, so you're on a current build:
cd ~/Downloads
tar -xzf gophish-vX.X-linux-64bit.tar.gz
sudo mv gophish /opt/
cd /opt/gophish
The admin UI runs over HTTPS with a self-signed cert generated on first launch. The included gophish.json controls the bind address and the phishing server URL:
{
"admin_server": { "listen_url": "0.0.0.0:3333", "tls_cert": "gophish.crt" },
"phish_server": { "listen_url": "0.0.0.0:80" }
}
Start it and open the admin interface on port 3333:
sudo ./gophish
# admin UI: https://localhost:3333 (password is printed to stdout on first run)
The Moving Parts
GoPhish composes a campaign out of five things. Understanding the model is most of the work.
- →SMTP Status / Sending Profile — how mail leaves: relay host, port, username, password, and the "From" address.
- →Users & Groups — your targets. In a lab, that's mailboxes you own.
- →Landing Pages — the page a victim lands on, usually a cloned login form that captures submissions.
- →Email Templates — the lure. GoPhish injects tracking pixels and links automatically.
- →Campaigns — binds the four above together and launches.
Step 1: Sending Profile
In the UI, New Profile → set the interface (your sending domain), the relay's host and port (587 with STARTTLS for most providers), and SMTP credentials. Hit Send Test Email — GoPhish gives a clear pass/fail and the raw SMTP conversation on failure, which is where you'll debug most of your delivery issues.
Step 2: The Landing Page
The fastest route is Clone Site: give it a URL and GoPhish fetches the HTML. That rarely captures POSTed credentials, because the original form submits to the real server. You edit the captured HTML so the form posts to GoPhish's capture handler instead:
<form method="POST" action="/submit?{{ .GUID }}">
<input type="hidden" name="data" value="{{ .Rhost }} {{ .Rtime }}" />
<input type="text" name="username" />
<input type="password" name="password" />
</form>
The {{ .GUID }} is the tracking token GoPhish stamps on every link — it's how a credential submission gets tied back to a specific target. After capture, set a Redirect URL pointing at the genuine site so the victim lands somewhere normal and doesn't notice.
Step 3: The Email Template
Templates use GoTemplate variables — {{ .Email.FirstName }}, {{ .BaseURL }} — so each send is personalised. Two things GoPhish handles for you and you should understand anyway:
- →A tracking pixel is auto-added to measure opens.
- →Every link is rewritten through
{{ .BaseURL }}so clicks route through your GoPhish server and get recorded.
Make the single-target link red in the preview (there's a checkbox) so you can eyeball where it actually points.
Step 4: Launch and What the Data Shows
A campaign moves each target through a lifecycle: email sent → opened → clicked → data submitted → reported. Watch those stages convert in the dashboard.
The interesting part is that success rate is almost entirely a function of message design, not the technical plumbing. Urgency ("your password expires today"), correct branding, and a plausible sender move the numbers far more than anything on the server side.
My lab run — 45 targets, all mailboxes I control — came out like this:
| Stage | Count | Rate |
|---|---|---|
| Email sent | 45 | 100% |
| Opened | 33 | 73.3% |
| Clicked | 28 | 62.2% |
| Data submitted | 24 | 53.3% |
| Reported | 0 | 0% |
Defensive Takeaways
- →Check the sending domain, not the display name. The "From" label is free text; the actual
MAIL FROMand DKIMd=domain are the truth — which is exactly what SPF/DKIM/DMARC exist to expose. - →Hover before clicking. The rewritten
{{ .BaseURL }}link is the tell in a real attack. - →A submission is a breach. If the landing page looked like a real login and credentials hit an unfamiliar server, the protocol is: change the password from a known-good device, then check for active sessions.
What I Learned
A 53% credential-submission rate against a plausible login page is uncomfortable — and that's with a self-aware audience in a lab. It's tempting to think "no one would click that"; the dashboard says otherwise. The infrastructure gets your mail delivered; the content gets your click and the submission.