doll.py 4.5 KB

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