mirror of
https://github.com/bettercap/bettercap
synced 2025-08-19 21:13:18 -07:00
new: ble.enum and ble.write now support autocompletion
This commit is contained in:
parent
742e7fd8bb
commit
49e2116d46
4 changed files with 55 additions and 12 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
golog "log"
|
golog "log"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bettercap/bettercap/modules/utils"
|
"github.com/bettercap/bettercap/modules/utils"
|
||||||
|
@ -63,7 +64,7 @@ func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
return mod.Show()
|
return mod.Show()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
mod.AddHandler(session.NewModuleHandler("ble.enum MAC", "ble.enum "+network.BLEMacValidator,
|
enum := session.NewModuleHandler("ble.enum MAC", "ble.enum "+network.BLEMacValidator,
|
||||||
"Enumerate services and characteristics for the given BLE device.",
|
"Enumerate services and characteristics for the given BLE device.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
if mod.isEnumerating() {
|
if mod.isEnumerating() {
|
||||||
|
@ -74,9 +75,13 @@ func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
mod.writeUUID = nil
|
mod.writeUUID = nil
|
||||||
|
|
||||||
return mod.enumAllTheThings(network.NormalizeMac(args[0]))
|
return mod.enumAllTheThings(network.NormalizeMac(args[0]))
|
||||||
}))
|
})
|
||||||
|
|
||||||
mod.AddHandler(session.NewModuleHandler("ble.write MAC UUID HEX_DATA", "ble.write "+network.BLEMacValidator+" ([a-fA-F0-9]+) ([a-fA-F0-9]+)",
|
enum.Complete("ble.enum", mod.macCompleter)
|
||||||
|
|
||||||
|
mod.AddHandler(enum)
|
||||||
|
|
||||||
|
write := session.NewModuleHandler("ble.write MAC UUID HEX_DATA", "ble.write "+network.BLEMacValidator+" ([a-fA-F0-9]+) ([a-fA-F0-9]+)",
|
||||||
"Write the HEX_DATA buffer to the BLE device with the specified MAC address, to the characteristics with the given UUID.",
|
"Write the HEX_DATA buffer to the BLE device with the specified MAC address, to the characteristics with the given UUID.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
mac := network.NormalizeMac(args[0])
|
mac := network.NormalizeMac(args[0])
|
||||||
|
@ -90,7 +95,11 @@ func NewBLERecon(s *session.Session) *BLERecon {
|
||||||
}
|
}
|
||||||
|
|
||||||
return mod.writeBuffer(mac, uuid, data)
|
return mod.writeBuffer(mac, uuid, data)
|
||||||
}))
|
})
|
||||||
|
|
||||||
|
write.Complete("ble.write", mod.macCompleter)
|
||||||
|
|
||||||
|
mod.AddHandler(write)
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
@ -107,6 +116,16 @@ func (mod BLERecon) Author() string {
|
||||||
return "Simone Margaritelli <evilsocket@gmail.com>"
|
return "Simone Margaritelli <evilsocket@gmail.com>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mod *BLERecon) macCompleter(prefix string) []string {
|
||||||
|
macs := []string{""}
|
||||||
|
mod.Session.BLE.EachDevice(func(mac string, dev *network.BLEDevice) {
|
||||||
|
if prefix == "" || strings.HasPrefix(mac, prefix) {
|
||||||
|
macs = append(macs, mac)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return macs
|
||||||
|
}
|
||||||
|
|
||||||
func (mod *BLERecon) isEnumerating() bool {
|
func (mod *BLERecon) isEnumerating() bool {
|
||||||
return mod.currDevice != nil
|
return mod.currDevice != nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,3 +95,12 @@ func (b *BLE) Devices() (devices []*BLEDevice) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BLE) EachDevice(cb func(mac string, d *BLEDevice)) {
|
||||||
|
b.Lock()
|
||||||
|
defer b.Unlock()
|
||||||
|
|
||||||
|
for m, dev := range b.devices {
|
||||||
|
cb(m, dev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,10 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/evilsocket/islazy/str"
|
||||||
"github.com/evilsocket/islazy/tui"
|
"github.com/evilsocket/islazy/tui"
|
||||||
|
|
||||||
|
"github.com/bettercap/readline"
|
||||||
)
|
)
|
||||||
|
|
||||||
const IPv4Validator = `^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$`
|
const IPv4Validator = `^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$`
|
||||||
|
@ -16,6 +19,7 @@ type ModuleHandler struct {
|
||||||
Description string
|
Description string
|
||||||
Parser *regexp.Regexp
|
Parser *regexp.Regexp
|
||||||
Exec func(args []string) error
|
Exec func(args []string) error
|
||||||
|
Completer *readline.PrefixCompleter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewModuleHandler(name string, expr string, desc string, exec func(args []string) error) ModuleHandler {
|
func NewModuleHandler(name string, expr string, desc string, exec func(args []string) error) ModuleHandler {
|
||||||
|
@ -33,6 +37,13 @@ func NewModuleHandler(name string, expr string, desc string, exec func(args []st
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *ModuleHandler) Complete(name string, cb func(prefix string) []string) {
|
||||||
|
h.Completer = readline.PcItem(name, readline.PcItemDynamic(func(prefix string) []string {
|
||||||
|
prefix = str.Trim(prefix[len(name):])
|
||||||
|
return cb(prefix)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
func (h *ModuleHandler) Help(padding int) string {
|
func (h *ModuleHandler) Help(padding int) string {
|
||||||
return fmt.Sprintf(" "+tui.Bold("%"+strconv.Itoa(padding)+"s")+" : %s\n", h.Name, h.Description)
|
return fmt.Sprintf(" "+tui.Bold("%"+strconv.Itoa(padding)+"s")+" : %s\n", h.Name, h.Description)
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,17 +38,21 @@ func (s *Session) setupReadline() (err error) {
|
||||||
tree := make(map[string][]string)
|
tree := make(map[string][]string)
|
||||||
for _, m := range s.Modules {
|
for _, m := range s.Modules {
|
||||||
for _, h := range m.Handlers() {
|
for _, h := range m.Handlers() {
|
||||||
parts := strings.Split(h.Name, " ")
|
if h.Completer == nil {
|
||||||
name := parts[0]
|
parts := strings.Split(h.Name, " ")
|
||||||
|
name := parts[0]
|
||||||
|
|
||||||
if _, found := tree[name]; !found {
|
if _, found := tree[name]; !found {
|
||||||
tree[name] = []string{}
|
tree[name] = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var appendedOption = strings.Join(parts[1:], " ")
|
var appendedOption = strings.Join(parts[1:], " ")
|
||||||
|
|
||||||
if len(appendedOption) > 0 && !containsCapitals(appendedOption) {
|
if len(appendedOption) > 0 && !containsCapitals(appendedOption) {
|
||||||
tree[name] = append(tree[name], appendedOption)
|
tree[name] = append(tree[name], appendedOption)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prefixCompleters = append(prefixCompleters, h.Completer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue