←︎ trollbots :: 6b8e95a


1
commit 6b8e95a01bfa1af317ef6187c1f36d3b1fc4aaf5 (HEAD -> master, origin/master)
2
Author: acidvegas <acid.vegas@acid.vegas>
3
Date:   Thu Apr 2 10:19:57 2020 -0400
4
5
    Updated
6
---
7
 efknockr/README.md            |  27 +++-
8
 efknockr/efknockr.py          | 262 +++++++++++++++++++++++++++++++++++++
9
 efknockr/efknockr/config.py   |  38 ------
10
 efknockr/efknockr/efknockr.py | 292 ------------------------------------------
11
 efknockr/efknockr/msg.txt     |   8 --
12
 5 files changed, 284 insertions(+), 343 deletions(-)
13
14
diff --git a/efknockr/README.md b/efknockr/README.md
15
index 7e4ae52..eed620e 100644
16
--- a/efknockr/README.md
17
+++ b/efknockr/README.md
18
@@ -1,6 +1,23 @@
19
-###### Requirements
20
-* Python  https://www.python.org/downloads/    (latest version)
21
-* PySocks https://pypi.python.org/pypi/PySocks (optional for using the --proxy setting)
22
+# EFknockr
23
+> The most annoying script IRC has ever seen!
24
 
