/
hid_inject.go
144 lines (118 loc) · 3.63 KB
/
hid_inject.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package hid
import (
"fmt"
"time"
"github.com/bettercap/bettercap/network"
"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, true); err != nil {
return err
} else if address == "clear" {
mod.inInjectMode = false
} else {
mod.inInjectMode = true
}
return nil
}
func errNoDevice(addr string) error {
return fmt.Errorf("HID device %s not found, make sure that hid.recon is on and that this device has been discovered", addr)
}
func errNoType(addr string) error {
return fmt.Errorf("HID frame injection requires the device type to be detected, try to 'hid.sniff %s' for a few seconds.", addr)
}
func errNotSupported(dev *network.HIDDevice) error {
return fmt.Errorf("HID frame injection is not supported for device type %s", dev.Type.String())
}
func errNoKeyMap(layout string) error {
return fmt.Errorf("could not find keymap for '%s' layout, supported layouts are: %s", layout, SupportedLayouts())
}
func (mod *HIDRecon) prepInjection() (error, *network.HIDDevice, []*Command) {
var err error
if err, mod.sniffType = mod.StringParam("hid.force.type"); err != nil {
return err, nil, nil
}
dev, found := mod.Session.HID.Get(mod.sniffAddr)
if found == false {
mod.Warning("device %s is not visible, will use HID type %s", mod.sniffAddr, tui.Yellow(mod.sniffType))
} else if dev.Type == network.HIDTypeUnknown {
mod.Warning("device %s type has not been detected yet, falling back to '%s'", mod.sniffAddr, tui.Yellow(mod.sniffType))
}
var builder FrameBuilder
if found && dev.Type != network.HIDTypeUnknown {
// get the device specific protocol handler
builder, found = FrameBuilders[dev.Type]
if found == false {
return errNotSupported(dev), nil, nil
}
} else {
// get the device protocol handler from the hid.force.type parameter
builder = builderFromName(mod.sniffType)
}
// get the keymap from the selected layout
keyMap := KeyMapFor(mod.keyLayout)
if keyMap == nil {
return errNoKeyMap(mod.keyLayout), nil, nil
}
// parse the script into a list of Command objects
cmds, err := mod.parser.Parse(keyMap, mod.scriptPath)
if err != nil {
return err, nil, nil
}
mod.Info("%s loaded ...", mod.scriptPath)
// build the protocol specific frames to send
if err := builder.BuildFrames(dev, cmds); err != nil {
return err, nil, nil
}
return nil, dev, cmds
}
func (mod *HIDRecon) doInjection() {
mod.writeLock.Lock()
defer mod.writeLock.Unlock()
err, dev, cmds := mod.prepInjection()
if err != nil {
mod.Error("%v", err)
return
}
numFrames := 0
szFrames := 0
for _, cmd := range cmds {
for _, frame := range cmd.Frames {
numFrames++
szFrames += len(frame.Data)
}
}
devType := mod.sniffType
if dev != nil {
devType = dev.Type.String()
}
mod.Info("sending %d (%s) HID frames to %s (type:%s layout:%s) ...",
numFrames,
humanize.Bytes(uint64(szFrames)),
tui.Bold(mod.sniffAddr),
tui.Yellow(devType),
tui.Yellow(mod.keyLayout))
for i, cmd := range cmds {
for j, frame := range cmd.Frames {
for attempt := 0; attempt < 3; attempt++ {
if err := mod.dongle.TransmitPayload(frame.Data, 500, 5); err != nil {
if attempt < 2 {
mod.Debug("error sending frame #%d of HID command #%d: %v, retrying ...", j, i, err)
} else {
mod.Error("error sending frame #%d of HID command #%d: %v", j, i, err)
}
} else {
break
}
}
if frame.Delay > 0 {
mod.Debug("sleeping %dms after frame #%d of command #%d ...", frame.Delay, j, i)
time.Sleep(frame.Delay)
}
}
}
}