Merge branch 'master' of github.com:evilsocket/bettercap-ng

This commit is contained in:
Matrix86 2018-02-20 12:41:06 +01:00
commit 8825ecb8db
25 changed files with 343 additions and 166 deletions

View file

@ -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 ## License
`bettercap` and `bettercap-ng` are made with ♥ by [Simone Margaritelli](https://www.evilsocket.net/) and they're released under the GPL 3 license. `bettercap` and `bettercap-ng` are made with ♥ by [Simone Margaritelli](https://www.evilsocket.net/) and they're released under the GPL 3 license.

View file

@ -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 $ {by}{fw}{env.iface.name}{reset} {bold}» {reset}
set ticker.commands clear; wifi.show set ticker.commands clear; wifi.show

View file

@ -12,7 +12,10 @@ net.sniff on
# interested in otherwise the sniffer might lose packets. # interested in otherwise the sniffer might lose packets.
set wifi.recon.channel 1 set wifi.recon.channel 1
# this will enable the wifi recon
set ticker.commands clear; wifi.show
wifi.recon on wifi.recon on
ticker on
# uncomment to recon clients of a specific AP given its BSSID # uncomment to recon clients of a specific AP given its BSSID
# wifi.recon DE:AD:BE:EF:DE:AD # wifi.recon DE:AD:BE:EF:DE:AD
@ -29,3 +32,7 @@ clear
# This will deauth every client for this specific access point, # This will deauth every client for this specific access point,
# you can put it as ticker.commands to have the ticker module # you can put it as ticker.commands to have the ticker module
# periodically deauth clients :D # periodically deauth clients :D
#
# For more options `help wifi.recon`.

View file

@ -22,6 +22,7 @@ type PfFirewall struct {
iface *network.Endpoint iface *network.Endpoint
filename string filename string
forwarding bool forwarding bool
enabled bool
} }
func Make(iface *network.Endpoint) FirewallManager { func Make(iface *network.Endpoint) FirewallManager {
@ -29,6 +30,7 @@ func Make(iface *network.Endpoint) FirewallManager {
iface: iface, iface: iface,
filename: pfFilePath, filename: pfFilePath,
forwarding: false, forwarding: false,
enabled: false,
} }
firewall.forwarding = firewall.IsForwardingEnabled() 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) 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 { if enabled {
core.Exec("pfctl", []string{"-e"}) core.Exec("pfctl", []string{"-e"})
} else { } else {
@ -165,11 +168,9 @@ func (f PfFirewall) EnableRedirection(r *Redirection, enabled bool) error {
} }
func (f PfFirewall) Restore() { func (f PfFirewall) Restore() {
err := f.EnableForwarding(f.forwarding) f.EnableForwarding(f.forwarding)
if err != nil { if f.enabled {
fmt.Fprintf(os.Stderr, "%s", err) f.enable(false)
} }
f.enable(false)
os.Remove(f.filename) os.Remove(f.filename)
} }

View file

@ -19,9 +19,6 @@ type APIResponse struct {
func SafeBind(c *gin.Context, obj interface{}) error { func SafeBind(c *gin.Context, obj interface{}) error {
decoder := json.NewDecoder(io.LimitReader(c.Request.Body, 100*1024)) decoder := json.NewDecoder(io.LimitReader(c.Request.Body, 100*1024))
if binding.EnableDecoderUseNumber {
decoder.UseNumber()
}
if err := decoder.Decode(obj); err != nil { if err := decoder.Decode(obj); err != nil {
return err return err
} }

View file

@ -154,8 +154,8 @@ func (s *DHCP6Spoofer) dhcpAdvertise(pkt gopacket.Packet, solicit dhcp6.Packet,
} }
var ip net.IP var ip net.IP
if t, found := s.Session.Lan.Hosts[target.String()]; found == true { if h, found := s.Session.Lan.Get(target.String()); found == true {
ip = t.IP ip = h.IP
} else { } else {
log.Warning("Address %s not known, using random identity association address.", target.String()) log.Warning("Address %s not known, using random identity association address.", target.String())
rand.Read(ip) rand.Read(ip)
@ -312,8 +312,8 @@ func (s *DHCP6Spoofer) dhcpReply(toType string, pkt gopacket.Packet, req dhcp6.P
addr = net.IP(raw[0]) addr = net.IP(raw[0])
} }
if t, found := s.Session.Lan.Hosts[target.String()]; found == true { 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(), t) log.Info("[%s] IPv6 address %s is now assigned to %s", core.Green("dhcp6"), addr.String(), h)
} else { } else {
log.Info("[%s] IPv6 address %s is now assigned to %s", core.Green("dhcp6"), addr.String(), target) log.Info("[%s] IPv6 address %s is now assigned to %s", core.Green("dhcp6"), addr.String(), target)
} }

View file

@ -111,7 +111,7 @@ func (s *DNSSpoofer) dnsReply(pkt gopacket.Packet, peth *layers.Ethernet, pudp *
redir := fmt.Sprintf("(->%s)", s.Address) redir := fmt.Sprintf("(->%s)", s.Address)
who := target.String() 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() who = t.String()
} }

View file

@ -19,6 +19,33 @@ func (s EventsStream) viewLogEvent(e session.Event) {
e.Data.(session.LogMessage).Message) 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) { func (s EventsStream) viewEndpointEvent(e session.Event) {
t := e.Data.(*network.Endpoint) t := e.Data.(*network.Endpoint)
vend := "" vend := ""
@ -74,6 +101,8 @@ func (s *EventsStream) View(e session.Event, refresh bool) {
s.viewLogEvent(e) s.viewLogEvent(e)
} else if strings.HasPrefix(e.Tag, "endpoint.") { } else if strings.HasPrefix(e.Tag, "endpoint.") {
s.viewEndpointEvent(e) s.viewEndpointEvent(e)
} else if strings.HasPrefix(e.Tag, "wifi.station.") {
s.viewStationEvent(e)
} else if strings.HasPrefix(e.Tag, "mod.") { } else if strings.HasPrefix(e.Tag, "mod.") {
s.viewModuleEvent(e) s.viewModuleEvent(e)
} else if strings.HasPrefix(e.Tag, "net.sniff.") { } else if strings.HasPrefix(e.Tag, "net.sniff.") {

View file

@ -45,7 +45,7 @@ func LoadProxyScriptSource(path, source string, sess *session.Session) (err erro
} }
// define session pointer // define session pointer
err = s.VM.Set("env", sess.Env.Storage) err = s.VM.Set("env", sess.Env.Data)
if err != nil { if err != nil {
log.Error("Error while defining environment: %s", err) log.Error("Error while defining environment: %s", err)
return return

View file

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/evilsocket/bettercap-ng/log" "github.com/evilsocket/bettercap-ng/log"
"github.com/evilsocket/bettercap-ng/network"
"github.com/evilsocket/bettercap-ng/session" "github.com/evilsocket/bettercap-ng/session"
"github.com/malfunkt/iprange" "github.com/malfunkt/iprange"
@ -80,6 +81,11 @@ func (p *Prober) Start() error {
} }
return p.SetRunning(true, func() { 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()) list, err := iprange.Parse(p.Session.Interface.CIDR())
if err != nil { if err != nil {
log.Fatal("%s", err) log.Fatal("%s", err)

View file

@ -71,11 +71,12 @@ func (d Discovery) Author() string {
func (d *Discovery) runDiff(cache network.ArpTable) { func (d *Discovery) runDiff(cache network.ArpTable) {
// check for endpoints who disappeared // check for endpoints who disappeared
var rem network.ArpTable = make(network.ArpTable) 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 { if _, found := cache[mac]; found == false {
rem[mac] = t.IpAddress rem[mac] = e.IpAddress
} }
} })
for mac, ip := range rem { for mac, ip := range rem {
d.Session.Lan.Remove(ip, mac) d.Session.Lan.Remove(ip, mac)

View file

@ -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()
}

View file

@ -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 { func mainParser(pkt gopacket.Packet, verbose bool) bool {
// simple networking sniffing mode? // simple networking sniffing mode?
nlayer := pkt.NetworkLayer() nlayer := pkt.NetworkLayer()

View file

@ -23,8 +23,7 @@ func vIP(ip net.IP) string {
} }
address := ip.String() address := ip.String()
host := session.I.Lan.Get(address) host := session.I.Lan.GetByIp(address)
if host != nil { if host != nil {
if host.Hostname != "" { if host.Hostname != "" {
return host.Hostname return host.Hostname

View file

@ -322,7 +322,7 @@ func (w *WiFiRecon) startDeauth(apMac net.HardwareAddr, clMac net.HardwareAddr)
} else { } else {
log.Info("Deauthing clients from AP %s ...", apMac.String()) log.Info("Deauthing clients from AP %s ...", apMac.String())
// deauth every authenticated client // deauth every authenticated client
for _, station := range w.Session.WiFi.Stations { for _, station := range w.Session.WiFi.List() {
if station.IsAP == false { if station.IsAP == false {
w.sendDeauthPacket(apMac, station.HW) w.sendDeauthPacket(apMac, station.HW)
} }

85
network/aliases.go Normal file
View file

@ -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()
}

View file

@ -1,18 +1,13 @@
package network package network
import ( import (
"bufio"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"os"
"strings" "strings"
"sync" "sync"
"github.com/evilsocket/bettercap-ng/core"
) )
const LANDefaultTTL = 10 const LANDefaultttl = 10
const LANAliasesFile = "~/bettercap.aliases" const LANAliasesFile = "~/bettercap.aliases"
type EndpointNewCallback func(e *Endpoint) type EndpointNewCallback func(e *Endpoint)
@ -21,36 +16,54 @@ type EndpointLostCallback func(e *Endpoint)
type LAN struct { type LAN struct {
sync.Mutex sync.Mutex
Interface *Endpoint Hosts map[string]*Endpoint `json:"hosts"`
Gateway *Endpoint iface *Endpoint
Hosts map[string]*Endpoint gateway *Endpoint
TTL map[string]uint ttl map[string]uint
Aliases map[string]string aliases *Aliases
newCb EndpointNewCallback newCb EndpointNewCallback
lostCb EndpointLostCallback lostCb EndpointLostCallback
aliasesFileName string aliasesFileName string
} }
func NewLAN(iface, gateway *Endpoint, newcb EndpointNewCallback, lostcb EndpointLostCallback) *LAN { func NewLAN(iface, gateway *Endpoint, newcb EndpointNewCallback, lostcb EndpointLostCallback) *LAN {
lan := &LAN{ err, aliases := LoadAliases()
Interface: iface, if err != nil {
Gateway: gateway, fmt.Printf("%s\n", err)
Hosts: make(map[string]*Endpoint),
TTL: make(map[string]uint),
Aliases: make(map[string]string),
newCb: newcb,
lostCb: lostcb,
} }
lan.aliasesFileName, _ = core.ExpandPath(LANAliasesFile) return &LAN{
if core.Exists(lan.aliasesFileName) { iface: iface,
if err := lan.loadAliases(); err != nil { gateway: gateway,
fmt.Printf("%s\n", err) 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) { func (lan *LAN) List() (list []*Endpoint) {
@ -64,62 +77,16 @@ func (lan *LAN) List() (list []*Endpoint) {
return 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 { 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 return false
} }
lan.Lock() lan.Lock()
defer lan.Unlock() defer lan.Unlock()
if ttl, found := lan.TTL[mac]; found == true { if ttl, found := lan.ttl[mac]; found == true {
return ttl < LANDefaultTTL return ttl < LANDefaultttl
} }
return true return true
} }
@ -129,33 +96,36 @@ func (lan *LAN) Remove(ip, mac string) {
defer lan.Unlock() defer lan.Unlock()
if e, found := lan.Hosts[mac]; found { if e, found := lan.Hosts[mac]; found {
lan.TTL[mac]-- lan.ttl[mac]--
if lan.TTL[mac] == 0 { if lan.ttl[mac] == 0 {
delete(lan.Hosts, mac) delete(lan.Hosts, mac)
delete(lan.TTL, mac) delete(lan.ttl, mac)
lan.lostCb(e) lan.lostCb(e)
} }
return return
} }
} }
func (lan *LAN) shouldIgnore(ip string) bool { func (lan *LAN) shouldIgnore(ip, mac string) bool {
// skip our own address // skip our own address
if ip == lan.Interface.IpAddress { if ip == lan.iface.IpAddress {
return true return true
} }
// skip the gateway // skip the gateway
if ip == lan.Gateway.IpAddress { if ip == lan.gateway.IpAddress {
return true return true
} }
// skip broadcast addresses // 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 return true
} }
// skip everything which is not in our subnet (multicast noise) // skip everything which is not in our subnet (multicast noise)
addr := net.ParseIP(ip) 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 { func (lan *LAN) Has(ip string) bool {
@ -171,7 +141,16 @@ func (lan *LAN) Has(ip string) bool {
return false 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() lan.Lock()
defer lan.Unlock() defer lan.Unlock()
@ -188,25 +167,21 @@ func (lan *LAN) AddIfNew(ip, mac string) *Endpoint {
lan.Lock() lan.Lock()
defer lan.Unlock() defer lan.Unlock()
if lan.shouldIgnore(ip) {
return nil
}
mac = NormalizeMac(mac) mac = NormalizeMac(mac)
if t, found := lan.Hosts[mac]; found {
if lan.TTL[mac] < LANDefaultTTL { if lan.shouldIgnore(ip, mac) {
lan.TTL[mac]++ return nil
} else if t, found := lan.Hosts[mac]; found {
if lan.ttl[mac] < LANDefaultttl {
lan.ttl[mac]++
} }
return t return t
} }
e := NewEndpoint(ip, mac) e := NewEndpointWithAlias(ip, mac, lan.aliases.Get(mac))
if alias, found := lan.Aliases[mac]; found {
e.Alias = alias
}
lan.Hosts[mac] = e lan.Hosts[mac] = e
lan.TTL[mac] = LANDefaultTTL lan.ttl[mac] = LANDefaultttl
lan.newCb(e) lan.newCb(e)

View file

@ -69,7 +69,7 @@ func NewEndpoint(ip, mac string) *Endpoint {
// start resolver goroutine // start resolver goroutine
go func() { 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] e.Hostname = names[0]
if e.ResolvedCallback != nil { if e.ResolvedCallback != nil {
e.ResolvedCallback(e) e.ResolvedCallback(e)
@ -80,6 +80,12 @@ func NewEndpoint(ip, mac string) *Endpoint {
return e return e
} }
func NewEndpointWithAlias(ip, mac, alias string) *Endpoint {
e := NewEndpoint(ip, mac)
e.Alias = alias
return e
}
func (t *Endpoint) Name() string { func (t *Endpoint) Name() string {
return t.Hostname return t.Hostname
} }

View file

@ -12,12 +12,14 @@ import (
const ( const (
MonitorModeAddress = "0.0.0.0" MonitorModeAddress = "0.0.0.0"
BroadcastSuffix = ".255"
BroadcastMac = "ff:ff:ff:ff:ff:ff"
IPv4MulticastStart = "01:00:5e:00:00:00" IPv4MulticastStart = "01:00:5e:00:00:00"
IPv4MulticastEnd = "01:00:5e:7f:ff:ff" IPv4MulticastEnd = "01:00:5e:7f:ff:ff"
) )
var ( var (
BroadcastMac = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} BroadcastHw = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
IPv4Validator = regexp.MustCompile("^[0-9\\.]+/?\\d*$") IPv4Validator = regexp.MustCompile("^[0-9\\.]+/?\\d*$")
) )
@ -60,7 +62,9 @@ func FindInterface(name string) (*Endpoint, error) {
* if passed explicitly. * if passed explicitly.
*/ */
doCheck := false 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 doCheck = true
} else if ifName == name { } else if ifName == name {
doCheck = true doCheck = true

View file

@ -12,19 +12,20 @@ var Channels5Ghz = [...]int{36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60,
type WiFi struct { type WiFi struct {
sync.Mutex sync.Mutex
Interface *Endpoint
Stations map[string]*Station
Stations map[string]*Station
iface *Endpoint
newCb StationNewCallback newCb StationNewCallback
lostCb StationLostCallback lostCb StationLostCallback
} }
func NewWiFi(iface *Endpoint, newcb StationNewCallback, lostcb StationLostCallback) *WiFi { func NewWiFi(iface *Endpoint, newcb StationNewCallback, lostcb StationLostCallback) *WiFi {
return &WiFi{ return &WiFi{
Interface: iface, Stations: make(map[string]*Station),
Stations: make(map[string]*Station), iface: iface,
newCb: newcb, newCb: newcb,
lostCb: lostcb, lostCb: lostcb,
} }
} }

View file

@ -22,6 +22,7 @@ func DHCP6EncodeList(elements []string) (encoded []byte) {
encoded = make([]byte, 0) encoded = make([]byte, 0)
for _, elem := range elements { for _, elem := range elements {
// this would be worth fuzzing btw
encoded = append(encoded, byte(len(elem)&0xff)) encoded = append(encoded, byte(len(elem)&0xff))
encoded = append(encoded, []byte(elem)...) encoded = append(encoded, []byte(elem)...)
} }

View file

@ -15,7 +15,7 @@ type Environment struct {
sync.Mutex sync.Mutex
Padding int `json:"-"` Padding int `json:"-"`
Storage map[string]string `json:"storage"` Data map[string]string `json:"data"`
cbs map[string]SetCallback cbs map[string]SetCallback
sess *Session sess *Session
@ -24,7 +24,7 @@ type Environment struct {
func NewEnvironment(s *Session) *Environment { func NewEnvironment(s *Session) *Environment {
env := &Environment{ env := &Environment{
Padding: 0, Padding: 0,
Storage: make(map[string]string), Data: make(map[string]string),
sess: s, sess: s,
cbs: make(map[string]SetCallback), cbs: make(map[string]SetCallback),
} }
@ -36,7 +36,7 @@ func (env *Environment) Has(name string) bool {
env.Lock() env.Lock()
defer env.Unlock() defer env.Unlock()
_, found := env.Storage[name] _, found := env.Data[name]
return found return found
} }
@ -57,8 +57,8 @@ func (env *Environment) Set(name, value string) string {
env.Lock() env.Lock()
defer env.Unlock() defer env.Unlock()
old, _ := env.Storage[name] old, _ := env.Data[name]
env.Storage[name] = value env.Data[name] = value
if cb, hasCallback := env.cbs[name]; hasCallback == true { if cb, hasCallback := env.cbs[name]; hasCallback == true {
cb(value) cb(value)
@ -78,7 +78,7 @@ func (env *Environment) Get(name string) (bool, string) {
env.Lock() env.Lock()
defer env.Unlock() defer env.Unlock()
if value, found := env.Storage[name]; found == true { if value, found := env.Data[name]; found == true {
return true, value return true, value
} }
@ -102,7 +102,7 @@ func (env *Environment) Sorted() []string {
defer env.Unlock() defer env.Unlock()
var keys []string var keys []string
for k := range env.Storage { for k := range env.Data {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) sort.Strings(keys)

View file

@ -100,12 +100,6 @@ func (p *EventPool) Clear() {
p.events = make([]Event, 0) p.events = make([]Event, 0)
} }
func (p *EventPool) Events() []Event {
p.Lock()
defer p.Unlock()
return p.events
}
func (p *EventPool) Sorted() []Event { func (p *EventPool) Sorted() []Event {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()

View file

@ -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 { type Prompt struct {
} }
@ -79,11 +79,11 @@ func (p Prompt) Render(s *Session) string {
prompt = strings.Replace(prompt, tok, cb(s), -1) prompt = strings.Replace(prompt, tok, cb(s), -1)
} }
m := envRe.FindStringSubmatch(prompt) m := envRe.FindAllString(prompt, -1)
if len(m) == 2 { for _, match := range m {
name := m[1] name := strings.Trim(strings.Replace(match, "env.", "", -1), "{}")
_, value := s.Env.Get(name) _, 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 // make sure an user error does not screw all terminal

View file

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/evilsocket/bettercap-ng/core" "github.com/evilsocket/bettercap-ng/core"
"github.com/evilsocket/bettercap-ng/network"
"github.com/evilsocket/readline" "github.com/evilsocket/readline"
) )
@ -132,7 +133,7 @@ func (s *Session) getHandler(args []string, sess *Session) error {
prev_ns = ns 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() fmt.Println()
} else if found, value := s.Env.Get(key); found == true { } 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 { readline.PcItem("get", readline.PcItemDynamic(func(prefix string) []string {
prefix = core.Trim(prefix[3:]) prefix = core.Trim(prefix[3:])
varNames := []string{""} varNames := []string{""}
for key := range s.Env.Storage { for key := range s.Env.Data {
if prefix == "" || strings.HasPrefix(key, prefix) == true { if prefix == "" || strings.HasPrefix(key, prefix) == true {
varNames = append(varNames, key) varNames = append(varNames, key)
} }
@ -256,7 +257,7 @@ func (s *Session) registerCoreHandlers() {
readline.PcItem("set", readline.PcItemDynamic(func(prefix string) []string { readline.PcItem("set", readline.PcItemDynamic(func(prefix string) []string {
prefix = core.Trim(prefix[3:]) prefix = core.Trim(prefix[3:])
varNames := []string{""} varNames := []string{""}
for key := range s.Env.Storage { for key := range s.Env.Data {
if prefix == "" || strings.HasPrefix(key, prefix) == true { if prefix == "" || strings.HasPrefix(key, prefix) == true {
varNames = append(varNames, key) varNames = append(varNames, key)
} }
@ -298,11 +299,11 @@ func (s *Session) registerCoreHandlers() {
readline.PcItem("alias", readline.PcItemDynamic(func(prefix string) []string { readline.PcItem("alias", readline.PcItemDynamic(func(prefix string) []string {
prefix = core.Trim(prefix[5:]) prefix = core.Trim(prefix[5:])
macs := []string{""} macs := []string{""}
for mac := range s.Lan.Hosts { s.Lan.EachHost(func(mac string, e *network.Endpoint) {
if prefix == "" || strings.HasPrefix(mac, prefix) == true { if prefix == "" || strings.HasPrefix(mac, prefix) == true {
macs = append(macs, mac) macs = append(macs, mac)
} }
} })
return macs return macs
}))) })))