tea.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env python2
  2. #
  3. # Reads the ESSIDS from probe requests aloud.
  4. #
  5. # Requirements: A wifi driver that supports monitor mode.
  6. # python2, festival, tcpdump, a tool for channel hopping
  7. # Acknowledge the true character of deceptively imperceptible technology!
  8. # Sending out probe requests all the time in client mode doesn't even make much sense from an engineering standpoint. It's a gratuitously dopey standard that serves no discernible purpose except for wasting battery power and making you trackable. AP beacons should suffice!
  9. import subprocess
  10. import re
  11. import os
  12. import sys
  13. import prepoui
  14. import threading
  15. from threading import Thread
  16. basedir = "."
  17. IFACE = "wlp2s0"
  18. # mon0"
  19. THRESHOLD = -65
  20. def install_lexrules(sayer):
  21. sayer.stdin.write("""
  22. (lex.add.entry '( "wifi" n ((( w ay ) 1) (( f ay ) 0))) )\n
  23. """)
  24. sayer.stdin.flush()
  25. class X:
  26. def launchpcap(self):
  27. self.pcap = subprocess.Popen(["sudo", "tcpdump", "-evnl", "-I", "-i", IFACE, "type mgt subtype probe-req"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  28. while (1):
  29. line = self.pcap.stdout.readline()
  30. if line == '':
  31. break
  32. self.process(line)
  33. def process(self, line):
  34. xre = r'([^\s]+) ([^\s]+) tsft (?:short preamble )?([^\s]+) Mb/s ([^\s]+) MHz ([^\s]+) ([^\s]+)dBm? signal (?:antenna )?.* BSSID:([^\s]+) DA:([^\s]+) SA:([^\s]+) (.+)'
  35. try:
  36. m = re.match(xre, line).groups()
  37. time = m[0]
  38. hhmmss = m[0][0:8]
  39. us = m[1]
  40. freq = m[2]
  41. dB = m[5]
  42. bssid = m[6]
  43. da = m[7]
  44. sa = m[8]
  45. ouisa = m[8][0:2]+m[8][3:5]+m[8][6:8]
  46. sarest = m[8][9:11]+m[8][12:14]+m[8][15:17]
  47. manusa = self.t.definitive(ouisa)
  48. what = m[9]
  49. m2 = re.match(r'Probe Request \((.*)\)', what)
  50. if m2:
  51. # subprocess.Popen(["aplay", "alert.wav"], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  52. name = m2.groups()[0]
  53. if (sa, name) in self.seen:
  54. try:
  55. dbval = int(dB)
  56. if dbval > self.seendB[sa]:
  57. self.seendB[sa] = dbval
  58. if dbval > THRESHOLD:
  59. print (manusa,sarest,name,dB), "approaching"
  60. except ValueError, ve:
  61. print ve
  62. else:
  63. # subprocess.Popen(["aplay", "alert.wav"], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  64. self.seen.add((sa, name))
  65. try:
  66. dbval = int(dB)
  67. self.seendB[sa] = dbval
  68. except ValueError, ve:
  69. print ve
  70. print (manusa, sarest, name, dB)
  71. if name != '':
  72. self.say(name)
  73. except AttributeError, ae:
  74. print ae
  75. print line
  76. def say(self, name):
  77. escaped = name.replace('"', '\\"')
  78. self.sayer.stdin.write("(SayText \"%s\")\n" % escaped)
  79. self.sayer.stdin.flush()
  80. def launchsayer(self):
  81. self.sayer = subprocess.Popen(["festival"], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  82. install_lexrules(self.sayer)
  83. def __init__(self):
  84. try:
  85. self.t = prepoui.Thingum() # DB conn
  86. self.seen = set() # already seen probes
  87. self.seendB = {} # signal strengths of remembererd probes
  88. except KeyboardInterrupt, ki:
  89. print ki
  90. sys.exit(0)
  91. except Exception, e:
  92. print e
  93. sys.exit(-1)
  94. def run(self):
  95. try:
  96. self.launchsayer()
  97. self.launchpcap()
  98. except KeyboardInterrupt, ki:
  99. print ki
  100. sys.exit(0)
  101. except Exception, e:
  102. print e
  103. sys.exit(-1)
  104. if __name__ == "__main__":
  105. """
  106. Squat.
  107. """
  108. x = X()
  109. x.run()