mirror of
https://github.com/bettercap/bettercap
synced 2025-08-19 21:13:18 -07:00
new: parsing RSSI ( ref #53 )
This commit is contained in:
parent
35c9740537
commit
0ad426024f
6 changed files with 98 additions and 30 deletions
|
@ -44,17 +44,18 @@ func (w *WiFi) Remove(mac string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFi) AddIfNew(ssid, mac string, isAp bool, channel int) *WiFiStation {
|
func (w *WiFi) AddIfNew(ssid, mac string, isAp bool, channel int, rssi int8) *WiFiStation {
|
||||||
w.Lock()
|
w.Lock()
|
||||||
defer w.Unlock()
|
defer w.Unlock()
|
||||||
|
|
||||||
mac = network.NormalizeMac(mac)
|
mac = network.NormalizeMac(mac)
|
||||||
if station, found := w.Stations[mac]; found {
|
if station, found := w.Stations[mac]; found {
|
||||||
w.Stations[mac].LastSeen = time.Now()
|
station.LastSeen = time.Now()
|
||||||
|
station.RSSI = rssi
|
||||||
return station
|
return station
|
||||||
}
|
}
|
||||||
|
|
||||||
newStation := NewWiFiStation(ssid, mac, isAp, channel)
|
newStation := NewWiFiStation(ssid, mac, isAp, channel, rssi)
|
||||||
w.Stations[mac] = newStation
|
w.Stations[mac] = newStation
|
||||||
|
|
||||||
w.Session.Events.Add("wifi.station.new", newStation)
|
w.Session.Events.Add("wifi.station.new", newStation)
|
||||||
|
|
|
@ -100,7 +100,7 @@ func NewWiFiRecon(s *session.Session) *WiFiRecon {
|
||||||
w.AddHandler(session.NewModuleHandler("wifi.show", "",
|
w.AddHandler(session.NewModuleHandler("wifi.show", "",
|
||||||
"Show current wireless stations list (default sorting by essid).",
|
"Show current wireless stations list (default sorting by essid).",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
return w.Show("channel")
|
return w.Show("rssi")
|
||||||
}))
|
}))
|
||||||
|
|
||||||
w.AddParam(session.NewIntParameter("wifi.recon.channel",
|
w.AddParam(session.NewIntParameter("wifi.recon.channel",
|
||||||
|
@ -142,6 +142,8 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string {
|
||||||
seen = core.Dim(seen)
|
seen = core.Dim(seen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
encryption := w.stats.EncryptionOf(station.HW)
|
||||||
|
|
||||||
sent := ""
|
sent := ""
|
||||||
bytes := w.stats.SentFrom(station.HW)
|
bytes := w.stats.SentFrom(station.HW)
|
||||||
if bytes > 0 {
|
if bytes > 0 {
|
||||||
|
@ -155,9 +157,11 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
row := []string{
|
row := []string{
|
||||||
|
fmt.Sprintf("%d dBm", station.RSSI),
|
||||||
bssid,
|
bssid,
|
||||||
station.ESSID(),
|
station.ESSID(),
|
||||||
station.Vendor,
|
station.Vendor,
|
||||||
|
encryption,
|
||||||
strconv.Itoa(station.Channel),
|
strconv.Itoa(station.Channel),
|
||||||
sent,
|
sent,
|
||||||
recvd,
|
recvd,
|
||||||
|
@ -165,6 +169,7 @@ func (w *WiFiRecon) getRow(station *WiFiStation) []string {
|
||||||
}
|
}
|
||||||
if w.isApSelected() {
|
if w.isApSelected() {
|
||||||
row = []string{
|
row = []string{
|
||||||
|
fmt.Sprintf("%d dBm", station.RSSI),
|
||||||
bssid,
|
bssid,
|
||||||
station.Vendor,
|
station.Vendor,
|
||||||
strconv.Itoa(station.Channel),
|
strconv.Itoa(station.Channel),
|
||||||
|
@ -209,11 +214,13 @@ func (w *WiFiRecon) Show(by string) error {
|
||||||
|
|
||||||
stations := w.wifi.List()
|
stations := w.wifi.List()
|
||||||
if by == "seen" {
|
if by == "seen" {
|
||||||
sort.Sort(BywifiSeenSorter(stations))
|
sort.Sort(ByWiFiSeenSorter(stations))
|
||||||
} else if by == "essid" {
|
} else if by == "essid" {
|
||||||
sort.Sort(ByEssidSorter(stations))
|
sort.Sort(ByEssidSorter(stations))
|
||||||
} else {
|
} else if by == "channel" {
|
||||||
sort.Sort(ByChannelSorter(stations))
|
sort.Sort(ByChannelSorter(stations))
|
||||||
|
} else {
|
||||||
|
sort.Sort(ByRSSISorter(stations))
|
||||||
}
|
}
|
||||||
|
|
||||||
rows := make([][]string, 0)
|
rows := make([][]string, 0)
|
||||||
|
@ -221,10 +228,10 @@ func (w *WiFiRecon) Show(by string) error {
|
||||||
rows = append(rows, w.getRow(s))
|
rows = append(rows, w.getRow(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
columns := []string{"BSSID", "SSID", "Vendor", "Channel", "Sent", "Recvd", "Last Seen"}
|
columns := []string{"RSSI", "BSSID", "SSID", "Vendor", "Encryption", "Channel", "Sent", "Recvd", "Last Seen"}
|
||||||
if w.isApSelected() {
|
if w.isApSelected() {
|
||||||
// these are clients
|
// these are clients
|
||||||
columns = []string{"MAC", "Vendor", "Channel", "Sent", "Received", "Last Seen"}
|
columns = []string{"RSSI", "MAC", "Vendor", "Channel", "Sent", "Received", "Last Seen"}
|
||||||
fmt.Printf("\n%s clients:\n", w.accessPoint.String())
|
fmt.Printf("\n%s clients:\n", w.accessPoint.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +270,6 @@ func (w *WiFiRecon) Configure() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info("WiFi recon active with channel hopping.")
|
log.Info("WiFi recon active with channel hopping.")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.wifi = NewWiFi(w.Session, w.Session.Interface)
|
w.wifi = NewWiFi(w.Session, w.Session.Interface)
|
||||||
|
@ -337,7 +343,7 @@ func (w *WiFiRecon) discoverAccessPoints(radiotap *layers.RadioTap, dot11 *layer
|
||||||
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok == true {
|
if ok, ssid := packets.Dot11ParseIDSSID(packet); ok == true {
|
||||||
bssid := dot11.Address3.String()
|
bssid := dot11.Address3.String()
|
||||||
channel := mhz2chan(int(radiotap.ChannelFrequency))
|
channel := mhz2chan(int(radiotap.ChannelFrequency))
|
||||||
w.wifi.AddIfNew(ssid, bssid, true, channel)
|
w.wifi.AddIfNew(ssid, bssid, true, channel, radiotap.DBMAntennaSignal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,23 +352,27 @@ func (w *WiFiRecon) discoverClients(radiotap *layers.RadioTap, dot11 *layers.Dot
|
||||||
if packets.Dot11IsDataFor(dot11, ap) == true {
|
if packets.Dot11IsDataFor(dot11, ap) == true {
|
||||||
src := dot11.Address2
|
src := dot11.Address2
|
||||||
channel := mhz2chan(int(radiotap.ChannelFrequency))
|
channel := mhz2chan(int(radiotap.ChannelFrequency))
|
||||||
w.wifi.AddIfNew("", src.String(), false, channel)
|
w.wifi.AddIfNew("", src.String(), false, channel, radiotap.DBMAntennaSignal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiRecon) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) {
|
func (w *WiFiRecon) updateStats(dot11 *layers.Dot11, packet gopacket.Packet) {
|
||||||
// only collect stats from data frames
|
// collect stats from data frames
|
||||||
if dot11.Type.MainType() != layers.Dot11TypeData {
|
if dot11.Type.MainType() == layers.Dot11TypeData {
|
||||||
return
|
bytes := uint64(len(packet.Data()))
|
||||||
|
|
||||||
|
dst := dot11.Address1
|
||||||
|
src := dot11.Address2
|
||||||
|
|
||||||
|
w.stats.CollectReceived(dst, bytes)
|
||||||
|
w.stats.CollectSent(src, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes := uint64(len(packet.Data()))
|
if ok, enc := packets.Dot11ParseEncryption(packet, dot11); ok == true {
|
||||||
|
for _, e := range enc {
|
||||||
dst := dot11.Address1
|
w.stats.CollectEncryption(dot11.Address3, e)
|
||||||
src := dot11.Address2
|
}
|
||||||
|
}
|
||||||
w.stats.CollectReceived(dst, bytes)
|
|
||||||
w.stats.CollectSent(src, bytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WiFiRecon) Start() error {
|
func (w *WiFiRecon) Start() error {
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
package modules
|
package modules
|
||||||
|
|
||||||
|
type ByRSSISorter []*WiFiStation
|
||||||
|
|
||||||
|
func (a ByRSSISorter) Len() int { return len(a) }
|
||||||
|
func (a ByRSSISorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
|
func (a ByRSSISorter) Less(i, j int) bool {
|
||||||
|
if a[i].RSSI == a[j].RSSI {
|
||||||
|
return a[i].HwAddress < a[j].HwAddress
|
||||||
|
}
|
||||||
|
return a[i].RSSI > a[j].RSSI
|
||||||
|
}
|
||||||
|
|
||||||
type ByChannelSorter []*WiFiStation
|
type ByChannelSorter []*WiFiStation
|
||||||
|
|
||||||
func (a ByChannelSorter) Len() int { return len(a) }
|
func (a ByChannelSorter) Len() int { return len(a) }
|
||||||
|
@ -22,10 +33,10 @@ func (a ByEssidSorter) Less(i, j int) bool {
|
||||||
return a[i].ESSID() < a[j].ESSID()
|
return a[i].ESSID() < a[j].ESSID()
|
||||||
}
|
}
|
||||||
|
|
||||||
type BywifiSeenSorter []*WiFiStation
|
type ByWiFiSeenSorter []*WiFiStation
|
||||||
|
|
||||||
func (a BywifiSeenSorter) Len() int { return len(a) }
|
func (a ByWiFiSeenSorter) Len() int { return len(a) }
|
||||||
func (a BywifiSeenSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
func (a ByWiFiSeenSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
func (a BywifiSeenSorter) Less(i, j int) bool {
|
func (a ByWiFiSeenSorter) Less(i, j int) bool {
|
||||||
return a[i].LastSeen.After(a[j].LastSeen)
|
return a[i].LastSeen.After(a[j].LastSeen)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,15 @@ type WiFiStation struct {
|
||||||
*network.Endpoint
|
*network.Endpoint
|
||||||
IsAP bool
|
IsAP bool
|
||||||
Channel int
|
Channel int
|
||||||
|
RSSI int8
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWiFiStation(essid, bssid string, isAp bool, channel int) *WiFiStation {
|
func NewWiFiStation(essid, bssid string, isAp bool, channel int, rssi int8) *WiFiStation {
|
||||||
return &WiFiStation{
|
return &WiFiStation{
|
||||||
Endpoint: network.NewEndpointNoResolve(network.MonitorModeAddress, bssid, essid, 0),
|
Endpoint: network.NewEndpointNoResolve(network.MonitorModeAddress, bssid, essid, 0),
|
||||||
IsAP: isAp,
|
IsAP: isAp,
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
|
RSSI: rssi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,22 @@ package modules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WiFiStationStats struct {
|
type WiFiStationStats struct {
|
||||||
Sent uint64
|
Sent uint64
|
||||||
Received uint64
|
Received uint64
|
||||||
|
Encryption map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWiFiStationStats(sent uint64, recvd uint64) *WiFiStationStats {
|
||||||
|
return &WiFiStationStats{
|
||||||
|
Sent: sent,
|
||||||
|
Received: recvd,
|
||||||
|
Encryption: make(map[string]bool),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type WiFiStats struct {
|
type WiFiStats struct {
|
||||||
|
@ -29,7 +39,7 @@ func (s *WiFiStats) CollectSent(station net.HardwareAddr, bytes uint64) {
|
||||||
if sstats, found := s.stats[bssid]; found == true {
|
if sstats, found := s.stats[bssid]; found == true {
|
||||||
sstats.Sent += bytes
|
sstats.Sent += bytes
|
||||||
} else {
|
} else {
|
||||||
s.stats[bssid] = &WiFiStationStats{Sent: bytes}
|
s.stats[bssid] = NewWiFiStationStats(bytes, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +51,21 @@ func (s *WiFiStats) CollectReceived(station net.HardwareAddr, bytes uint64) {
|
||||||
if sstats, found := s.stats[bssid]; found == true {
|
if sstats, found := s.stats[bssid]; found == true {
|
||||||
sstats.Received += bytes
|
sstats.Received += bytes
|
||||||
} else {
|
} else {
|
||||||
s.stats[bssid] = &WiFiStationStats{Received: bytes}
|
s.stats[bssid] = NewWiFiStationStats(0, bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WiFiStats) CollectEncryption(station net.HardwareAddr, enc string) {
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
|
||||||
|
bssid := station.String()
|
||||||
|
if sstats, found := s.stats[bssid]; found == true {
|
||||||
|
sstats.Encryption[enc] = true
|
||||||
|
} else {
|
||||||
|
stats := NewWiFiStationStats(0, 0)
|
||||||
|
stats.Encryption[enc] = true
|
||||||
|
s.stats[bssid] = stats
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,3 +90,18 @@ func (s *WiFiStats) SentTo(station net.HardwareAddr) uint64 {
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *WiFiStats) EncryptionOf(station net.HardwareAddr) string {
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
|
||||||
|
bssid := station.String()
|
||||||
|
if sstats, found := s.stats[bssid]; found == true {
|
||||||
|
unique := make([]string, 0)
|
||||||
|
for key := range sstats.Encryption {
|
||||||
|
unique = append(unique, key)
|
||||||
|
}
|
||||||
|
return strings.Join(unique, ", ")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
@ -66,6 +66,11 @@ func Dot11ParseIDSSID(packet gopacket.Packet) (bool, string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Dot11ParseEncryption(packet gopacket.Packet, dot11 *layers.Dot11) (bool, []string) {
|
||||||
|
// TODO :(
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Dot11IsDataFor(dot11 *layers.Dot11, station net.HardwareAddr) bool {
|
func Dot11IsDataFor(dot11 *layers.Dot11, station net.HardwareAddr) bool {
|
||||||
// only check data packets of connected stations
|
// only check data packets of connected stations
|
||||||
if dot11.Type.MainType() != layers.Dot11TypeData {
|
if dot11.Type.MainType() != layers.Dot11TypeData {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue