diff --git a/README.md b/README.md index 1a2791c8..8e604633 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,61 @@ function onResponse(req, res) { } ``` +#### caplets/airmon.cap + +Put a wifi interface in monitor mode and listen for frames in order to detect WiF access points and clients. + +``` +set $ {by}{fw}{env.iface.name}{reset} {bold}» {reset} +set ticker.commands clear; wifi.show + +# uncomment to disable channel hopping +# set wifi.recon.channel 1 + +wifi.recon on +ticker on +events.clear +clear +``` + +#### caplets/wpa\_handshake.cap + +Use various modules to inject wifi frames performing a deauthentication attack, while a sniffer is waiting for WPA handshakes. + +``` +# swag prompt for wifi +set $ {by}{fw}{env.iface.name}{reset} {bold}» {reset} + +# Sniff EAPOL frames ( WPA handshakes ) and save them to a pcap file. +set net.sniff.verbose true +set net.sniff.filter ether proto 0x888e +set net.sniff.output wpa.pcap +net.sniff on + +# since we need to capture the handshake, we can't hop +# through channels but we need to stick to the one we're +# interested in otherwise the sniffer might lose packets. +set wifi.recon.channel 1 + +wifi.recon on + +# uncomment to recon clients of a specific AP given its BSSID +# wifi.recon DE:AD:BE:EF:DE:AD + +events.clear +clear + +# now just deauth clients and wait ^_^ +# +# Example: +# +# wifi.deauth AP-BSSID-HERE +# +# This will deauth every client for this specific access point, +# you can put it as ticker.commands to have the ticker module +# periodically deauth clients :D +``` + ## License `bettercap` and `bettercap-ng` are made with ♥ by [Simone Margaritelli](https://www.evilsocket.net/) and they're released under the GPL 3 license. diff --git a/caplets/airodump.cap b/caplets/airodump.cap index 7a9bd1c5..c613d52a 100644 --- a/caplets/airodump.cap +++ b/caplets/airodump.cap @@ -1,3 +1,6 @@ +# let's add some api :D +include caplets/rest-api.cap + set $ {by}{fw}{env.iface.name}{reset} {bold}» {reset} set ticker.commands clear; wifi.show diff --git a/caplets/wpa_handshake.cap b/caplets/wpa_handshake.cap index b5095006..0c5bbcaa 100644 --- a/caplets/wpa_handshake.cap +++ b/caplets/wpa_handshake.cap @@ -12,7 +12,10 @@ net.sniff on # interested in otherwise the sniffer might lose packets. set wifi.recon.channel 1 +# this will enable the wifi recon +set ticker.commands clear; wifi.show wifi.recon on +ticker on # uncomment to recon clients of a specific AP given its BSSID # wifi.recon DE:AD:BE:EF:DE:AD @@ -29,3 +32,7 @@ clear # This will deauth every client for this specific access point, # you can put it as ticker.commands to have the ticker module # periodically deauth clients :D +# +# For more options `help wifi.recon`. + + diff --git a/firewall/firewall_darwin.go b/firewall/firewall_darwin.go index 6f77bd7d..d141bad3 100644 --- a/firewall/firewall_darwin.go +++ b/firewall/firewall_darwin.go @@ -22,6 +22,7 @@ type PfFirewall struct { iface *network.Endpoint filename string forwarding bool + enabled bool } func Make(iface *network.Endpoint) FirewallManager { @@ -29,6 +30,7 @@ func Make(iface *network.Endpoint) FirewallManager { iface: iface, filename: pfFilePath, forwarding: false, + enabled: false, } firewall.forwarding = firewall.IsForwardingEnabled() @@ -108,7 +110,8 @@ func (f PfFirewall) generateRule(r *Redirection) string { r.Interface, r.Protocol, src_a, r.SrcPort, dst_a, r.DstPort) } -func (f PfFirewall) enable(enabled bool) { +func (f *PfFirewall) enable(enabled bool) { + f.enabled = enabled if enabled { core.Exec("pfctl", []string{"-e"}) } else { @@ -165,11 +168,9 @@ func (f PfFirewall) EnableRedirection(r *Redirection, enabled bool) error { } func (f PfFirewall) Restore() { - err := f.EnableForwarding(f.forwarding) - if err != nil { - fmt.Fprintf(os.Stderr, "%s", err) + f.EnableForwarding(f.forwarding) + if f.enabled { + f.enable(false) } - - f.enable(false) os.Remove(f.filename) } diff --git a/modules/api_rest_utils.go b/modules/api_rest_utils.go index c87ee08e..fc280664 100644 --- a/modules/api_rest_utils.go +++ b/modules/api_rest_utils.go @@ -19,9 +19,6 @@ type APIResponse struct { func SafeBind(c *gin.Context, obj interface{}) error { decoder := json.NewDecoder(io.LimitReader(c.Request.Body, 100*1024)) - if binding.EnableDecoderUseNumber { - decoder.UseNumber() - } if err := decoder.Decode(obj); err != nil { return err } diff --git a/modules/dhcp6_spoof.go b/modules/dhcp6_spoof.go index 489cd6ea..de18273e 100644 --- a/modules/dhcp6_spoof.go +++ b/modules/dhcp6_spoof.go @@ -154,8 +154,8 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet, } var ip net.IP - if t, found := s.Session.Lan.Hosts[target.String()]; found == true { - ip = t.IP + if h, found := s.Session.Lan.Get(target.String()); found == true { + ip = h.IP } else { log.Warning("Address %s not known, using random identity association address.", target.String()) rand.Read(ip) @@ -312,8 +312,8 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P addr = net.IP(raw[0]) } - if t, found := s.Session.Lan.Hosts[target.String()]; found == true { - log.Info("[%s] IPv6 address %s is now assigned to %s", core.Green("dhcp6"), addr.String(), t) + if h, found := s.Session.Lan.Get(target.String()); found == true { + log.Info("[%s] IPv6 address %s is now assigned to %s", core.Green("dhcp6"), addr.String(), h) } else { log.Info("[%s] IPv6 address %s is now assigned to %s", core.Green("dhcp6"), addr.String(), target) } diff --git a/modules/dns_spoof.go b/modules/dns_spoof.go index 54cfd43a..c10db635 100644 --- a/modules/dns_spoof.go +++ b/modules/dns_spoof.go @@ -111,7 +111,7 @@ func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp * redir := fmt.Sprintf("(->%s)", s.Address) who := target.String() - if t, found := s.Session.Lan.Hosts[target.String()]; found == true { + if t, found := s.Session.Lan.Get(target.String()); found == true { who = t.String() } diff --git a/modules/events_view.go b/modules/events_view.go index d8d40d7c..ba6aa677 100644 --- a/modules/events_view.go +++ b/modules/events_view.go @@ -19,6 +19,33 @@ func (s EventsStream) viewLogEvent(e session.Event) { e.Data.(session.LogMessage).Message) } +func (s EventsStream) viewStationEvent(e session.Event) { + st := e.Data.(*network.Station) + vend := "" + if st.Vendor != "" { + vend = fmt.Sprintf(" (%s)", st.Vendor) + } + + if e.Tag == "wifi.station.new" { + fmt.Printf("[%s] WiFi station %s detected as %s%s.\n", + e.Time.Format(eventTimeFormat), + core.Bold(st.ESSID()), + core.Green(st.BSSID()), + vend) + } else if e.Tag == "wifi.station.lost" { + fmt.Printf("[%s] WiFi station %s (%s) lost.\n", + e.Time.Format(eventTimeFormat), + core.Red(st.ESSID()), + st.BSSID()) + } else { + fmt.Printf("[%s] [%s] %s\n", + e.Time.Format(eventTimeFormat), + core.Green(e.Tag), + st) + } + +} + func (s EventsStream) viewEndpointEvent(e session.Event) { t := e.Data.(*network.Endpoint) vend := "" @@ -74,6 +101,8 @@ func (s *EventsStream) View(e session.Event, refresh bool) { s.viewLogEvent(e) } else if strings.HasPrefix(e.Tag, "endpoint.") { s.viewEndpointEvent(e) + } else if strings.HasPrefix(e.Tag, "wifi.station.") { + s.viewStationEvent(e) } else if strings.HasPrefix(e.Tag, "mod.") { s.viewModuleEvent(e) } else if strings.HasPrefix(e.Tag, "net.sniff.") { diff --git a/modules/http_proxy_script.go b/modules/http_proxy_script.go index 29a35f11..b164e37c 100644 --- a/modules/http_proxy_script.go +++ b/modules/http_proxy_script.go @@ -45,7 +45,7 @@ func LoadProxyScriptSource(path, source string, sess *session.Session) (err erro } // define session pointer - err = s.VM.Set("env", sess.Env.Storage) + err = s.VM.Set("env", sess.Env.Data) if err != nil { log.Error("Error while defining environment: %s", err) return diff --git a/modules/net_probe.go b/modules/net_probe.go index 7f698cd8..911554d3 100644 --- a/modules/net_probe.go +++ b/modules/net_probe.go @@ -6,6 +6,7 @@ import ( "time" "github.com/evilsocket/bettercap-ng/log" + "github.com/evilsocket/bettercap-ng/network" "github.com/evilsocket/bettercap-ng/session" "github.com/malfunkt/iprange" @@ -80,6 +81,11 @@ func (p *Prober) Start() error { } return p.SetRunning(true, func() { + if p.Session.Interface.IpAddress == network.MonitorModeAddress { + log.Info("Interface is in monitor mode, skipping net.probe") + return + } + list, err := iprange.Parse(p.Session.Interface.CIDR()) if err != nil { log.Fatal("%s", err) diff --git a/modules/net_recon.go b/modules/net_recon.go index 26e15bca..5a3b8241 100644 --- a/modules/net_recon.go +++ b/modules/net_recon.go @@ -71,11 +71,12 @@ func (d Discovery) Author() string { func (d *Discovery) runDiff(cache network.ArpTable) { // check for endpoints who disappeared var rem network.ArpTable = make(network.ArpTable) - for mac, t := range d.Session.Lan.Hosts { + + d.Session.Lan.EachHost(func(mac string, e *network.Endpoint) { if _, found := cache[mac]; found == false { - rem[mac] = t.IpAddress + rem[mac] = e.IpAddress } - } + }) for mac, ip := range rem { d.Session.Lan.Remove(ip, mac) diff --git a/modules/net_sniff_dot11.go b/modules/net_sniff_dot11.go new file mode 100644 index 00000000..c3231e2a --- /dev/null +++ b/modules/net_sniff_dot11.go @@ -0,0 +1,28 @@ +package modules + +import ( + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +func dot11Parser(radiotap *layers.RadioTap, dot11 *layers.Dot11, pkt gopacket.Packet, verbose bool) { + NewSnifferEvent( + pkt.Metadata().Timestamp, + "802.11", + "-", + "-", + SniffData{ + "Size": len(pkt.Data()), + }, + "%s %s proto=%d a1=%s a2=%s a3=%s a4=%s seqn=%d frag=%d", + dot11.Type, + dot11.Flags, + dot11.Proto, + dot11.Address1, + dot11.Address2, + dot11.Address3, + dot11.Address4, + dot11.SequenceNumber, + dot11.FragmentNumber, + ).Push() +} diff --git a/modules/net_sniff_parsers.go b/modules/net_sniff_parsers.go index f96237f5..4da791f3 100644 --- a/modules/net_sniff_parsers.go +++ b/modules/net_sniff_parsers.go @@ -86,22 +86,6 @@ func unkParser(ip *layers.IPv4, pkt gopacket.Packet, verbose bool) { } } -func dot11Parser(radiotap *layers.RadioTap, dot11 *layers.Dot11, pkt gopacket.Packet, verbose bool) { - if verbose == true { - NewSnifferEvent( - pkt.Metadata().Timestamp, - "802.11", - "-", - "-", - SniffData{ - "Size": len(pkt.Data()), - }, - "%v", - dot11, - ).Push() - } -} - func mainParser(pkt gopacket.Packet, verbose bool) bool { // simple networking sniffing mode? nlayer := pkt.NetworkLayer() diff --git a/modules/net_sniff_views.go b/modules/net_sniff_views.go index 7c471f9c..86244375 100644 --- a/modules/net_sniff_views.go +++ b/modules/net_sniff_views.go @@ -23,8 +23,7 @@ func vIP(ip net.IP) string { } address := ip.String() - host := session.I.Lan.Get(address) - + host := session.I.Lan.GetByIp(address) if host != nil { if host.Hostname != "" { return host.Hostname diff --git a/modules/wifi_recon.go b/modules/wifi_recon.go index 7a10d6e7..0e8ddb02 100644 --- a/modules/wifi_recon.go +++ b/modules/wifi_recon.go @@ -322,7 +322,7 @@ func (w *WiFiRecon) startDeauth(apMac net.HardwareAddr, clMac net.HardwareAddr) } else { log.Info("Deauthing clients from AP %s ...", apMac.String()) // deauth every authenticated client - for _, station := range w.Session.WiFi.Stations { + for _, station := range w.Session.WiFi.List() { if station.IsAP == false { w.sendDeauthPacket(apMac, station.HW) } diff --git a/network/aliases.go b/network/aliases.go new file mode 100644 index 00000000..711e7af2 --- /dev/null +++ b/network/aliases.go @@ -0,0 +1,85 @@ +package network + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "strings" + "sync" + + "github.com/evilsocket/bettercap-ng/core" +) + +var fileName, _ = core.ExpandPath("~/bettercap.aliases") + +type Aliases struct { + sync.Mutex + + data map[string]string +} + +func LoadAliases() (err error, aliases *Aliases) { + aliases = &Aliases{ + data: make(map[string]string), + } + + if core.Exists(fileName) { + var file *os.File + + file, err = os.Open(fileName) + if err != nil { + return + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + parts := strings.SplitN(line, " ", 2) + mac := core.Trim(parts[0]) + alias := core.Trim(parts[1]) + aliases.data[mac] = alias + } + } + + return +} + +func (a *Aliases) saveUnlocked() error { + data := "" + for mac, alias := range a.data { + data += fmt.Sprintf("%s %s\n", mac, alias) + } + return ioutil.WriteFile(fileName, []byte(data), 0644) +} + +func (a *Aliases) Save() error { + a.Lock() + defer a.Unlock() + + return a.saveUnlocked() +} + +func (a *Aliases) Get(mac string) string { + a.Lock() + defer a.Unlock() + + if alias, found := a.data[mac]; found == true { + return alias + } + return "" +} + +func (a *Aliases) Set(mac, alias string) error { + a.Lock() + defer a.Unlock() + + if alias != "" { + a.data[mac] = alias + } else { + delete(a.data, mac) + } + + return a.saveUnlocked() +} diff --git a/network/lan.go b/network/lan.go index 92a06de0..8a020582 100644 --- a/network/lan.go +++ b/network/lan.go @@ -1,18 +1,13 @@ package network import ( - "bufio" "fmt" - "io/ioutil" "net" - "os" "strings" "sync" - - "github.com/evilsocket/bettercap-ng/core" ) -const LANDefaultTTL = 10 +const LANDefaultttl = 10 const LANAliasesFile = "~/bettercap.aliases" type EndpointNewCallback func(e *Endpoint) @@ -21,36 +16,54 @@ type EndpointLostCallback func(e *Endpoint) type LAN struct { sync.Mutex - Interface *Endpoint - Gateway *Endpoint - Hosts map[string]*Endpoint - TTL map[string]uint - Aliases map[string]string - + Hosts map[string]*Endpoint `json:"hosts"` + iface *Endpoint + gateway *Endpoint + ttl map[string]uint + aliases *Aliases newCb EndpointNewCallback lostCb EndpointLostCallback aliasesFileName string } func NewLAN(iface, gateway *Endpoint, newcb EndpointNewCallback, lostcb EndpointLostCallback) *LAN { - lan := &LAN{ - Interface: iface, - Gateway: gateway, - Hosts: make(map[string]*Endpoint), - TTL: make(map[string]uint), - Aliases: make(map[string]string), - newCb: newcb, - lostCb: lostcb, + err, aliases := LoadAliases() + if err != nil { + fmt.Printf("%s\n", err) } - lan.aliasesFileName, _ = core.ExpandPath(LANAliasesFile) - if core.Exists(lan.aliasesFileName) { - if err := lan.loadAliases(); err != nil { - fmt.Printf("%s\n", err) - } + return &LAN{ + iface: iface, + gateway: gateway, + Hosts: make(map[string]*Endpoint), + ttl: make(map[string]uint), + aliases: aliases, + newCb: newcb, + lostCb: lostcb, } +} - return lan +func (lan *LAN) SetAliasFor(mac, alias string) bool { + lan.Lock() + defer lan.Unlock() + + mac = NormalizeMac(mac) + if e, found := lan.Hosts[mac]; found { + lan.aliases.Set(mac, alias) + e.Alias = alias + return true + } + return false +} + +func (lan *LAN) Get(mac string) (*Endpoint, bool) { + lan.Lock() + defer lan.Unlock() + + if e, found := lan.Hosts[mac]; found == true { + return e, true + } + return nil, false } func (lan *LAN) List() (list []*Endpoint) { @@ -64,62 +77,16 @@ func (lan *LAN) List() (list []*Endpoint) { return } -func (lan *LAN) loadAliases() error { - file, err := os.Open(lan.aliasesFileName) - if err != nil { - return err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := scanner.Text() - parts := strings.SplitN(line, " ", 2) - mac := core.Trim(parts[0]) - alias := core.Trim(parts[1]) - lan.Aliases[mac] = alias - } - - return nil -} - -func (lan *LAN) saveAliases() { - data := "" - for mac, alias := range lan.Aliases { - data += fmt.Sprintf("%s %s\n", mac, alias) - } - ioutil.WriteFile(lan.aliasesFileName, []byte(data), 0644) -} - -func (lan *LAN) SetAliasFor(mac, alias string) bool { - lan.Lock() - defer lan.Unlock() - - if t, found := lan.Hosts[mac]; found == true { - if alias != "" { - lan.Aliases[mac] = alias - } else { - delete(lan.Aliases, mac) - } - - t.Alias = alias - lan.saveAliases() - return true - } - - return false -} - func (lan *LAN) WasMissed(mac string) bool { - if mac == lan.Interface.HwAddress || mac == lan.Gateway.HwAddress { + if mac == lan.iface.HwAddress || mac == lan.gateway.HwAddress { return false } lan.Lock() defer lan.Unlock() - if ttl, found := lan.TTL[mac]; found == true { - return ttl < LANDefaultTTL + if ttl, found := lan.ttl[mac]; found == true { + return ttl < LANDefaultttl } return true } @@ -129,33 +96,36 @@ func (lan *LAN) Remove(ip, mac string) { defer lan.Unlock() if e, found := lan.Hosts[mac]; found { - lan.TTL[mac]-- - if lan.TTL[mac] == 0 { + lan.ttl[mac]-- + if lan.ttl[mac] == 0 { delete(lan.Hosts, mac) - delete(lan.TTL, mac) - + delete(lan.ttl, mac) lan.lostCb(e) } return } } -func (lan *LAN) shouldIgnore(ip string) bool { +func (lan *LAN) shouldIgnore(ip, mac string) bool { // skip our own address - if ip == lan.Interface.IpAddress { + if ip == lan.iface.IpAddress { return true } // skip the gateway - if ip == lan.Gateway.IpAddress { + if ip == lan.gateway.IpAddress { return true } // skip broadcast addresses - if strings.HasSuffix(ip, ".255") { + if strings.HasSuffix(ip, BroadcastSuffix) { + return true + } + // skip broadcast macs + if strings.ToLower(mac) == BroadcastMac { return true } // skip everything which is not in our subnet (multicast noise) addr := net.ParseIP(ip) - return lan.Interface.Net.Contains(addr) == false + return lan.iface.Net.Contains(addr) == false } func (lan *LAN) Has(ip string) bool { @@ -171,7 +141,16 @@ func (lan *LAN) Has(ip string) bool { return false } -func (lan *LAN) Get(ip string) *Endpoint { +func (lan *LAN) EachHost(cb func(mac string, e *Endpoint)) { + lan.Lock() + defer lan.Unlock() + + for m, h := range lan.Hosts { + cb(m, h) + } +} + +func (lan *LAN) GetByIp(ip string) *Endpoint { lan.Lock() defer lan.Unlock() @@ -188,25 +167,21 @@ func (lan *LAN) AddIfNew(ip, mac string) *Endpoint { lan.Lock() defer lan.Unlock() - if lan.shouldIgnore(ip) { - return nil - } - mac = NormalizeMac(mac) - if t, found := lan.Hosts[mac]; found { - if lan.TTL[mac] < LANDefaultTTL { - lan.TTL[mac]++ + + if lan.shouldIgnore(ip, mac) { + return nil + } else if t, found := lan.Hosts[mac]; found { + if lan.ttl[mac] < LANDefaultttl { + lan.ttl[mac]++ } return t } - e := NewEndpoint(ip, mac) - if alias, found := lan.Aliases[mac]; found { - e.Alias = alias - } + e := NewEndpointWithAlias(ip, mac, lan.aliases.Get(mac)) lan.Hosts[mac] = e - lan.TTL[mac] = LANDefaultTTL + lan.ttl[mac] = LANDefaultttl lan.newCb(e) diff --git a/network/lan_endpoint.go b/network/lan_endpoint.go index c9a83d92..01a84e7b 100644 --- a/network/lan_endpoint.go +++ b/network/lan_endpoint.go @@ -69,7 +69,7 @@ func NewEndpoint(ip, mac string) *Endpoint { // start resolver goroutine go func() { - if names, err := net.LookupAddr(e.IpAddress); err == nil { + if names, err := net.LookupAddr(e.IpAddress); err == nil && len(names) > 0 { e.Hostname = names[0] if e.ResolvedCallback != nil { e.ResolvedCallback(e) @@ -80,6 +80,12 @@ func NewEndpoint(ip, mac string) *Endpoint { return e } +func NewEndpointWithAlias(ip, mac, alias string) *Endpoint { + e := NewEndpoint(ip, mac) + e.Alias = alias + return e +} + func (t *Endpoint) Name() string { return t.Hostname } diff --git a/network/net.go b/network/net.go index b0929b05..dc69e7ec 100644 --- a/network/net.go +++ b/network/net.go @@ -12,12 +12,14 @@ import ( const ( MonitorModeAddress = "0.0.0.0" + BroadcastSuffix = ".255" + BroadcastMac = "ff:ff:ff:ff:ff:ff" IPv4MulticastStart = "01:00:5e:00:00:00" IPv4MulticastEnd = "01:00:5e:7f:ff:ff" ) var ( - BroadcastMac = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} + BroadcastHw = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} IPv4Validator = regexp.MustCompile("^[0-9\\.]+/?\\d*$") ) @@ -60,7 +62,9 @@ func FindInterface(name string) (*Endpoint, error) { * if passed explicitly. */ doCheck := false - if name == "" && ifName != "lo" && ifName != "lo0" && nAddrs > 0 { + if name == mac { + doCheck = true + } else if name == "" && ifName != "lo" && ifName != "lo0" && nAddrs > 0 { doCheck = true } else if ifName == name { doCheck = true diff --git a/network/wifi.go b/network/wifi.go index 08852e6d..f7f6514f 100644 --- a/network/wifi.go +++ b/network/wifi.go @@ -12,19 +12,20 @@ var Channels5Ghz = [...]int{36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, type WiFi struct { sync.Mutex - Interface *Endpoint - Stations map[string]*Station + Stations map[string]*Station + + iface *Endpoint newCb StationNewCallback lostCb StationLostCallback } func NewWiFi(iface *Endpoint, newcb StationNewCallback, lostcb StationLostCallback) *WiFi { return &WiFi{ - Interface: iface, - Stations: make(map[string]*Station), - newCb: newcb, - lostCb: lostcb, + Stations: make(map[string]*Station), + iface: iface, + newCb: newcb, + lostCb: lostcb, } } diff --git a/packets/dhcp6.go b/packets/dhcp6.go index 9722b41f..656f5ae9 100644 --- a/packets/dhcp6.go +++ b/packets/dhcp6.go @@ -22,6 +22,7 @@ func DHCP6EncodeList(elements []string) (encoded []byte) { encoded = make([]byte, 0) for _, elem := range elements { + // this would be worth fuzzing btw encoded = append(encoded, byte(len(elem)&0xff)) encoded = append(encoded, []byte(elem)...) } diff --git a/session/environment.go b/session/environment.go index 358b61a6..4a421308 100644 --- a/session/environment.go +++ b/session/environment.go @@ -15,7 +15,7 @@ type Environment struct { sync.Mutex Padding int `json:"-"` - Storage map[string]string `json:"storage"` + Data map[string]string `json:"data"` cbs map[string]SetCallback sess *Session @@ -24,7 +24,7 @@ type Environment struct { func NewEnvironment(s *Session) *Environment { env := &Environment{ Padding: 0, - Storage: make(map[string]string), + Data: make(map[string]string), sess: s, cbs: make(map[string]SetCallback), } @@ -36,7 +36,7 @@ func (env *Environment) Has(name string) bool { env.Lock() defer env.Unlock() - _, found := env.Storage[name] + _, found := env.Data[name] return found } @@ -57,8 +57,8 @@ func (env *Environment) Set(name, value string) string { env.Lock() defer env.Unlock() - old, _ := env.Storage[name] - env.Storage[name] = value + old, _ := env.Data[name] + env.Data[name] = value if cb, hasCallback := env.cbs[name]; hasCallback == true { cb(value) @@ -78,7 +78,7 @@ func (env *Environment) Get(name string) (bool, string) { env.Lock() defer env.Unlock() - if value, found := env.Storage[name]; found == true { + if value, found := env.Data[name]; found == true { return true, value } @@ -102,7 +102,7 @@ func (env *Environment) Sorted() []string { defer env.Unlock() var keys []string - for k := range env.Storage { + for k := range env.Data { keys = append(keys, k) } sort.Strings(keys) diff --git a/session/events.go b/session/events.go index 91dec096..e9c44deb 100644 --- a/session/events.go +++ b/session/events.go @@ -100,12 +100,6 @@ func (p *EventPool) Clear() { p.events = make([]Event, 0) } -func (p *EventPool) Events() []Event { - p.Lock() - defer p.Unlock() - return p.events -} - func (p *EventPool) Sorted() []Event { p.Lock() defer p.Unlock() diff --git a/session/prompt.go b/session/prompt.go index 708b2a59..b5c4b0b3 100644 --- a/session/prompt.go +++ b/session/prompt.go @@ -56,7 +56,7 @@ var PromptCallbacks = map[string]func(s *Session) string{ }, } -var envRe = regexp.MustCompile("{env\\.(.+)}") +var envRe = regexp.MustCompile("{env\\.([^}]+)}") type Prompt struct { } @@ -79,11 +79,11 @@ func (p Prompt) Render(s *Session) string { prompt = strings.Replace(prompt, tok, cb(s), -1) } - m := envRe.FindStringSubmatch(prompt) - if len(m) == 2 { - name := m[1] + m := envRe.FindAllString(prompt, -1) + for _, match := range m { + name := strings.Trim(strings.Replace(match, "env.", "", -1), "{}") _, value := s.Env.Get(name) - prompt = strings.Replace(prompt, m[0], value, -1) + prompt = strings.Replace(prompt, match, value, -1) } // make sure an user error does not screw all terminal diff --git a/session/session_core_handlers.go b/session/session_core_handlers.go index e08eb0c5..02f1ee2c 100644 --- a/session/session_core_handlers.go +++ b/session/session_core_handlers.go @@ -8,6 +8,7 @@ import ( "time" "github.com/evilsocket/bettercap-ng/core" + "github.com/evilsocket/bettercap-ng/network" "github.com/evilsocket/readline" ) @@ -132,7 +133,7 @@ func (s *Session) getHandler(args []string, sess *Session) error { prev_ns = ns } - fmt.Printf(" %"+strconv.Itoa(s.Env.Padding)+"s: '%s'\n", k, s.Env.Storage[k]) + fmt.Printf(" %"+strconv.Itoa(s.Env.Padding)+"s: '%s'\n", k, s.Env.Data[k]) } fmt.Println() } else if found, value := s.Env.Get(key); found == true { @@ -241,7 +242,7 @@ func (s *Session) registerCoreHandlers() { readline.PcItem("get", readline.PcItemDynamic(func(prefix string) []string { prefix = core.Trim(prefix[3:]) varNames := []string{""} - for key := range s.Env.Storage { + for key := range s.Env.Data { if prefix == "" || strings.HasPrefix(key, prefix) == true { varNames = append(varNames, key) } @@ -256,7 +257,7 @@ func (s *Session) registerCoreHandlers() { readline.PcItem("set", readline.PcItemDynamic(func(prefix string) []string { prefix = core.Trim(prefix[3:]) varNames := []string{""} - for key := range s.Env.Storage { + for key := range s.Env.Data { if prefix == "" || strings.HasPrefix(key, prefix) == true { varNames = append(varNames, key) } @@ -298,11 +299,11 @@ func (s *Session) registerCoreHandlers() { readline.PcItem("alias", readline.PcItemDynamic(func(prefix string) []string { prefix = core.Trim(prefix[5:]) macs := []string{""} - for mac := range s.Lan.Hosts { + s.Lan.EachHost(func(mac string, e *network.Endpoint) { if prefix == "" || strings.HasPrefix(mac, prefix) == true { macs = append(macs, mac) } - } + }) return macs })))