25
-###### Information
26
-For each server defined in the config, the bot will connnect, join every channel, send the lines from msg.txt, mass hilight everyone, and then part.
27
+## Requirements
28
+* [Python](https://www.python.org/downloads/) *(latest version)*
29
+* [PySocks](https://pypi.python.org/pypi/PySocks) *(optional for using the --proxy setting)*
30
+
31
+## Information
32
+For each server defined in the config, the bot will connnect, join every channel, send the lines from msg.txt, mass hilight everyone, and then part.
33
+
34
+For questions, comments, & concerns, please join [#5000](irc://irc.supernets.org/%265000) on [irc.supernets.org](irc://irc.supernets.org/%265000)
35
+
36
+## Todo
37
+* Make use of the [asyncio](https://docs.python.org/3/library/asyncio.html) library.
38
+* Convert text with random unicode & combining diacritics & maybe zero-width characters.
39
+* Dynamic msg files using replacers defined in config.
40
+* Detect global/channel user counts.
41
+* Weechat dcc exploit.
42
+* PM every nick collected after knocking.
43
+* Create an output log of all networks, channels, nicks, and more.
44
+
45
+## Warning
46
+This script is for testing against your own server(s). I am not responsible for how the public uses these.
47
diff --git a/efknockr/efknockr.py b/efknockr/efknockr.py
48
new file mode 100644
49
index 0000000..36e9d3b
50
--- /dev/null
51
+++ b/efknockr/efknockr.py
52
@@ -0,0 +1,262 @@
53
+#!/usr/bin/env python
54
+# EFknockr (EFK) - Developed by acidvegas in Python (https://acid.vegas/trollbots)
55
+# efknockr.py
56
+
57
+'''
58
+
59
+"The most annoying script IRC has ever seen"
60
+
61
+'''
62
+
63
+import argparse
64
+import concurrent.futures
65
+import os
66
+import random
67
+import socket
68
+import ssl
69
+import string
70
+import threading
71
+import time
72
+
73
+class settings:
74
+    mass_hilite = True # Hilite all the users in a channel before parting.
75
+    part_msg    = 'Smell ya l8r'
76
+    proxy       = None # Proxy should be a Socks5 in IP:PORT format.
77
+    register    = True # Register with NickServ before joining channels.
78
+    vhost       = None
79
+
80
+class throttle:
81
+    channels = 3   # Maximum number of channels to be flooding at once.
82
+    delay    = 31  # Delay before sending registering nick (if enabled) and sending /LIST.
83
+    join     = 3   # Delay between each channel join.
84
+    message  = 0.5 # Delay between each message sent to a channel.
85
+    threads  = 100 # Maximum number of threads running.
86
+    timeout  = 15  # Timeout for all sockets.
87
+    users    = 10  # Minimum number of users required in a channel.
88
+
89
+bad_numerics = {
90
+	'404' : 'ERR_CANNOTSENDTOCHAN',
91
+	'405' : 'ERR_TOOMANYCHANNELS',
92
+	'470' : 'ERR_LINKCHANNEL',
93
+	'471' : 'ERR_CHANNELISFULL',
94
+	'473' : 'ERR_INVITEONLYCHAN',
95
+	'474' : 'ERR_BANNEDFROMCHAN',
96
+	'475' : 'ERR_BADCHANNELKEY',
97
+	'477' : 'ERR_NEEDREGGEDNICK',
98
+	'489' : 'ERR_SECUREONLYCHAN',
99
+	'519' : 'ERR_TOOMANYUSERS',
100
+	'520' : 'ERR_OPERONLY'
101
+}
102
+
103
+def debug(msg):
104
+	print(f'{get_time()} | [~] - {msg}')
105
+
106
+def error(msg, reason=None):
107
+	print(f'{get_time()} | [!] - {msg} ({reason})') if reason else print(f'{get_time()} | [!] - {msg}')
108
+
109
+def error_exit(msg):
110
+	raise SystemExit(f'{get_time()} | [!] - {msg}')
111
+
112
+def get_time():
113
+	return time.strftime('%I:%M:%S')
114
+
115
+def rnd():
116
+	return ''.join(random.choice(string.ascii_letters) for _ in range(random.randint(4, 8)))
117
+
118
+class clone:
119
+	def __init__(self, server):
120
+		self.channels = {'all':list(), 'bad':list(), 'current':list(), 'nicks':dict()}
121
+		self.server   = server
122
+		self.sock     = None
123
+		self.port     = 6697 # Fallback to 6667 if SSL fails
124
+
125
+	def attack(self):
126
+		try:
127
+			while self.channels['all']:
128
+				while len(self.channels['current']) >= throttle.channels:
129
+					time.sleep(1)
130
+				chan = random.choice(self.channels['all'])
131
+				self.raw('JOIN ' + chan)
132
+				time.sleep(throttle.join)
133
+				if chan in self.channels['all']:
134
+					self.channels['all'].remove(chan)
135
+			debug('Finished knocking all channels on ' + self.server)
136
+		except Exception as ex:
137
+			error('Error occured in the attack loop!', ex)
138
+		finally:
139
+			self.event_disconnect()
140
+
141
+	def connect(self):
142
+		try:
143
+			self.create_socket()
144
+			self.sock.connect((self.server, self.port))
145
+			self.raw('USER {rnd()} 0 * :{rnd()}')
146
+			self.raw('NICK ' + rnd())
147
+		except socket.error:
148
+			if self.port == 6697:
149
+				self.port = 6667
150
+				self.connect()
151
+			else:
152
+				self.event_disconnect()
153
+		else:
154
+			self.listen()
155
+
156
+	def create_socket(self):
157
+		if settings.proxy:
158
+			proxy_server, proxy_port = settings.proxy.split(':')
159
+			self.sock = socks.socksocket()
160
+			self.sock.setproxy(socks.PROXY_TYPE_SOCKS5, proxy_server, int(proxy_port))
161
+		else:
162
+			self.sock = socket.socket(socket.AF_INET6) if ':' in self.server else socket.socket()
163
+			if settings.vhost:
164
+				self.sock.bind((settings.vhost, 0))
165
+			if self.port == 6697:
166
+				self.sock = ssl.wrap_socket(self.sock)
167
+		self.sock.settimeout(throttle.timeout)
168
+
169
+	def event_connect(self, name, daemon):
170
+		debug(f'Connected to {name} ({daemon})')
171
+		self.server = name
172
+		time.sleep(throttle.delay) # high delay could cause a ping out, asyncio would help
173
+		if settings.register:
174
+			self.sendmsg('NickServ', f'REGISTER {rnd()} {rnd()}@gmail.com')
175
+		self.raw('LIST >' + str(throttle.users))
176
+
177
+	def event_disconnect(self):
178
+		self.sock.close()
179
+
180
+	def event_end_of_list(self):
181
+		if self.channels['all']:
182
+			debug('Found {0:,} channels on {1}'.format(len(self.channels['all']), self.server))
183
+			threading.Thread(target=self.attack).start()
184
+		else:
185
+			error('Found zero channels on ' + self.server)
186
+			self.event_disconnect()
187
+
188
+	def event_end_of_names(self, chan):
189
+		self.channels['current'].append(chan)
190
+		debug(f'Knocking {chan} channel on {self.server}...')
191
+		try:
192
+			for line in msg_lines:
193
+				if chan in self.channels['bad']:
194
+					break
195
+				self.sendmsg(chan, line)
196
+				time.sleep(throttle.message)
197
+			if chan in self.channels['nicks']:
198
+				self.channels['nicks'][chan] = ' '.join(self.channels['nicks'][chan])
199
+				if len(self.channels['nicks'][chan]) <= 400:
200
+					self.sendmsg(chan, self.channels['nicks'][chan])
201
+				else:
202
+					while len(self.channels['nicks'][chan]) > 400:
203
+						if chan in self.channels['bad']:
204
+							break
205
+						segment = self.channels['nicks'][chan][:400]
206
+						segment = segment[:-len(segment.split()[len(segment.split())-1])]
207
+						self.sendmsg(chan, segment)
208
+						self.channels['nicks'][chan] = self.channels['nicks'][chan][len(segment):]
209
+						time.sleep(throttle.message)
210
+			self.raw(f'PART {chan} :{settings.part_msg}')
211
+		except Exception as ex:
212
+			error('Error occured in the attack loop!', ex)
213
+		finally:
214
+			if chan in self.channels['current']:
215
+				self.channels['current'].remove(chan)
216
+			if chan in self.channels['bad']:
217
+				self.channels['bad'].remove(chan)
218
+			if chan in self.channels['nicks']:
219
+				del self.channels['nicks'][chan]
220
+
221
+	def event_names(self, chan, names):
222
+		if settings.mass_hilite:
223
+			if chan not in self.channels['nicks']:
224
+				self.channels['nicks'][chan] = list()
225
+			for name in names:
226
+				if name[:1] in '~!@%&+:':
227
+					name = name[1:]
228
+				if name != 'ChanServ' and name not in self.channels['nicks'][chan]:
229
+					self.channels['nicks'][chan].append(name)
230
+
231
+	def handle_events(self, data):
232
+		args = data.split()
233
+		if data.startswith('ERROR :Closing Link:'):
234
+			raise Exception('Connection has closed.')
235
+		elif args[0] == 'PING':
236
+			self.raw('PONG ' + args[1][1:])
237
+		elif args[1] == '004': # RPL_MYINFO
238
+			server_name   = args[3]
239
+			server_daemon = args[4]
240
+			self.event_connect(server_name, server_daemon)
241
+		elif args[1] == '266': # RPL_GLOBALUSERS
242
+			global_users = args[3] # might use this for something in the future
243
+		elif args[1] == '322' and len(args) >= 5: # RPL_LIST
244
+			chan  = args[3]
245
+			users = args[4] # might use this for something in the future
246
+			self.channels['all'].append(chan)
247
+		elif args[1] == '323': # RPL_LISTEND
248
+			self.event_end_of_list()
249
+		elif args[1] == '353' and len(args) >= 6: # RPL_NAMREPLY
250
+			chan  = args[4]
251
+			names = ' '.join(args[5:])[2:].split()
252
+			self.event_names(chan, names)
253
+		elif args[1] == '366' and len(args) >= 4: # RPL_ENDOFNAMES
254
+			chan = args[3]
255
+			threading.Thread(target=self.event_end_of_names, args=(chan,)).start()
256
+		elif args[1] == '433': # ERR_NICKNAMEINUSE
257
+			self.raw('NICK ' + rnd())
258
+		elif args[1] == '464': # ERR_PASSWDMISMATCH
259
+			error('Network has a password.', self.server)
260
+		elif args[1] == '465': # ERR_YOUREBANNEDCREEP
261
+			error('K-Lined.', self.server)
262
+		elif args[1] in bad_numerics and len(args) >= 4:
263
+			chan = args[3]
264
+			if chan not in self.channels['bad']:
265
+				self.channels['bad'].append(chan)
266
+				error(f'Failed to knock {chan} channel on {self.server}', bad_numerics[args[1]])
267
+
268
+	def listen(self):
269
+		while True:
270
+			try:
271
+				data = self.sock.recv(1024).decode('utf-8')
272
+				for line in (line for line in data.split('\r\n') if len(line.split()) >= 2):
273
+					self.handle_events(line)
274
+			except (UnicodeDecodeError,UnicodeEncodeError):
275
+				pass
276
+			except Exception as ex:
277
+				error('Unexpected error occured.', ex)
278
+				break
279
+		self.event_disconnect()
280
+
281
+	def raw(self, msg):
282
+		self.sock.send(bytes(msg + '\r\n', 'utf-8'))
283
+
284
+	def sendmsg(self, target, msg):
285
+		self.raw(f'PRIVMSG {target} :{msg}')
286
+
287
+# Main
288
+print('#'*56)
289
+print('#{:^54}#'.format(''))
290
+print('#{:^54}#'.format('EFknockr (EFK)'))
291
+print('#{:^54}#'.format('Developed by acidvegas in Python'))
292
+print('#{:^54}#'.format('https://acid.vegas/trollbots'))
293
+print('#{:^54}#'.format(''))
294
+print('#'*56)
295
+parser = argparse.ArgumentParser(usage='%(prog)s <msg_file> <targets_file>')
296
+parser.add_argument('msg_file',     help='file to send contents')
297
+parser.add_argument('targets_file', help='file with a list of ip addresses')
298
+args = parser.parse_args()
299
+if settings.proxy:
300
+	try:
301
+		import socks
302
+	except ImportError:
303
+		error_exit('Missing PySocks module! (https://pypi.python.org/pypi/PySocks)')
304
+if os.path.isfile(args.msg_file) and os.path.isfile(args.targets_file):
305
+	msg_lines = [line.rstrip() for line in open(args.msg_file,     encoding='utf8', errors='replace').readlines() if line]
306
+	targets   = [line.rstrip() for line in open(args.targets_file, encoding='utf8', errors='replace').readlines() if line]
307
+else:
308
+	error_exit('File is missing or is a directory!')
309
+debug(f'Loaded {len(targets):,} targets.')
310
+random.shuffle(targets)
311
+with concurrent.futures.ThreadPoolExecutor(max_workers=throttle.threads) as executor:
312
+	checks = [executor.submit(clone(target).connect) for target in targets]
313
+	concurrent.futures.wait(checks)
314
+debug('EFknockr has finished knocking.')
315
diff --git a/efknockr/efknockr/config.py b/efknockr/efknockr/config.py
316
deleted file mode 100644
317
index 2074e00..0000000
318
--- a/efknockr/efknockr/config.py
319
+++ /dev/null
320
@@ -1,38 +0,0 @@
321
-#!/usr/bin/env python
322
-# EFknockr (EFK) - Developed by acidvegas in Python (https://acid.vegas/trollbots)
323
-# config.py
324
-
325
-class connection:
326
-	proxy = None # Proxy should be a Socks5 in IP:PORT format.
327
-	vhost = None
328
-
329
-class settings:
330
-	mass_hilite = True # Hilite all the users in a channel before parting.
331
-	part_msg    = 'Smell ya l8r'
332
-
333
-class throttle:
334
-	channels = 3   # Maximum number of channels to be flooding at once.
335
-	join     = 3   # Delay between each channel join.
336
-	message  = 0.5 # Delay between each message sent to a channel.
337
-	threads  = 100 # Maximum number of threads running.
338
-	timeout  = 15  # Timeout for all sockets.
339
-	users    = 10  # Minimum number of users required in a channel.
340
-
341
-# Attack List / Options
342
-defaults = {
343
-	'port'     : 6667,
344
-	'ipv6'     : False,
345
-	'ssl'      : False,
346
-	'password' : None, # This is the network password issued on connect.
347
-	'channels' : None, # Setting channels to None will crawl all channels.
348
-	'nickname' : 'EFknockr',
349
-	'username' : 'efk',
350
-	'realname' : 'acid.vegas/efknockr',
351
-	'nickserv' : None
352
-}
353
-
354
-targets  = {
355
-	'irc.server1.com' : None,                                              # None as the server options will use the default settings.
356
-	'irc.server2.com' : {'port':6697, 'ssl':True},                         # Change the default settings by specifying options to change.
357
-	'irc.server3.com' : {'channels':['#channel1','#channel2','#channel3']} # Setting specific channels can be done with a list.
358
-}
359
diff --git a/efknockr/efknockr/efknockr.py b/efknockr/efknockr/efknockr.py
360
deleted file mode 100644
361
index 56dd0aa..0000000
362
--- a/efknockr/efknockr/efknockr.py
363
+++ /dev/null
364
@@ -1,292 +0,0 @@
365
-#!/usr/bin/env python
366
-# EFknockr (EFK) - Developed by acidvegas in Python (https://acid.vegas/trollbots)
367
-# efknockr.py
368
-
369
-import concurrent.futures
370
-import os
371
-import random
372
-import socket
373
-import ssl
374
-import sys
375
-import threading
376
-import time
377
-
378
-sys.dont_write_bytecode = True
379
-
380
-import config
381
-
382
-# Bad IRC Events
383
-bad_msgs = (
384
-	'Color is not permitted',
385
-	'No external channel messages',
386
-	'You need voice',
387
-	'You must have a registered nick'
388
-)
389
-
390
-bad_numerics = {
391
-	'471' : 'ERR_CHANNELISFULL',
392
-	'473' : 'ERR_INVITEONLYCHAN',
393
-	'474' : 'ERR_BANNEDFROMCHAN',
394
-	'475' : 'ERR_BADCHANNELKEY',
395
-	'477' : 'ERR_NEEDREGGEDNICK',
396
-	'489' : 'ERR_SECUREONLYCHAN',
397
-	'519' : 'ERR_TOOMANYUSERS',
398
-	'520' : 'ERR_OPERONLY'
399
-}
400
-
401
-def debug(msg):
402
-	print(f'{get_time()} | [~] - {msg}')
403
-
404
-def error(msg, reason=None):
405
-	print(f'{get_time()} | [!] - {msg} ({reason})') if reason else print(f'{get_time()} | [!] - {msg}')
406
-
407
-def error_exit(msg):
408
-	raise SystemExit(f'{get_time()} | [!] - {msg}')
409
-
410
-def get_time():
411
-	return time.strftime('%I:%M:%S')
412
-
413
-class clone:
414
-	def __init__(self, server, options):
415
-		self.server           = server
416
-		self.options          = options
417
-		self.bad_channels     = list()
418
-		self.current_channels = list()
419
-		self.nicklist         = dict()
420
-		self.nickname         = None
421
-		self.sock             = None
422
-
423
-	def run(self):
424
-		if not self.options:
425
-			self.options = config.defaults
426
-		else:
427
-			self.options.update(config.defaults)
428
-		self.nickname = self.options['nickname']
429
-		self.connect()
430
-
431
-	def attack(self):
432
-		try:
433
-			while self.options['channels']:
434
-				chan = random.choice(self.options['channels'])
435
-				try:
436
-					self.join_channel(chan)
437
-				except Exception as ex:
438
-					error('Error occured in the attack loop!', ex)
439
-					break
440
-				else:
441
-					time.sleep(config.throttle.join)
442
-					while len(self.current_channels) >= config.throttle.channels:
443
-						time.sleep(1)
444
-				finally:
445
-					if chan in self.options['channels']:
446
-						self.options['channels'].remove(chan)
447
-			debug('Finished knocking all channels on ' + self.server)
448
-			self.event_disconnect()
449
-		except Exception as ex:
450
-			error('Error occured in the attack loop!', ex)
451
-
452
-	def connect(self):
453
-		try:
454
-			self.create_socket()
455
-			self.sock.connect((self.server, self.options['port']))
456
-			self.register()
457
-		except socket.error:
458
-			#error('Failed to connect to ' + self.server)
459
-			self.event_disconnect()
460
-		else:
461
-			self.listen()
462
-
463
-	def create_socket(self):
464
-		family = socket.AF_INET6 if self.options['ipv6'] else socket.AF_INET
465
-		if config.connection.proxy:
466
-			proxy_server, proxy_port = config.settings.proxy.split(':')
467
-			self.sock = socks.socksocket(family, socket.SOCK_STREAM)
468
-			self.sock.setblocking(0)
469
-			self.sock.setproxy(socks.PROXY_TYPE_SOCKS5, proxy_server, int(proxy_port))
470
-		else:
471
-			self.sock = socket.socket(family, socket.SOCK_STREAM)
472
-		self.sock.settimeout(config.throttle.timeout)
473
-		if config.connection.vhost:
474
-			self.sock.bind((config.connection.vhost, 0))
475
-		if self.options['ssl']:
476
-			self.sock = ssl.wrap_socket(self.sock)
477
-
478
-	def event_connect(self):
479
-		debug('Connected to ' + self.server)
480
-		if self.options['nickserv']:
481
-			self.sendmsg('NickServ', f'IDENTIFY {0} {1}'.format(self.options['nickname'], self.options['nickserv']))
482
-		if self.options['channels']:
483
-			if type(self.options['channels']) == list:
484
- 				threading.Thread(target=self.attack).start()
485
-			else:
486
-				error('Invalid channel list for ' + self.server)
487
-				self.event_disconnect()
488
-		else:
489
-			self.options['channels'] = list()
490
-			time.sleep(65)
491
-			self.raw('LIST >' + str(config.throttle.users))
492
-
493
-	def event_disconnect(self):
494
-		self.sock.close()
495
-
496
-	def event_end_of_list(self):
497
-		if self.options['channels']:
498
-			debug('Found {0} channels on {1}'.format(len(self.options['channels']), self.server))
499
-			threading.Thread(target=self.attack).start()
500
-		else:
501
-			error('Found zero channels on ' + self.server)
502
-			self.event_disconnect()
503
-
504
-	def event_end_of_names(self, chan):
505
-		self.current_channels.append(chan)
506
-		debug(f'Knocking {chan} channel on {self.server}...')
507
-		try:
508
-			for line in msg_lines:
509
-				if chan in self.bad_channels:
510
-					break
511
-				self.sendmsg(chan, line)
512
-				time.sleep(config.throttle.message)
513
-			if chan in self.nicklist:
514
-				self.nicklist[chan] = ' '.join(self.nicklist[chan])
515
-				if len(self.nicklist[chan]) <= 400:
516
-					self.sendmsg(chan, self.nicklist[chan])
517
-				else:
518
-					while len(self.nicklist[chan]) > 400:
519
-						if chan in self.bad_channels:
520
-							break
521
-						segment = self.nicklist[chan][:400]
522
-						segment = segment[:-len(segment.split()[len(segment.split())-1])]
523
-						self.sendmsg(chan, segment)
524
-						self.nicklist[chan] = self.nicklist[chan][len(segment):]
525
-						time.sleep(config.throttle.message)
526
-			self.part(chan, config.settings.part_msg)
527
-		except Exception as ex:
528
-			error('Error occured in the attack loop!', ex)
529
-		finally:
530
-			if chan in self.current_channels:
531
-				self.current_channels.remove(chan)
532
-			if chan in self.bad_channels:
533
-				self.bad_channels.remove(chan)
534
-			if chan in self.nicklist:
535
-				del self.nicklist[chan]
536
-
537
-	def event_list_channel(self, chan, users):
538
-		self.options['channels'].append(chan)
539
-
540
-	def event_nick_in_use(self):
541
-		self.nickname += '_'
542
-		self.nick(self.nickname)
543
-
544
-	def event_names(self, chan, names):
545
-		if config.settings.mass_hilite:
546
-			if chan not in self.nicklist:
547
-				self.nicklist[chan] = list()
548
-			for name in names:
549
-				if name[:1] in '~!@%&+:':
550
-					name = name[1:]
551
-				if name != self.nickname and name not in self.nicklist[chan]:
552
-					self.nicklist[chan].append(name)
553
-
554
-	def handle_events(self, data):
555
-		args = data.split()
556
-		if data.startswith('ERROR :Closing Link:'):
557
-			if 'Password mismatch' in data:
558
-				error('Network has a password.', self.server)
559
-			raise Exception('Connection has closed.')
560
-		elif args[0] == 'PING' and len(args) == 2:
561
-			self.raw('PONG ' + args[1][1:])
562
-		elif args[1] == '001': # RPL_WELCOME
563
-			self.event_connect()
564
-		elif args[1] == '322' and len(args) >= 5: # RPL_LIST
565
-			chan  = args[3]
566
-			users = args[4]
567
-			self.event_list_channel(chan, users)
568
-		elif args[1] == '323': # RPL_LISTEND
569
-			self.event_end_of_list()
570
-		elif args[1] == '353' and len(args) >= 6: # RPL_NAMREPLY
571
-			chan  = args[4]
572
-			names = ' '.join(args[5:])[2:].split()
573
-			self.event_names(chan, names)
574
-		elif args[1] == '366' and len(args) >= 4: # RPL_ENDOFNAMES
575
-			chan = args[3]
576
-			threading.Thread(target=self.event_end_of_names, args=(chan,)).start()
577
-		elif args[1] == '404' and len(args) >= 4: # ERR_CANNOTSENDTOCHAN
578
-			chan = args[3]
579
-			for item in bad_msgs:
580
-				if item in data:
581
-					error(f'Failed to message {chan} channel on {self.server}', '404: ' + item)
582
-					if chan not in self.bad_channels:
583
-						self.bad_channels.append(chan)
584
-						break
585
-		elif args[1] == '433': # ERR_NICKNAMEINUSE
586
-			self.event_nick_in_use()
587
-		elif args[1] == '464': # ERR_PASSWDMISMATCH
588
-			error('Network has a password.', self.server)
589
-		elif args[1] in bad_numerics and len(args) >= 4:
590
-			chan = args[3]
591
-			if chan not in self.bad_channels:
592
-				self.bad_channels.append(chan)
593
-			error(f'Failed to knock {chan} channel on {self.server}', bad_numerics[args[1]])
594
-
595
-	def join_channel(self, chan):
596
-		self.raw('JOIN ' + chan)
597
-
598
-	def listen(self):
599
-		while True:
600
-			try:
601
-				data = self.sock.recv(1024).decode('utf-8')
602
-				for line in (line for line in data.split('\r\n') if len(line.split()) >= 2):
603
-					self.handle_events(line)
604
-			except (UnicodeDecodeError,UnicodeEncodeError):
605
-				pass
606
-			except Exception as ex:
607
-				#error('Unexpected error occured.', ex)
608
-				break
609
-		self.event_disconnect()
610
-
611
-	def nick(self, nick):
612
-		self.raw('NICK ' + nick)
613
-
614
-	def part(self, chan, msg):
615
-		self.raw(f'PART {chan} :{msg}')
616
-
617
-	def raw(self, msg):
618
-		self.sock.send(bytes(msg + '\r\n', 'utf-8'))
619
-
620
-	def register(self):
621
-		if self.options['password']:
622
-			self.raw('PASS ' + self.options['password'])
623
-		self.raw('USER {0} 0 * :{1}'.format(self.options['username'], self.options['realname']))
624
-		self.raw('NICK ' + self.nickname)
625
-
626
-	def sendmsg(self, target, msg):
627
-		self.raw(f'PRIVMSG {target} :{msg}')
628
-
629
-# Main
630
-print('#'*56)
631
-print('#{0}#'.format(''.center(54)))
632
-print('#{0}#'.format('EFknockr (EFK)'.center(54)))
633
-print('#{0}#'.format('Developed by acidvegas in Python'.center(54)))
634
-print('#{0}#'.format('https://acid.vegas/trollbots'.center(54)))
635
-print('#{0}#'.format(''.center(54)))
636
-print('#'*56)
637
-if config.connection.proxy:
638
-	try:
639
-		import socks
640
-	except ImportError:
641
-		error_exit('Missing PySocks module! (https://pypi.python.org/pypi/PySocks)')
642
-msg_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'msg.txt')
643
-if os.path.isfile(msg_file):
644
-	msg_lines = [line.rstrip() for line in open(msg_file, encoding='utf8', errors='replace').readlines() if line]
645
-	print(msg_lines)
646
-else:
647
-	error_exit('Missing message file!')
648
-del msg_file
649
-debug(f'Loaded {len(config.targets)} targets from config.')
650
-server_list = list(config.targets)
651
-random.shuffle(server_list)
652
-with concurrent.futures.ThreadPoolExecutor(max_workers=config.throttle.threads) as executor:
653
-	checks = {executor.submit(clone(server, config.targets[server]).run): server for server in server_list}
654
-	for future in concurrent.futures.as_completed(checks):
655
-		checks[future]
656
-debug('EFknockr has finished knocking.')
657
diff --git a/efknockr/efknockr/msg.txt b/efknockr/efknockr/msg.txt
658
deleted file mode 100644
659
index 43dd4b7..0000000
660
--- a/efknockr/efknockr/msg.txt
661
+++ /dev/null
662
@@ -1,8 +0,0 @@
663
-EFKnockr script developed by acidvegas
664
-███████╗███████╗██╗  ██╗
665
-██╔════╝██╔════╝██║ ██╔╝
666
-█████╗  █████╗  █████╔╝
667
-██╔══╝  ██╔══╝  ██╔═██╗
668
-███████╗██║     ██║  ██╗
669
-╚══════╝╚═╝     ╚═╝  ╚═╝
670
-https://acid.vegas/efknockr