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 |