mirror of
https://github.com/bettercap/bettercap.git
synced 2025-03-12 04:36:03 -07:00
new: aliases are now centralized and can be used for any type of device (closes #504)
This commit is contained in:
parent
96853e663b
commit
7e7f2ef645
@ -124,7 +124,7 @@ func (mod *WiFiModule) discoverClients(radiotap *layers.RadioTap, dot11 *layers.
|
||||
freq := int(radiotap.ChannelFrequency)
|
||||
rssi := radiotap.DBMAntennaSignal
|
||||
|
||||
if station, isNew := ap.AddClientIfNew(bssid, freq, rssi, mod.Session.Lan.Aliases()); isNew {
|
||||
if station, isNew := ap.AddClientIfNew(bssid, freq, rssi); isNew {
|
||||
mod.Session.Events.Add("wifi.client.new", ClientEvent{
|
||||
AP: ap,
|
||||
Client: station,
|
||||
|
@ -36,7 +36,7 @@ func (mod *WiFiModule) discoverHandshakes(radiotap *layers.RadioTap, dot11 *laye
|
||||
staIsUs := bytes.Equal(staMac, mod.iface.HW)
|
||||
station, found := ap.Get(staMac.String())
|
||||
if !found {
|
||||
station, _ = ap.AddClientIfNew(staMac.String(), ap.Frequency, ap.RSSI, mod.Session.Lan.Aliases())
|
||||
station, _ = ap.AddClientIfNew(staMac.String(), ap.Frequency, ap.RSSI)
|
||||
}
|
||||
|
||||
rawPMKID := []byte(nil)
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bettercap/gatt"
|
||||
|
||||
"github.com/evilsocket/islazy/data"
|
||||
)
|
||||
|
||||
const BLEMacValidator = "([a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2})"
|
||||
@ -18,6 +20,7 @@ type BLEDevLostCallback func(dev *BLEDevice)
|
||||
|
||||
type BLE struct {
|
||||
sync.RWMutex
|
||||
aliases *data.UnsortedKV
|
||||
devices map[string]*BLEDevice
|
||||
newCb BLEDevNewCallback
|
||||
lostCb BLEDevLostCallback
|
||||
@ -27,9 +30,10 @@ type bleJSON struct {
|
||||
Devices []*BLEDevice `json:"devices"`
|
||||
}
|
||||
|
||||
func NewBLE(newcb BLEDevNewCallback, lostcb BLEDevLostCallback) *BLE {
|
||||
func NewBLE(aliases *data.UnsortedKV, newcb BLEDevNewCallback, lostcb BLEDevLostCallback) *BLE {
|
||||
return &BLE{
|
||||
devices: make(map[string]*BLEDevice),
|
||||
aliases: aliases,
|
||||
newCb: newcb,
|
||||
lostCb: lostcb,
|
||||
}
|
||||
@ -55,14 +59,19 @@ func (b *BLE) AddIfNew(id string, p gatt.Peripheral, a *gatt.Advertisement, rssi
|
||||
defer b.Unlock()
|
||||
|
||||
id = NormalizeMac(id)
|
||||
alias := b.aliases.GetOr(id, "")
|
||||
if dev, found := b.devices[id]; found {
|
||||
dev.LastSeen = time.Now()
|
||||
dev.RSSI = rssi
|
||||
dev.Advertisement = a
|
||||
if alias != "" {
|
||||
dev.Alias = alias
|
||||
}
|
||||
return dev
|
||||
}
|
||||
|
||||
newDev := NewBLEDevice(p, a, rssi)
|
||||
newDev.Alias = alias
|
||||
b.devices[id] = newDev
|
||||
|
||||
if b.newCb != nil {
|
||||
|
@ -27,6 +27,7 @@ type BLEService struct {
|
||||
}
|
||||
|
||||
type BLEDevice struct {
|
||||
Alias string
|
||||
LastSeen time.Time
|
||||
DeviceName string
|
||||
Vendor string
|
||||
@ -40,6 +41,7 @@ type bleDeviceJSON struct {
|
||||
LastSeen time.Time `json:"last_seen"`
|
||||
Name string `json:"name"`
|
||||
MAC string `json:"mac"`
|
||||
Alias string `json:"alias"`
|
||||
Vendor string `json:"vendor"`
|
||||
RSSI int `json:"rssi"`
|
||||
Connectable bool `json:"connectable"`
|
||||
@ -81,6 +83,7 @@ func (d *BLEDevice) MarshalJSON() ([]byte, error) {
|
||||
LastSeen: d.LastSeen,
|
||||
Name: d.Name(),
|
||||
MAC: d.Device.ID(),
|
||||
Alias: d.Alias,
|
||||
Vendor: d.Vendor,
|
||||
RSSI: d.RSSI,
|
||||
Connectable: d.Advertisement.Connectable,
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/evilsocket/islazy/data"
|
||||
)
|
||||
|
||||
type HIDDevNewCallback func(dev *HIDDevice)
|
||||
@ -11,6 +13,7 @@ type HIDDevLostCallback func(dev *HIDDevice)
|
||||
|
||||
type HID struct {
|
||||
sync.RWMutex
|
||||
aliases *data.UnsortedKV
|
||||
devices map[string]*HIDDevice
|
||||
newCb HIDDevNewCallback
|
||||
lostCb HIDDevLostCallback
|
||||
@ -20,9 +23,10 @@ type hidJSON struct {
|
||||
Devices []*HIDDevice `json:"devices"`
|
||||
}
|
||||
|
||||
func NewHID(newcb HIDDevNewCallback, lostcb HIDDevLostCallback) *HID {
|
||||
func NewHID(aliases *data.UnsortedKV, newcb HIDDevNewCallback, lostcb HIDDevLostCallback) *HID {
|
||||
return &HID{
|
||||
devices: make(map[string]*HIDDevice),
|
||||
aliases: aliases,
|
||||
newCb: newcb,
|
||||
lostCb: lostcb,
|
||||
}
|
||||
@ -52,14 +56,20 @@ func (b *HID) AddIfNew(address []byte, channel int, payload []byte) (bool, *HIDD
|
||||
defer b.Unlock()
|
||||
|
||||
id := HIDAddress(address)
|
||||
alias := b.aliases.GetOr(id, "")
|
||||
|
||||
if dev, found := b.devices[id]; found {
|
||||
dev.LastSeen = time.Now()
|
||||
dev.AddChannel(channel)
|
||||
dev.AddPayload(payload)
|
||||
if alias != "" {
|
||||
dev.Alias = alias
|
||||
}
|
||||
return false, dev
|
||||
}
|
||||
|
||||
newDev := NewHIDDevice(address, channel, payload)
|
||||
newDev.Alias = alias
|
||||
b.devices[id] = newDev
|
||||
|
||||
if b.newCb != nil {
|
||||
|
@ -42,6 +42,7 @@ type HIDDevice struct {
|
||||
sync.Mutex
|
||||
LastSeen time.Time
|
||||
Type HIDType
|
||||
Alias string
|
||||
Address string
|
||||
RawAddress []byte
|
||||
channels map[int]bool
|
||||
@ -53,6 +54,7 @@ type hidDeviceJSON struct {
|
||||
LastSeen time.Time `json:"last_seen"`
|
||||
Type string `json:"type"`
|
||||
Address string `json:"address"`
|
||||
Alias string `json:"alias"`
|
||||
Channels []string `json:"channels"`
|
||||
Payloads []string `json:"payloads"`
|
||||
PayloadsSize uint64 `json:"payloads_size"`
|
||||
@ -102,6 +104,7 @@ func (dev *HIDDevice) MarshalJSON() ([]byte, error) {
|
||||
LastSeen: dev.LastSeen,
|
||||
Type: dev.Type.String(),
|
||||
Address: dev.Address,
|
||||
Alias: dev.Alias,
|
||||
Channels: dev.channelsListUnlocked(),
|
||||
Payloads: make([]string, 0),
|
||||
PayloadsSize: dev.payloadsSz,
|
||||
|
@ -2,23 +2,18 @@ package network
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/evilsocket/islazy/data"
|
||||
"github.com/evilsocket/islazy/fs"
|
||||
)
|
||||
|
||||
const LANDefaultttl = 10
|
||||
const LANAliasesFile = "~/bettercap.aliases"
|
||||
|
||||
type EndpointNewCallback func(e *Endpoint)
|
||||
type EndpointLostCallback func(e *Endpoint)
|
||||
|
||||
var aliasesFileName, _ = fs.Expand(LANAliasesFile)
|
||||
|
||||
type LAN struct {
|
||||
sync.Mutex
|
||||
hosts map[string]*Endpoint
|
||||
@ -34,12 +29,7 @@ type lanJSON struct {
|
||||
Hosts []*Endpoint `json:"hosts"`
|
||||
}
|
||||
|
||||
func NewLAN(iface, gateway *Endpoint, newcb EndpointNewCallback, lostcb EndpointLostCallback) *LAN {
|
||||
aliases, err := data.NewUnsortedKV(aliasesFileName, data.FlushOnEdit)
|
||||
if err != nil {
|
||||
fmt.Printf("error loading %s: %s", aliasesFileName, err)
|
||||
}
|
||||
|
||||
func NewLAN(iface, gateway *Endpoint, aliases *data.UnsortedKV, newcb EndpointNewCallback, lostcb EndpointLostCallback) *LAN {
|
||||
return &LAN{
|
||||
iface: iface,
|
||||
gateway: gateway,
|
||||
@ -63,19 +53,6 @@ func (l *LAN) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(doc)
|
||||
}
|
||||
|
||||
func (lan *LAN) SetAliasFor(mac, alias string) bool {
|
||||
lan.Lock()
|
||||
defer lan.Unlock()
|
||||
|
||||
mac = NormalizeMac(mac)
|
||||
lan.aliases.Set(mac, alias)
|
||||
if e, found := lan.hosts[mac]; found {
|
||||
e.Alias = alias
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (lan *LAN) Get(mac string) (*Endpoint, bool) {
|
||||
lan.Lock()
|
||||
defer lan.Unlock()
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/google/gopacket/layers"
|
||||
"github.com/google/gopacket/pcapgo"
|
||||
|
||||
"github.com/evilsocket/islazy/data"
|
||||
"github.com/evilsocket/islazy/fs"
|
||||
)
|
||||
|
||||
@ -43,22 +44,24 @@ type APLostCallback func(ap *AccessPoint)
|
||||
type WiFi struct {
|
||||
sync.Mutex
|
||||
|
||||
aps map[string]*AccessPoint
|
||||
iface *Endpoint
|
||||
newCb APNewCallback
|
||||
lostCb APLostCallback
|
||||
aliases *data.UnsortedKV
|
||||
aps map[string]*AccessPoint
|
||||
iface *Endpoint
|
||||
newCb APNewCallback
|
||||
lostCb APLostCallback
|
||||
}
|
||||
|
||||
type wifiJSON struct {
|
||||
AccessPoints []*AccessPoint `json:"aps"`
|
||||
}
|
||||
|
||||
func NewWiFi(iface *Endpoint, newcb APNewCallback, lostcb APLostCallback) *WiFi {
|
||||
func NewWiFi(iface *Endpoint, aliases *data.UnsortedKV, newcb APNewCallback, lostcb APLostCallback) *WiFi {
|
||||
return &WiFi{
|
||||
aps: make(map[string]*AccessPoint),
|
||||
iface: iface,
|
||||
newCb: newcb,
|
||||
lostCb: lostcb,
|
||||
aps: make(map[string]*AccessPoint),
|
||||
aliases: aliases,
|
||||
iface: iface,
|
||||
newCb: newcb,
|
||||
lostCb: lostcb,
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,6 +137,7 @@ func (w *WiFi) AddIfNew(ssid, mac string, frequency int, rssi int8) (*AccessPoin
|
||||
defer w.Unlock()
|
||||
|
||||
mac = NormalizeMac(mac)
|
||||
alias := w.aliases.GetOr(mac, "")
|
||||
if ap, found := w.aps[mac]; found {
|
||||
ap.LastSeen = time.Now()
|
||||
if rssi != 0 {
|
||||
@ -143,10 +147,15 @@ func (w *WiFi) AddIfNew(ssid, mac string, frequency int, rssi int8) (*AccessPoin
|
||||
if !isBogusMacESSID(ssid) {
|
||||
ap.Hostname = ssid
|
||||
}
|
||||
|
||||
if alias != "" {
|
||||
ap.Alias = alias
|
||||
}
|
||||
return ap, false
|
||||
}
|
||||
|
||||
newAp := NewAccessPoint(ssid, mac, frequency, rssi)
|
||||
newAp := NewAccessPoint(ssid, mac, frequency, rssi, w.aliases)
|
||||
newAp.Alias = alias
|
||||
w.aps[mac] = newAp
|
||||
|
||||
if w.newCb != nil {
|
||||
|
@ -12,6 +12,7 @@ type AccessPoint struct {
|
||||
*Station
|
||||
sync.Mutex
|
||||
|
||||
aliases *data.UnsortedKV
|
||||
clients map[string]*Station
|
||||
withKeyMaterial bool
|
||||
}
|
||||
@ -22,9 +23,10 @@ type apJSON struct {
|
||||
Handshake bool `json:"handshake"`
|
||||
}
|
||||
|
||||
func NewAccessPoint(essid, bssid string, frequency int, rssi int8) *AccessPoint {
|
||||
func NewAccessPoint(essid, bssid string, frequency int, rssi int8, aliases *data.UnsortedKV) *AccessPoint {
|
||||
return &AccessPoint{
|
||||
Station: NewStation(essid, bssid, frequency, rssi),
|
||||
aliases: aliases,
|
||||
clients: make(map[string]*Station),
|
||||
}
|
||||
}
|
||||
@ -67,11 +69,12 @@ func (ap *AccessPoint) RemoveClient(mac string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) AddClientIfNew(bssid string, frequency int, rssi int8, aliases *data.UnsortedKV) (*Station, bool) {
|
||||
func (ap *AccessPoint) AddClientIfNew(bssid string, frequency int, rssi int8) (*Station, bool) {
|
||||
ap.Lock()
|
||||
defer ap.Unlock()
|
||||
|
||||
bssid = NormalizeMac(bssid)
|
||||
alias := ap.aliases.GetOr(bssid, "")
|
||||
|
||||
if s, found := ap.clients[bssid]; found {
|
||||
// update
|
||||
@ -79,17 +82,15 @@ func (ap *AccessPoint) AddClientIfNew(bssid string, frequency int, rssi int8, al
|
||||
s.RSSI = rssi
|
||||
s.LastSeen = time.Now()
|
||||
|
||||
if aliases != nil {
|
||||
s.Alias = aliases.GetOr(bssid, "")
|
||||
if alias != "" {
|
||||
s.Alias = alias
|
||||
}
|
||||
|
||||
return s, false
|
||||
}
|
||||
|
||||
s := NewStation("", bssid, frequency, rssi)
|
||||
if aliases != nil {
|
||||
s.Alias = aliases.GetOr(bssid, "")
|
||||
}
|
||||
s.Alias = alias
|
||||
ap.clients[bssid] = s
|
||||
|
||||
return s, true
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"github.com/bettercap/bettercap/network"
|
||||
"github.com/bettercap/bettercap/packets"
|
||||
|
||||
"github.com/evilsocket/islazy/data"
|
||||
"github.com/evilsocket/islazy/fs"
|
||||
"github.com/evilsocket/islazy/log"
|
||||
"github.com/evilsocket/islazy/ops"
|
||||
@ -54,6 +55,10 @@ type GPS struct {
|
||||
Separation float64 // Geoidal separation
|
||||
}
|
||||
|
||||
const AliasesFile = "~/bettercap.aliases"
|
||||
|
||||
var aliasesFileName, _ = fs.Expand(AliasesFile)
|
||||
|
||||
type Session struct {
|
||||
Options core.Options
|
||||
Interface *network.Endpoint
|
||||
@ -68,6 +73,7 @@ type Session struct {
|
||||
Active bool
|
||||
GPS GPS
|
||||
Modules ModuleList
|
||||
Aliases *data.UnsortedKV
|
||||
|
||||
Input *readline.Instance
|
||||
Prompt Prompt
|
||||
@ -115,6 +121,10 @@ func New() (*Session, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.Aliases, err = data.NewUnsortedKV(aliasesFileName, data.FlushOnEdit); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.Events = NewEventPool(*s.Options.Debug, *s.Options.Silent)
|
||||
|
||||
s.registerCoreHandlers()
|
||||
@ -235,25 +245,25 @@ func (s *Session) Start() error {
|
||||
|
||||
s.Firewall = firewall.Make(s.Interface)
|
||||
|
||||
s.HID = network.NewHID(func(dev *network.HIDDevice) {
|
||||
s.HID = network.NewHID(s.Aliases, func(dev *network.HIDDevice) {
|
||||
s.Events.Add("hid.device.new", dev)
|
||||
}, func(dev *network.HIDDevice) {
|
||||
s.Events.Add("hid.device.lost", dev)
|
||||
})
|
||||
|
||||
s.BLE = network.NewBLE(func(dev *network.BLEDevice) {
|
||||
s.BLE = network.NewBLE(s.Aliases, func(dev *network.BLEDevice) {
|
||||
s.Events.Add("ble.device.new", dev)
|
||||
}, func(dev *network.BLEDevice) {
|
||||
s.Events.Add("ble.device.lost", dev)
|
||||
})
|
||||
|
||||
s.WiFi = network.NewWiFi(s.Interface, func(ap *network.AccessPoint) {
|
||||
s.WiFi = network.NewWiFi(s.Interface, s.Aliases, func(ap *network.AccessPoint) {
|
||||
s.Events.Add("wifi.ap.new", ap)
|
||||
}, func(ap *network.AccessPoint) {
|
||||
s.Events.Add("wifi.ap.lost", ap)
|
||||
})
|
||||
|
||||
s.Lan = network.NewLAN(s.Interface, s.Gateway, func(e *network.Endpoint) {
|
||||
s.Lan = network.NewLAN(s.Interface, s.Gateway, s.Aliases, func(e *network.Endpoint) {
|
||||
s.Events.Add("endpoint.new", e)
|
||||
}, func(e *network.Endpoint) {
|
||||
s.Events.Add("endpoint.lost", e)
|
||||
|
@ -271,13 +271,55 @@ func (s *Session) shHandler(args []string, sess *Session) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func normalizeMac(mac string) string {
|
||||
var parts []string
|
||||
if strings.ContainsRune(mac, '-') {
|
||||
parts = strings.Split(mac, "-")
|
||||
} else {
|
||||
parts = strings.Split(mac, ":")
|
||||
}
|
||||
|
||||
for i, p := range parts {
|
||||
if len(p) < 2 {
|
||||
parts[i] = "0" + p
|
||||
}
|
||||
}
|
||||
return strings.ToLower(strings.Join(parts, ":"))
|
||||
}
|
||||
|
||||
func (s *Session) propagateAlias(mac, alias string) {
|
||||
mac = normalizeMac(mac)
|
||||
|
||||
s.Aliases.Set(mac, alias)
|
||||
|
||||
if dev, found := s.BLE.Get(mac); found {
|
||||
dev.Alias = alias
|
||||
}
|
||||
|
||||
if dev, found := s.HID.Get(mac); found {
|
||||
dev.Alias = alias
|
||||
}
|
||||
|
||||
if ap, found := s.WiFi.Get(mac); found {
|
||||
ap.Alias = alias
|
||||
}
|
||||
|
||||
if sta, found := s.WiFi.GetClient(mac); found {
|
||||
sta.Alias = alias
|
||||
}
|
||||
|
||||
if host, found := s.Lan.Get(mac); found {
|
||||
host.Alias = alias
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) aliasHandler(args []string, sess *Session) error {
|
||||
mac := args[0]
|
||||
alias := str.Trim(args[1])
|
||||
if alias == "\"\"" || alias == "''" {
|
||||
alias = ""
|
||||
}
|
||||
s.Lan.SetAliasFor(mac, alias)
|
||||
s.propagateAlias(mac, alias)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -383,7 +425,7 @@ func (s *Session) registerCoreHandlers() {
|
||||
readline.PcItem("!"))
|
||||
|
||||
s.addHandler(NewCommandHandler("alias MAC NAME",
|
||||
"^alias\\s+([a-fA-F0-9:]{17})\\s*(.*)",
|
||||
"^alias\\s+([a-fA-F0-9:]{14,17})\\s*(.*)",
|
||||
"Assign an alias to a given endpoint given its MAC address.",
|
||||
s.aliasHandler),
|
||||
readline.PcItem("alias", readline.PcItemDynamic(func(prefix string) []string {
|
||||
|
Loading…
x
Reference in New Issue
Block a user