hid_recon.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package hid
  2. import (
  3. "time"
  4. "github.com/bettercap/nrf24"
  5. "github.com/google/gousb"
  6. )
  7. func (mod *HIDRecon) doHopping() {
  8. mod.writeLock.Lock()
  9. defer mod.writeLock.Unlock()
  10. if mod.inPromMode == false {
  11. if err := mod.dongle.EnterPromiscMode(); err != nil {
  12. mod.Error("error entering promiscuous mode: %v", err)
  13. } else {
  14. mod.inSniffMode = false
  15. mod.inPromMode = true
  16. mod.Debug("device entered promiscuous mode")
  17. }
  18. }
  19. if time.Since(mod.lastHop) >= mod.hopPeriod {
  20. mod.channel++
  21. if mod.channel > nrf24.TopChannel {
  22. mod.channel = 1
  23. }
  24. if err := mod.dongle.SetChannel(mod.channel); err != nil {
  25. if err == gousb.ErrorNoDevice || err == gousb.TransferStall {
  26. mod.Error("device disconnected, stopping module")
  27. mod.forceStop()
  28. return
  29. } else {
  30. mod.Warning("error hopping on channel %d: %v", mod.channel, err)
  31. }
  32. } else {
  33. mod.lastHop = time.Now()
  34. }
  35. }
  36. }
  37. func (mod *HIDRecon) onDeviceDetected(buf []byte) {
  38. if sz := len(buf); sz >= 5 {
  39. addr, payload := buf[0:5], buf[5:]
  40. mod.Debug("detected device %x on channel %d (payload:%x)\n", addr, mod.channel, payload)
  41. if isNew, dev := mod.Session.HID.AddIfNew(addr, mod.channel, payload); isNew {
  42. // sniff for a while in order to detect the device type
  43. go func() {
  44. prevSilent := mod.sniffSilent
  45. if err := mod.setSniffMode(dev.Address, true); err == nil {
  46. mod.Debug("detecting device type ...")
  47. defer func() {
  48. mod.sniffLock.Unlock()
  49. mod.setSniffMode("clear", prevSilent)
  50. }()
  51. // make sure nobody can sniff to another
  52. // address until we're not done here...
  53. mod.sniffLock.Lock()
  54. time.Sleep(mod.sniffPeriod)
  55. } else {
  56. mod.Warning("error while sniffing %s: %v", dev.Address, err)
  57. }
  58. }()
  59. }
  60. }
  61. }
  62. func (mod *HIDRecon) devPruner() {
  63. mod.waitGroup.Add(1)
  64. defer mod.waitGroup.Done()
  65. maxDeviceTTL := time.Duration(mod.devTTL) * time.Second
  66. mod.Debug("devices pruner started with ttl %v", maxDeviceTTL)
  67. for mod.Running() {
  68. for _, dev := range mod.Session.HID.Devices() {
  69. sinceLastSeen := time.Since(dev.LastSeen)
  70. if sinceLastSeen > maxDeviceTTL {
  71. mod.Debug("device %s not seen in %s, removing.", dev.Address, sinceLastSeen)
  72. mod.Session.HID.Remove(dev.Address)
  73. }
  74. }
  75. time.Sleep(30 * time.Second)
  76. }
  77. }
  78. func (mod *HIDRecon) Start() error {
  79. if err := mod.Configure(); err != nil {
  80. return err
  81. }
  82. return mod.SetRunning(true, func() {
  83. mod.waitGroup.Add(1)
  84. defer mod.waitGroup.Done()
  85. go mod.devPruner()
  86. mod.Info("hopping on %d channels every %s", nrf24.TopChannel, mod.hopPeriod)
  87. for mod.Running() {
  88. if mod.isSniffing() {
  89. mod.doPing()
  90. } else {
  91. mod.doHopping()
  92. }
  93. if mod.isInjecting() {
  94. mod.doInjection()
  95. mod.setInjectionMode("clear")
  96. continue
  97. }
  98. buf, err := mod.dongle.ReceivePayload()
  99. if err != nil {
  100. if err == gousb.ErrorNoDevice || err == gousb.TransferStall {
  101. mod.Error("device disconnected, stopping module")
  102. mod.forceStop()
  103. return
  104. }
  105. mod.Warning("error receiving payload from channel %d: %v", mod.channel, err)
  106. continue
  107. }
  108. if mod.isSniffing() {
  109. mod.onSniffedBuffer(buf)
  110. } else {
  111. mod.onDeviceDetected(buf)
  112. }
  113. }
  114. mod.Debug("stopped")
  115. })
  116. }