Skip to content

Commit 4a65e39

Browse files
author
Michael Eder
committed
Add custom 404 support
1 parent db63ee9 commit 4a65e39

File tree

3 files changed

+55
-69
lines changed

3 files changed

+55
-69
lines changed

README.md

Lines changed: 11 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,17 @@
1-
![gophish logo](https://raw.github.com/gophish/gophish/master/static/images/gophish_purple.png)
1+
# Gophish
22

3-
Gophish
4-
=======
3+
edermi's custom gophish fork.
4+
Don't expect this one to work for you.
5+
Please don't open issues, I'll ignore / close them.
6+
If you decide to use this, you're on your own.
57

6-
![Build Status](https://github.com/gophish/gophish/workflows/CI/badge.svg) [![GoDoc](https://godoc.org/github.com/gophish/gophish?status.svg)](https://godoc.org/github.com/gophish/gophish)
8+
## Changes compared to vanilla gophish
79

8-
Gophish: Open-Source Phishing Toolkit
10+
### Custom error page templating for 404 error pages in phishing handler
911

10-
[Gophish](https://getgophish.com) is an open-source phishing toolkit designed for businesses and penetration testers. It provides the ability to quickly and easily setup and execute phishing engagements and security awareness training.
12+
Allows to show a more benign 404 page. Also may be used for redirecting with some Javascript: `<script>window.location.replace("https://target.fqdn");</script>`
1113

12-
### Install
14+
Changes made:
15+
- Add `templates/404.html`
16+
- In `controllers/phish.go`, add custom replacements for `http.NotFound` and `http.Error`
1317

14-
Installation of Gophish is dead-simple - just download and extract the zip containing the [release for your system](https://github.com/gophish/gophish/releases/), and run the binary. Gophish has binary releases for Windows, Mac, and Linux platforms.
15-
16-
### Building From Source
17-
**If you are building from source, please note that Gophish requires Go v1.10 or above!**
18-
19-
To build Gophish from source, simply run ```go get github.com/gophish/gophish``` and ```cd``` into the project source directory. Then, run ```go build```. After this, you should have a binary called ```gophish``` in the current directory.
20-
21-
### Docker
22-
You can also use Gophish via the official Docker container [here](https://hub.docker.com/r/gophish/gophish/).
23-
24-
### Setup
25-
After running the Gophish binary, open an Internet browser to https://localhost:3333 and login with the default username and password listed in the log output.
26-
e.g.
27-
```
28-
time="2020-07-29T01:24:08Z" level=info msg="Please login with the username admin and the password 4304d5255378177d"
29-
```
30-
31-
Releases of Gophish prior to v0.10.1 have a default username of `admin` and password of `gophish`.
32-
33-
### Documentation
34-
35-
Documentation can be found on our [site](http://getgophish.com/documentation). Find something missing? Let us know by filing an issue!
36-
37-
### Issues
38-
39-
Find a bug? Want more features? Find something missing in the documentation? Let us know! Please don't hesitate to [file an issue](https://github.com/gophish/gophish/issues/new) and we'll get right on it.
40-
41-
### License
42-
```
43-
Gophish - Open-Source Phishing Framework
44-
45-
The MIT License (MIT)
46-
47-
Copyright (c) 2013 - 2020 Jordan Wright
48-
49-
Permission is hereby granted, free of charge, to any person obtaining a copy
50-
of this software ("Gophish Community Edition") and associated documentation files (the "Software"), to deal
51-
in the Software without restriction, including without limitation the rights
52-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
53-
copies of the Software, and to permit persons to whom the Software is
54-
furnished to do so, subject to the following conditions:
55-
56-
The above copyright notice and this permission notice shall be included in
57-
all copies or substantial portions of the Software.
58-
59-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65-
THE SOFTWARE.
66-
```

controllers/phish.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package controllers
22

33
import (
4+
"bytes"
45
"compress/gzip"
56
"context"
67
"errors"
78
"fmt"
9+
"html/template"
810
"net"
911
"net/http"
1012
"strings"
@@ -81,6 +83,32 @@ func WithContactAddress(addr string) PhishingServerOption {
8183
}
8284
}
8385

86+
// Overwrite net.https Error with a custom one to set our own headers
87+
// Go's internal Error func returns text/plain so browser's won't render the html
88+
func customError(w http.ResponseWriter, error string, code int) {
89+
w.Header().Set("Content-Type", "text/html; charset=utf-8")
90+
w.Header().Set("X-Content-Type-Options", "nosniff")
91+
w.WriteHeader(code)
92+
fmt.Fprintln(w, error)
93+
}
94+
95+
// Overwrite go's internal not found to allow templating the not found page
96+
// The templating string is currently not passed in, therefore there is no templating yet
97+
// If I need it in the future, it's a 5 minute change...
98+
func customNotFound(w http.ResponseWriter, r *http.Request) {
99+
tmpl404, err := template.ParseFiles("templates/404.html")
100+
if err != nil {
101+
log.Fatal(err)
102+
}
103+
var b bytes.Buffer
104+
err = tmpl404.Execute(&b, "")
105+
if err != nil {
106+
http.NotFound(w, r)
107+
return
108+
}
109+
customError(w, b.String(), http.StatusNotFound)
110+
}
111+
84112
// Start launches the phishing server, listening on the configured address.
85113
func (ps *PhishingServer) Start() {
86114
if ps.config.UseTLS {
@@ -138,7 +166,7 @@ func (ps *PhishingServer) TrackHandler(w http.ResponseWriter, r *http.Request) {
138166
if err != ErrInvalidRequest && err != ErrCampaignComplete {
139167
log.Error(err)
140168
}
141-
http.NotFound(w, r)
169+
customNotFound(w, r)
142170
return
143171
}
144172
// Check for a preview
@@ -172,7 +200,7 @@ func (ps *PhishingServer) ReportHandler(w http.ResponseWriter, r *http.Request)
172200
if err != ErrInvalidRequest && err != ErrCampaignComplete {
173201
log.Error(err)
174202
}
175-
http.NotFound(w, r)
203+
customNotFound(w, r)
176204
return
177205
}
178206
// Check for a preview
@@ -206,7 +234,7 @@ func (ps *PhishingServer) PhishHandler(w http.ResponseWriter, r *http.Request) {
206234
if err != ErrInvalidRequest && err != ErrCampaignComplete {
207235
log.Error(err)
208236
}
209-
http.NotFound(w, r)
237+
customNotFound(w, r)
210238
return
211239
}
212240
w.Header().Set("X-Server", config.ServerName) // Useful for checking if this is a GoPhish server (e.g. for campaign reporting plugins)
@@ -216,13 +244,13 @@ func (ps *PhishingServer) PhishHandler(w http.ResponseWriter, r *http.Request) {
216244
ptx, err = models.NewPhishingTemplateContext(&preview, preview.BaseRecipient, preview.RId)
217245
if err != nil {
218246
log.Error(err)
219-
http.NotFound(w, r)
247+
customNotFound(w, r)
220248
return
221249
}
222250
p, err := models.GetPage(preview.PageId, preview.UserId)
223251
if err != nil {
224252
log.Error(err)
225-
http.NotFound(w, r)
253+
customNotFound(w, r)
226254
return
227255
}
228256
renderPhishResponse(w, r, ptx, p)
@@ -242,7 +270,7 @@ func (ps *PhishingServer) PhishHandler(w http.ResponseWriter, r *http.Request) {
242270
p, err := models.GetPage(c.PageId, c.UserId)
243271
if err != nil {
244272
log.Error(err)
245-
http.NotFound(w, r)
273+
customNotFound(w, r)
246274
return
247275
}
248276
switch {
@@ -260,7 +288,7 @@ func (ps *PhishingServer) PhishHandler(w http.ResponseWriter, r *http.Request) {
260288
ptx, err = models.NewPhishingTemplateContext(&c, rs.BaseRecipient, rs.RId)
261289
if err != nil {
262290
log.Error(err)
263-
http.NotFound(w, r)
291+
customNotFound(w, r)
264292
}
265293
renderPhishResponse(w, r, ptx, p)
266294
}
@@ -276,7 +304,7 @@ func renderPhishResponse(w http.ResponseWriter, r *http.Request, ptx models.Phis
276304
redirectURL, err := models.ExecuteTemplate(p.RedirectURL, ptx)
277305
if err != nil {
278306
log.Error(err)
279-
http.NotFound(w, r)
307+
customNotFound(w, r)
280308
return
281309
}
282310
http.Redirect(w, r, redirectURL, http.StatusFound)
@@ -287,7 +315,7 @@ func renderPhishResponse(w http.ResponseWriter, r *http.Request, ptx models.Phis
287315
html, err := models.ExecuteTemplate(p.HTML, ptx)
288316
if err != nil {
289317
log.Error(err)
290-
http.NotFound(w, r)
318+
customNotFound(w, r)
291319
return
292320
}
293321
w.Write([]byte(html))

templates/404.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<html>
2+
<head><title>404 Not Found</title></head>
3+
<body>
4+
<center><h1>404 Not Found</h1></center>
5+
<hr><center>nginx</center>
6+
</body>
7+
</html>

0 commit comments

Comments
 (0)