Browse Classifications
- All Resources
- Strategic Content
- Technical Content
- Ahead of the Breach Podcast Content
- Partner Program Content
A must read if you plan to use GoPhish in your methodology
I’m going to quickly go through the process of setting up GoPhish and show you how we evade defenders to increase the success rate of our phishing campaigns.
Phishing is getting harder and harder. Landing in a user’s inbox, creating the pretext, and setting up your infrastructure in a way that doesn’t get you caught isn’t as easy as it used to be.
We want to build infrastructure that’s long-lasting, blocks security solutions, and appears legitimate to users. That’s a huge task. So, let’s start by focusing on the tool almost all of us use for phishing engagements: GoPhish.
We’ll review how to:
Believe it or not, out of the box, Gophish will tip your hand to security controls and defenders by design. Several aspects of the tool reveal to security controls that emails a user received came from a Gophish server. On top of this, the phishing site your users visit further reveals your intentions. It does so using easily fingerprinted HTTP headers and 404 pages.
Let’s start by looking at the GoPhish source code. If you grep the source code for the value X-GoPhish, you will be greeted with the following:
As you can see, email sending utilities within the project append the header listed below to your emails when they go out:
This is a big no-no, as it allows security controls to fingerprint your email as malicious easily. With that, we need to change this header to look a little more normal. The easiest way to do this on the fly is to run the following command in the root directory of a freshly cloned GoPhish repository:
find . -type f -exec sed -i.bak 's/X-Gophish-Contact/X-Contact/g' {} +
find . -type f -exec sed -i.bak 's/X-Gophish-Signature/X-Signature/g' {} +
We still have a couple more changes to make before we can continue. In the file config.go there is a Server variable set to “gophish” out of the box. This is shown in the screenshot below:
So what is the best way to change this? We don’t want to spoof any mail client or server because it might tip our hand (Trust me on this!). So instead, let’s opt to set the value to IGNORE.
This comes courtesy of the great ired.team blog article linked below:
I did this using vim, but you can also use sed to get the job done.
We need to also change the 404 page displayed to users when they don’t have a valid URL sent during our campaign. We can additionally make changes to the response headers returned when visiting the phishing site itself. This is optional, as we should use a reverse proxy to shield our phishing infrastructure.
Why are we doing this? A great article on the Insomniac blog about fingerprinting GoPhish servers spells it out wonderfully. One of the best ways for catching a live GoPhish instance is the 404 page and headers sent along with it. They’re fairly unique in combination. You can read more using the link below:
Making this change is a little more difficult than you would expect. I was inspired to flesh this out after reading edermi’s article on modding GoPhish and seeing some of the challenges that exist. Edermi already did the groundwork needed to add a custom 404 page to GoPhish. With this, we can simply import their changes right into our modified version of the tool. Please see the article below for some more context.
In the referenced article, edermi does all the heavy lifting for us. To make this simple, replace the phish.go file in your base GoPhish repository with the file linked below.
Once you’ve copied the version of the file created by edermi to your repository, create a custom 404 page in the template directory at the root of your GoPhish repository. For example, this is my current 404.html file.
Modify this page to fit your pretext and headers.
You may want to make some additional changes based on your use case. For example, modifying the headers returned by the server is easy by making additions to the code on line 86 of the phish.go file you just added to the repository. This is my current setup:
Note that you should use a reverse proxy in front of your GoPhish server, regardless. Only really make this change as an extra precaution or as needed.
Every phishing link you send includes an easily identifiable uncommon parameter in the URL. The link is used to track clicks during your campaign. An example of a URL sent to users in phishing emails is listed below:
https://phish.acme.com/rid?=12345
That rid
parameter screams GoPhish and is so easy to flag on. Changing this is simple. In the file, campaign.go
in the GoPhish repository, the parameter is defined on line 130. Change it to something benign that’s common in marketing emails. Use the following command to make the change:
sed -i 's/const RecipientParameter = "rid"/const RecipientParameter = "keyname"/g' models/campaign.go
We opted to use the variable keyname
here, but you can use whatever you want. Your links will now include the keyname variable as opposed to rid.
https://phish.acme.com/?keyname=12345
So what did we change to avoid security controls?
These changes aren’t going to bypass everything, but they’ll go a long way in getting your phishing email into a user’s inbox.
This is all awesome, but we pentesters want to make this process much faster. So let’s automate the process. Luckily, I have a new repository available on GitHub that builds a Docker image with all these changes built right in.
Do the following to get the repository up and running:
Clone the repository and build the container
git clone https://github.com/puzzlepeaches/sneaky_gophish && \
cd sneaky_gophish && \
docker build -t sneaky_gophish .
Run the container with the following command
docker run -itd --name sneaky_gophish -p 3333:3333 -p 8080:8080 sneaky_gophish
Get the admin password
docker logs sneaky_gophish | grep password
So what does this Dockerfile actually do? It’s nearly identical to the upstream GoPhish repository with all the changes listed above included – before the compilation of the GoPhish binary. The core of these changes starts around line 48 in the Dockerfile.
# Stripping X-Gophish
USER root
RUN sed -i 's/X-Gophish-Contact/X-Contact/g' models/email_request_test.go
RUN sed -i 's/X-Gophish-Contact/X-Contact/g' models/maillog.go
RUN sed -i 's/X-Gophish-Contact/X-Contact/g' models/maillog_test.go
RUN sed -i 's/X-Gophish-Contact/X-Contact/g' models/email_request.go
# Stripping X-Gophish-Signature
RUN sed -i 's/X-Gophish-Signature/X-Signature/g' webhook/webhook.go
# Changing server name
RUN sed -i 's/const ServerName = "gophish"/const ServerName = "IGNORE"/' config/config.go
# Changing rid value
RUN sed -i 's/const RecipientParameter = "rid"/const RecipientParameter = "keyname"/g' models/campaign.go
I have some additional caveats listed in the GitHub repository. They’re also listed below:
The container I built isn’t the miracle cure for evasion, but it’s a good start. It’s a bad idea to use any of your tooling out of the box. You’ve heard this before, but I want to reiterate how important it is to understand how your tools work.
The GoPhish authors include indicators to weed out unsophisticated attackers only trying to steal someone’s Netflix password. That isn’t the level of value we should show our clients. Highly skilled attackers are making these changes, and they’re the ones your customers need to worry about.
You can make additional changes to evade controls and also make your phishing campaigns easier to deploy. This is an exercise for the reader, however.
Pull requests to the repository I created are welcome. The core of changes made are fairly simple and could easily be expanded upon and made a bit more dynamic to continue working after changes have been made to the upstream GitHub repository.
Continuous Human & Automated Security
Continuously monitor your attack surface with advanced change detection. Upon change, testers and systems perform security testing. You are alerted and assisted in remediation efforts all contained in a single security application, the Sprocket Platform.