doll.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-"
  3. """
  4. This file is part of the UFONet project, https://ufonet.03c8.net
  5. Copyright (c) 2013/2026 | psy <epsylon@riseup.net>
  6. You should have received a copy of the GNU General Public License along
  7. with UFONet; if not, write to the Free Software Foundation, Inc., 51
  8. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9. """
  10. from threading import Thread
  11. import socket, time, os, base64, re
  12. from urllib.parse import urlparse
  13. class Needle(Thread):
  14. def __init__(self, client, addr, parent):
  15. Thread.__init__(self)
  16. self.daemon = True
  17. self.client = client
  18. self.parent = parent
  19. def run(self):
  20. data = self.client.recv(1024)
  21. if data:
  22. if data.startswith("HEAD"):
  23. self.parent.data_arrived(data)
  24. self.client.send("""HTTP/1.1 200 OK
  25. Server: UFONet Galactic Cyber Warfare
  26. Date: Wed, 05 Nov 2042 16:21:23 GMT
  27. Content-Type: text/html
  28. Content-Length: """+str(len('thanks for coming!'))+"""
  29. Connection: close
  30. """)
  31. self.client.close()
  32. else:
  33. self.parent.data_arrived(data)
  34. self.client.send('Welcome to UFONet mothership! ;-)\n')
  35. self.client.send('='*40)
  36. self.client.send("\n\nStream:\n")
  37. self.client.send('-'*15 + "\n\n")
  38. f = open("mothership", 'r') # read mothership stream
  39. self.client.send(str(f.read()))
  40. f.close()
  41. self.client.close()
  42. self.parent.client_finished(self)
  43. class Doll(Thread):
  44. def __init__(self, parent):
  45. Thread.__init__(self)
  46. self.daemon = True
  47. self._clients = []
  48. self._armed = True
  49. self.ready = False
  50. self.running =False
  51. self.parent = parent
  52. self.real_zombies = [] # 100% vulnerable zombies
  53. if os.path.exists('mothership') == True:
  54. os.remove('mothership') # remove mothership stream
  55. with open('alien') as f: # call alien to verify vulnerability
  56. self.alien = f.read().splitlines()
  57. f.close()
  58. def data_arrived(self, data):
  59. data.split("\n")[0]
  60. self.check_zombie(data)
  61. f = open("mothership", 'a') # append data mothership stream
  62. f.write(data)
  63. f.close()
  64. def check_zombie(self, data): # check for requests received by a zombie
  65. if str(''.join(self.alien)) in data: # hash check
  66. if "%7C" in data: # %7C -> |
  67. regex_zmb = re.compile('{}(.*){}'.format(re.escape('%7C'), re.escape(' HTTP'))) # regex magics
  68. else:
  69. regex_zmb = re.compile('{}(.*){}'.format(re.escape('|'), re.escape(' HTTP'))) # regex magics
  70. pattern_zmb = re.compile(regex_zmb)
  71. zombie_vul = re.findall(pattern_zmb, data)
  72. if zombie_vul not in self.real_zombies: # add zombies only one time
  73. self.real_zombies.append(zombie_vul)
  74. def client_finished(self, _thread):
  75. self._clients.remove(_thread)
  76. def shutdown(self):
  77. if self.ready:
  78. self.socket.shutdown(socket.SHUT_RDWR)
  79. self.socket.close()
  80. self.running = False
  81. self._armed = False
  82. self.ready = False
  83. def run(self):
  84. while not self.running and self._armed:
  85. try:
  86. s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
  87. s.bind(('', 8080))
  88. self.running = True
  89. except socket.error as e:
  90. print("\n[Warning] Doll socket busy, retry opening")
  91. if e.errno == 98: # if is in use wait a bit and retry
  92. time.sleep(3)
  93. else:
  94. return
  95. if not self._armed:
  96. print("\n[Error] Doll not armed")
  97. return
  98. self.socket = s
  99. self.ready = True
  100. s.listen(1)
  101. while self.running and self._armed:
  102. try:
  103. conn, addr = s.accept()
  104. except socket.timeout:
  105. print("\n[Warning] Socket is giving timeout...")
  106. pass
  107. except socket.error as e:
  108. if self.ready == False:
  109. return
  110. else:
  111. break
  112. else:
  113. t = Needle(conn, addr, self)
  114. t.start()
  115. self._clients.append(t)
  116. if self.ready:
  117. s.close()
  118. self.ready = False