mirror of
https://github.com/bettercap/bettercap
synced 2025-08-19 21:13:18 -07:00
new: new ble.show.filter, ble.show.limit and ble.show.sort parameters
This commit is contained in:
parent
93a68bee27
commit
d62090267e
3 changed files with 112 additions and 13 deletions
|
@ -10,6 +10,7 @@ import (
|
||||||
golog "log"
|
golog "log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bettercap/bettercap/modules/utils"
|
||||||
"github.com/bettercap/bettercap/network"
|
"github.com/bettercap/bettercap/network"
|
||||||
"github.com/bettercap/bettercap/session"
|
"github.com/bettercap/bettercap/session"
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ type BLERecon struct {
|
||||||
connTimeout time.Duration
|
connTimeout time.Duration
|
||||||
quit chan bool
|
quit chan bool
|
||||||
done chan bool
|
done chan bool
|
||||||
|
selector *utils.ViewSelector
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBLERecon(s *session.Session) *BLERecon {
|
func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
|
@ -39,6 +41,10 @@ func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
connected: false,
|
connected: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod.selector = utils.ViewSelectorFor(&mod.SessionModule,
|
||||||
|
"ble.show",
|
||||||
|
[]string{"rssi", "mac", "seen"}, "rssi asc")
|
||||||
|
|
||||||
mod.AddHandler(session.NewModuleHandler("ble.recon on", "",
|
mod.AddHandler(session.NewModuleHandler("ble.recon on", "",
|
||||||
"Start Bluetooth Low Energy devices discovery.",
|
"Start Bluetooth Low Energy devices discovery.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
|
|
|
@ -12,5 +12,22 @@ type ByBLERSSISorter []*network.BLEDevice
|
||||||
func (a ByBLERSSISorter) Len() int { return len(a) }
|
func (a ByBLERSSISorter) Len() int { return len(a) }
|
||||||
func (a ByBLERSSISorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
func (a ByBLERSSISorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
func (a ByBLERSSISorter) Less(i, j int) bool {
|
func (a ByBLERSSISorter) Less(i, j int) bool {
|
||||||
|
if a[i].RSSI == a[j].RSSI {
|
||||||
|
return a[i].Device.ID() < a[j].Device.ID()
|
||||||
|
}
|
||||||
return a[i].RSSI > a[j].RSSI
|
return a[i].RSSI > a[j].RSSI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ByBLEMacSorter []*network.BLEDevice
|
||||||
|
|
||||||
|
func (a ByBLEMacSorter) Len() int { return len(a) }
|
||||||
|
func (a ByBLEMacSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
|
func (a ByBLEMacSorter) Less(i, j int) bool {
|
||||||
|
return a[i].Device.ID() < a[j].Device.ID()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ByBLESeenSorter []*network.BLEDevice
|
||||||
|
|
||||||
|
func (a ByBLESeenSorter) Len() int { return len(a) }
|
||||||
|
func (a ByBLESeenSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
|
func (a ByBLESeenSorter) Less(i, j int) bool { return a[i].LastSeen.Before(a[j].LastSeen) }
|
||||||
|
|
|
@ -24,8 +24,20 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
||||||
|
// ref. https://www.metageek.com/training/resources/understanding-rssi-2.html
|
||||||
|
rssi := fmt.Sprintf("%d dBm", dev.RSSI)
|
||||||
|
if dev.RSSI >= -67 {
|
||||||
|
rssi = tui.Green(rssi)
|
||||||
|
} else if dev.RSSI >= -70 {
|
||||||
|
rssi = tui.Dim(tui.Green(rssi))
|
||||||
|
} else if dev.RSSI >= -80 {
|
||||||
|
rssi = tui.Yellow(rssi)
|
||||||
|
} else {
|
||||||
|
rssi = tui.Dim(tui.Red(rssi))
|
||||||
|
}
|
||||||
|
|
||||||
address := network.NormalizeMac(dev.Device.ID())
|
address := network.NormalizeMac(dev.Device.ID())
|
||||||
vendor := dev.Vendor
|
vendor := tui.Dim(dev.Vendor)
|
||||||
sinceSeen := time.Since(dev.LastSeen)
|
sinceSeen := time.Since(dev.LastSeen)
|
||||||
lastSeen := dev.LastSeen.Format("15:04:05")
|
lastSeen := dev.LastSeen.Format("15:04:05")
|
||||||
|
|
||||||
|
@ -36,13 +48,13 @@ func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
||||||
address = tui.Dim(address)
|
address = tui.Dim(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
isConnectable := tui.Red("no")
|
isConnectable := tui.Red("✖")
|
||||||
if dev.Advertisement.Connectable {
|
if dev.Advertisement.Connectable {
|
||||||
isConnectable = tui.Green("yes")
|
isConnectable = tui.Green("✔")
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{
|
return []string{
|
||||||
fmt.Sprintf("%d dBm", dev.RSSI),
|
rssi,
|
||||||
address,
|
address,
|
||||||
dev.Device.Name(),
|
dev.Device.Name(),
|
||||||
vendor,
|
vendor,
|
||||||
|
@ -51,24 +63,88 @@ func (mod *BLERecon) getRow(dev *network.BLEDevice) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *BLERecon) Show() error {
|
func (mod *BLERecon) doFilter(dev *network.BLEDevice) bool {
|
||||||
devices := mod.Session.BLE.Devices()
|
if mod.selector.Expression == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return mod.selector.Expression.MatchString(dev.Device.ID()) ||
|
||||||
|
mod.selector.Expression.MatchString(dev.Device.Name()) ||
|
||||||
|
mod.selector.Expression.MatchString(dev.Vendor)
|
||||||
|
}
|
||||||
|
|
||||||
sort.Sort(ByBLERSSISorter(devices))
|
func (mod *BLERecon) doSelection() (err error, devices []*network.BLEDevice) {
|
||||||
|
if err = mod.selector.Update(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
devices = mod.Session.BLE.Devices()
|
||||||
|
filtered := []*network.BLEDevice{}
|
||||||
|
for _, dev := range devices {
|
||||||
|
if mod.doFilter(dev) {
|
||||||
|
filtered = append(filtered, dev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
devices = filtered
|
||||||
|
|
||||||
|
switch mod.selector.SortField {
|
||||||
|
case "mac":
|
||||||
|
sort.Sort(ByBLEMacSorter(devices))
|
||||||
|
case "seen":
|
||||||
|
sort.Sort(ByBLESeenSorter(devices))
|
||||||
|
default:
|
||||||
|
sort.Sort(ByBLERSSISorter(devices))
|
||||||
|
}
|
||||||
|
|
||||||
|
// default is asc
|
||||||
|
if mod.selector.Sort == "desc" {
|
||||||
|
// from https://github.com/golang/go/wiki/SliceTricks
|
||||||
|
for i := len(devices)/2 - 1; i >= 0; i-- {
|
||||||
|
opp := len(devices) - 1 - i
|
||||||
|
devices[i], devices[opp] = devices[opp], devices[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mod.selector.Limit > 0 {
|
||||||
|
limit := mod.selector.Limit
|
||||||
|
max := len(devices)
|
||||||
|
if limit > max {
|
||||||
|
limit = max
|
||||||
|
}
|
||||||
|
devices = devices[0:limit]
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *BLERecon) colNames() []string {
|
||||||
|
colNames := []string{"RSSI", "MAC", "Name", "Vendor", "Connectable", "Seen"}
|
||||||
|
switch mod.selector.SortField {
|
||||||
|
case "rssi":
|
||||||
|
colNames[0] += " " + mod.selector.SortSymbol
|
||||||
|
case "mac":
|
||||||
|
colNames[1] += " " + mod.selector.SortSymbol
|
||||||
|
case "seen":
|
||||||
|
colNames[5] += " " + mod.selector.SortSymbol
|
||||||
|
}
|
||||||
|
return colNames
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mod *BLERecon) Show() error {
|
||||||
|
err, devices := mod.doSelection()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
rows := make([][]string, 0)
|
rows := make([][]string, 0)
|
||||||
for _, dev := range devices {
|
for _, dev := range devices {
|
||||||
rows = append(rows, mod.getRow(dev))
|
rows = append(rows, mod.getRow(dev))
|
||||||
}
|
}
|
||||||
nrows := len(rows)
|
|
||||||
|
|
||||||
columns := []string{"RSSI", "Address", "Name", "Vendor", "Connectable", "Last Seen"}
|
if len(rows) > 0 {
|
||||||
|
tui.Table(os.Stdout, mod.colNames(), rows)
|
||||||
if nrows > 0 {
|
mod.Session.Refresh()
|
||||||
tui.Table(os.Stdout, columns, rows)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.Session.Refresh()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue