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

Add custom DNS option #1064

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
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Unreleased
- Feature: Add ability to add custom A or CNAME records for internal DNS server using command `config dnsentry <name> <record_type> <value>` e.g. 'www CNAME cloudfront.net.'
- Fixed: Redirection to `redirect_url` on page reload after authorization tokens have been captured.

# 3.3.0
Expand Down
30 changes: 30 additions & 0 deletions core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ type GeneralConfig struct {
Autocert bool `mapstructure:"autocert" json:"autocert" yaml:"autocert"`
}

type DNSEntry struct {
Type string `mapstructure:"type" json:"type" yaml:"type"`
Value string `mapstructure:"value" json:"value" yaml:"value"`
}

type Config struct {
general *GeneralConfig
certificates *CertificatesConfig
Expand All @@ -91,6 +96,7 @@ type Config struct {
lureIds []string
subphishlets []*SubPhishlet
cfg *viper.Viper
dnsentries map[string]*DNSEntry
}

const (
Expand All @@ -102,6 +108,7 @@ const (
CFG_BLACKLIST = "blacklist"
CFG_SUBPHISHLETS = "subphishlets"
CFG_GOPHISH = "gophish"
CFG_DNSENTRIES = "dnsentries"
)

const DEFAULT_UNAUTH_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" // Rick'roll
Expand All @@ -116,6 +123,7 @@ func NewConfig(cfg_dir string, path string) (*Config, error) {
phishletNames: []string{},
lures: []*Lure{},
blacklistConfig: &BlacklistConfig{},
dnsentries: make(map[string]*DNSEntry),
}

c.cfg = viper.New()
Expand Down Expand Up @@ -183,6 +191,7 @@ func NewConfig(cfg_dir string, path string) (*Config, error) {
c.cfg.UnmarshalKey(CFG_PROXY, &c.proxyConfig)
c.cfg.UnmarshalKey(CFG_PHISHLETS, &c.phishletConfig)
c.cfg.UnmarshalKey(CFG_CERTIFICATES, &c.certificates)
c.cfg.UnmarshalKey(CFG_DNSENTRIES, &c.dnsentries)

for i := 0; i < len(c.lures); i++ {
c.lureIds = append(c.lureIds, GenRandomToken())
Expand Down Expand Up @@ -302,6 +311,19 @@ func (c *Config) SetDnsPort(port int) {
c.cfg.WriteConfig()
}

func (c *Config) SetDnsEntry(name string, rtype string, value string) {
rtypes := []string{"A", "CNAME"}
if !stringExists(rtype, rtypes) {
log.Error("invalid record type %s, allowed types are %s", rtype, strings.Join(rtypes, ","))
return
}
entry := &DNSEntry{rtype, value}
c.dnsentries[name] = entry
c.cfg.Set(CFG_DNSENTRIES, c.dnsentries)
log.Info("DNS entry set: %s -> %s: %s", name, rtype, value)
c.cfg.WriteConfig()
}

func (c *Config) EnableProxy(enabled bool) {
c.proxyConfig.Enabled = enabled
c.cfg.Set(CFG_PROXY, c.proxyConfig)
Expand Down Expand Up @@ -823,3 +845,11 @@ func (c *Config) GetGoPhishApiKey() string {
func (c *Config) GetGoPhishInsecureTLS() bool {
return c.gophishConfig.InsecureTLS
}

func (c *Config) GetDnsEntries() string {
out := ""
for k, v := range c.dnsentries {
out += fmt.Sprintf("%s -> %s: %s; ", k, v.Type, v.Value)
}
return out
}
31 changes: 26 additions & 5 deletions core/nameserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,33 @@ func (o *Nameserver) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
log.Debug("DNS SOA: " + fqdn)
m.Answer = append(m.Answer, soa)
case dns.TypeA:
log.Debug("DNS A: " + fqdn + " = " + o.cfg.general.ExternalIpv4)
rr := &dns.A{
Hdr: dns.RR_Header{Name: fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 300},
A: net.ParseIP(o.cfg.general.ExternalIpv4),
val, dnsentry := o.cfg.dnsentries[strings.TrimRight(strings.Replace(fqdn, strings.ToLower(o.cfg.general.Domain), "", -1), ".")]
if dnsentry {
log.Debug("DNS %s: %s = %s (DNSEntry)", val.Type, fqdn, val.Value)
if val.Type == "A" {
rr := &dns.A{
Hdr: dns.RR_Header{Name: fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 300},
A: net.ParseIP(val.Value),
}

m.Answer = append(m.Answer, rr)
} else if val.Type == "CNAME" {
rr := &dns.CNAME{
Hdr: dns.RR_Header{Name: fqdn, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 300},
Target: val.Value,
}

m.Answer = append(m.Answer, rr)
}
} else {
log.Debug("DNS A: " + fqdn + " = " + o.cfg.general.ExternalIpv4)
rr := &dns.A{
Hdr: dns.RR_Header{Name: fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 300},
A: net.ParseIP(o.cfg.general.ExternalIpv4),
}

m.Answer = append(m.Answer, rr)
}
m.Answer = append(m.Answer, rr)
case dns.TypeNS:
log.Debug("DNS NS: " + fqdn)
if fqdn == pdom(o.cfg.general.Domain) {
Expand Down
13 changes: 10 additions & 3 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", "external_ipv4", "bind_ipv4", "https_port", "dns_port", "unauth_url", "autocert", "gophish admin_url", "gophish api_key", "gophish insecure", "dnsentries"}
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, t.cfg.GetDnsEntries()}
log.Printf("\n%s\n", AsRows(keys, vals))
return nil
} else if pn == 2 {
Expand Down Expand Up @@ -269,6 +269,12 @@ func (t *Terminal) handleConfig(args []string) error {
}
}
}
} else if pn == 4 {
switch args[0] {
case "dnsentry":
t.cfg.SetDnsEntry(args[1], args[2], args[3])
return nil
}
}
return fmt.Errorf("invalid syntax: %s", args)
}
Expand Down Expand Up @@ -1161,7 +1167,7 @@ func (t *Terminal) createHelp() {
h, _ := NewHelp()
h.AddCommand("config", "general", "manage general configuration", "Shows values of all configuration variables and allows to change them.", LAYER_TOP,
readline.PcItem("config", readline.PcItem("domain"), readline.PcItem("ipv4", readline.PcItem("external"), readline.PcItem("bind")), readline.PcItem("unauth_url"), readline.PcItem("autocert", readline.PcItem("on"), readline.PcItem("off")),
readline.PcItem("gophish", readline.PcItem("admin_url"), readline.PcItem("api_key"), readline.PcItem("insecure", readline.PcItem("true"), readline.PcItem("false")), readline.PcItem("test"))))
readline.PcItem("gophish", readline.PcItem("admin_url"), readline.PcItem("api_key"), readline.PcItem("insecure", readline.PcItem("true"), readline.PcItem("false")), readline.PcItem("test")), readline.PcItem("dnsentry")))
h.AddSubCommand("config", nil, "", "show all configuration variables")
h.AddSubCommand("config", []string{"domain"}, "domain <domain>", "set base domain for all phishlets (e.g. evilsite.com)")
h.AddSubCommand("config", []string{"ipv4"}, "ipv4 <ipv4_address>", "set ipv4 external address of the current server")
Expand All @@ -1173,6 +1179,7 @@ func (t *Terminal) createHelp() {
h.AddSubCommand("config", []string{"gophish", "api_key"}, "gophish api_key <key>", "set up the api key for the gophish instance to communicate with")
h.AddSubCommand("config", []string{"gophish", "insecure"}, "gophish insecure <true|false>", "enable or disable the verification of gophish tls certificate (set to `true` if using self-signed certificate)")
h.AddSubCommand("config", []string{"gophish", "test"}, "gophish test", "test the gophish configuration")
h.AddSubCommand("config", []string{"dnsentry"}, "dnsentry <name> <record_type> <value>", "provide a DNS entry of type A or CNAME to be returned by the internal resolver e.g. 'www CNAME cloudfront.net.'")

h.AddCommand("proxy", "general", "manage proxy configuration", "Configures proxy which will be used to proxy the connection to remote website", LAYER_TOP,
readline.PcItem("proxy", readline.PcItem("enable"), readline.PcItem("disable"), readline.PcItem("type"), readline.PcItem("address"), readline.PcItem("port"), readline.PcItem("username"), readline.PcItem("password")))
Expand Down