Initial commit

This commit is contained in:
Dionysus 2023-07-09 21:58:52 -04:00
commit 108343167c
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
5 changed files with 651 additions and 0 deletions

BIN
.screens/driveby.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
.screens/gun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

15
LICENSE Normal file
View File

@ -0,0 +1,15 @@
ISC License
Copyright (c) 2021, acidvegas <acid.vegas@acid.vegas>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# EFknockr
## WARNING: This is simply a PROOF-OF-CONCEPT that outlines major flaws in how we use IRC currently!
![](.screens/gun.png)
## WARNING: This repository was made for testing against your own server(s). I am not responsible for the public use.
## Information
This is basically an IRC drive-by. It takes a list of IRC servers, connects to all of them & joins every channel to send a custom message. You can also have it mass highlight & mass private message the channels for more attention to your message. It will do various things to make sure it does not get banned, throttled, or detected.
Proxy scanning is included as an option, which will find thousands of new proxies on every loop. Combine that with the daemon mode *(24/7 knocking)* & this becomes un-stoppable. Tied with a residential proxy service & this becomes a problem.
The humor behind this script is that anyone can mass portscan **0.0.0.0/0** *(the entire IPv4 range)* for port **6667** & essentially send a message to every IRC server on the internet. **But I have heard a rumor that doing so will only affect channels that are boring, lame, & shitty :) :) :)**
I am not going to get into how to set this up or use it. This is simply here to serve as a proof-of-concept.
## Previews
Here are some examples of people using EFknockr:
![](.screens/driveby.png)
## Disclaimer
The proof-of-concept here is a classic example of the on going problem wtih using standard ports for known services on IPv4.
Both SSH & Telnet world-wide get thousands of login attempts daily because of this. IRC is no different & is certainly not excluded from this problem.
**Welcome to the fucking state of the Internet boyz**
I am well aware that people might use this script for malicious purposes....as they should. We cannot just be oblivious to major problems with networked services. IRC is a very small space in modern day. Becasue of that, it seems like setting up an IRCd is all people cared to learn...skipping over what it means to be a network operator.
**It is no different than being a sysadmin**
I have dealt with IRC flooding for years. Most times, I rarely have to tocuh the keyboard to handle it. Everything is laid out in the IRCd documentation. Big shout outs to [UnrealIRCd](https://www.unrealircd.org/) for being the BEST FUCKING IRC DAEMON EVER!
Anyways...at the end of the day...it is text on a screen. It is just **text** on a **screen**. Quite often lost in the backlog after a short period...
###### Todo
* Invite support
* Parse `MAXTARGETS` & `MAXCHANNELS` from **005** responses for fine tuned spamming
* UTF-16 Bot crashing for improper unicode decoding
* Weechat DCC buffer-overlfow exploit *(See [here](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8073))*
* OpenSSL crash exploit *(See [here](https://forums.unrealircd.org/viewtopic.php?f=1&t=9085))*
* `/LIST` tarpit detection & evasion
* Scramble the order of operations to be entirely random to thwart fingerprinting
* Drop unicode for normal letters to thwart spamfilters
* Add unifuck option
* Do not knock on channels we registered
___
###### Mirrors
[acid.vegas](https://git.acid.vegas/efknockr) • [GitHub](https://github.com/acidvegas/efknockr) • [GitLab](https://gitlab.com/acidvegas/efknockr) • [SourceHut](https://git.sr.ht/~acidvegas/efknockr) • [SuperNETs](https://git.supernets.org/acidvegas/efknockr)

583
efknockr.py Normal file
View File

@ -0,0 +1,583 @@
#!/usr/bin/env python
# efknockr (internet relay chat beacon) - developed by acidvegas in python (https://git.acid.vegas/efknockr)
import asyncio
import ipaddress
import os
import random
import re
import ssl
import sys
import time
import urllib.request
class settings:
chan_first = False # Finish knocking channels before sending private messages
confuse = True # Use unicode confusables in messages to avoid spamfilters
daemon = False # Run in daemon mode (24/7 throttled knocking)
errors = True # Show errors in console
errors_conn = False # Show connection errors in console
exploits = False # Use a exploit payloads
mass_hl = True # Hilite all the users in a channel before parting
part_msg = 'Smell ya l8r' # Send a custom part message when leaving channels
proxies = False # Connect with proxies
proxies_only = False # Only connect with proxies
register = True # Register with NickServ before joining channels
register_chan = '#EFKnockr' # Set to None to disable channel registrations
register_chan_topic = 'EFK' # Topic to set for the registered channel
class throttle:
channels = 3 if not settings.daemon else 2 # Maximum number of channels to knock at once
connect = 15 if not settings.daemon else 60 # Delay between each connection attempt on a diffferent port
delay = 300 if not settings.daemon else 600 # Delay before registering nick (if enabled) & sending /LIST
jdelay = 3 if not settings.daemon else 10 # Delay before messaging a channel
join = 10 if not settings.daemon else 30 # Delay between channel JOINs
message = 1.5 if not settings.daemon else 3 # Delay between each message sent
nick = 300 if not settings.daemon else 600 # Delay between every random NICK change
nicks = 5 if not settings.daemon else 15 # Delay between each nick private messaged
private = 5 if not settings.daemon else 15 # Delay between private messages
pthreads = 500 if not settings.daemon else 300 # Maximum number of threads for proxy checking
ptimeout = 15 if not settings.daemon else 30 # Timeout for all sockets
seconds = 300 if not settings.daemon else 600 # Maximum seconds to wait when throttled for JOIN or PM
users = 10 if not settings.daemon else 5 # Minimum number of users in a channel to knock
threads = 500 if not settings.daemon else 50 # Maximum number of threads running
timeout = 30 if not settings.daemon else 60 # Timeout for all sockets
ztimeout = 200 if not settings.daemon else 300 # Timeout for zero data from server ;) ;) ;)
messages = (
'This message has been brought to you by EFknockr!',
'WHAT IS UP PORT 6667!?',
['multi','lined','message','example'],
['cant',' stop',' me','cause',' im a',' pumper'],
'b i g a c i d v e g a s h a s u'
)
class bad:
donotscan = (
'irc.dronebl.org', 'irc.alphachat.net',
'5.9.164.48', '45.32.74.177', '104.238.146.46', '149.248.55.130',
'2001:19f0:6001:1dc::1', '2001:19f0:b001:ce3::1', '2a01:4f8:160:2501:48:164:9:5', '2001:19f0:6401:17c::1'
)
chan = {
'403' : 'ERR_NOSUCHCHANNEL', '405' : 'ERR_TOOMANYCHANNELS',
'435' : 'ERR_BANONCHAN', '442' : 'ERR_NOTONCHANNEL',
'448' : 'ERR_FORBIDDENCHANNEL', '470' : 'ERR_LINKCHANNEL',
'471' : 'ERR_CHANNELISFULL', '473' : 'ERR_INVITEONLYCHAN',
'474' : 'ERR_BANNEDFROMCHAN', '475' : 'ERR_BADCHANNELKEY',
'476' : 'ERR_BADCHANMASK', '477' : 'ERR_NEEDREGGEDNICK',
'479' : 'ERR_BADCHANNAME', '480' : 'ERR_THROTTLE',
'485' : 'ERR_CHANBANREASON', '488' : 'ERR_NOSSL',
'489' : 'ERR_SECUREONLYCHAN', '519' : 'ERR_TOOMANYUSERS',
'520' : 'ERR_OPERONLY', '926' : 'ERR_BADCHANNEL'
}
error = {
'install identd' : 'Identd required',
'trying to reconnect too fast' : 'Throttled',
'trying to (re)connect too fast' : 'Throttled',
'reconnecting too fast' : 'Throttled',
'access denied' : 'Access denied',
'not authorized to' : 'Not authorized',
'not authorised to' : 'Not authorized',
'password mismatch' : 'Password mismatch',
'dronebl' : 'DroneBL',
'dnsbl' : 'DNSBL',
'g:lined' : 'G:Lined',
'z:lined' : 'Z:Lined',
'timeout' : 'Timeout',
'closing link' : 'Banned',
'banned' : 'Banned',
'client exited' : 'QUIT',
'quit' : 'QUIT'
}
# Globals
all_proxies = list()
good_proxies = list()
def confuse(data):
if settings.confuse:
chars = ''
for char in data:
if random.choice((True,False,False)):
if char == ' ':
chars += '\u00A0'
elif char.lower() in ('abcdefghijklmnopqrstvwyz'):
chars += char + random.choice(('\u200B','\u2060','\x0f','\x03\x0f'))
else:
chars += char
else:
chars += char
return ''.join(chars)
else:
return data
def debug(data):
print('{0} \033[1;30m|\033[0m [\033[35m~\033[0m] {1}'.format(time.strftime('%I:%M:%S'), data))
def error(data, reason=None):
if settings.errors:
print('{0} \033[1;30m|\033[0m [\033[31m!\033[0m] {1} \033[1;30m({2})\033[0m'.format(time.strftime('%I:%M:%S'), data, str(reason))) if reason else print('{0} \033[1;30m|\033[0m [\033[31m!\033[0m] {1}'.format(time.strftime('%I:%M:%S'), data))
def get_proxies():
urls = (
'https://find-your-own-proxies.com/socks5.txt',
'https://find-your-own-proxies.com/socks5.txt',
'https://find-your-own-proxies.com/socks5.txt'
)
proxies = list()
for url in urls:
try:
req = urllib.request.Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')
source = urllib.request.urlopen(req, timeout=10).read().decode()
proxies+= list(set([proxy for proxy in re.findall('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+', source, re.MULTILINE) if proxy not in proxies]))
except Exception as ex:
error('failed to grab new proxies!', ex)
return proxies if proxies else False
async def check_proxy(semaphore, proxy):
async with semaphore:
ip, port = proxy.split(':')
options = {
'proxy' : aiosocks.Socks5Addr(proxy.split(':')[0], int(proxy.split(':')[1])),
'proxy_auth' : None,
'dst' : ('www.google.com',80),
'limit' : 1024,
'ssl' : None,
'family' : 2
}
try:
await asyncio.wait_for(aiosocks.open_connection(**options), throttle.ptimeout)
except:
pass
else:
debug('\033[1;32mGOOD\033[0m \033[1;30m|\033[0m ' + proxy)
if ip not in all_proxies:
all_proxies.append(ip)
good_proxies.append(proxy)
def rndnick():
prefix = random.choice(['st','sn','cr','pl','pr','fr','fl','qu','br','gr','sh','sk','tr','kl','wr','bl']+list('bcdfgklmnprstvwz'))
midfix = random.choice(('aeiou'))+random.choice(('aeiou'))+random.choice(('bcdfgklmnprstvwz'))
suffix = random.choice(['ed','est','er','le','ly','y','ies','iest','ian','ion','est','ing','led','inger']+list('abcdfgklmnprstvwz'))
return prefix+midfix+suffix
def ssl_ctx():
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
return ctx
class probe:
def __init__(self, semaphore, server, proxy=None):
self.semaphore = semaphore
self.server = server
self.proxy = proxy
self.display = server.ljust(18)+' \033[1;30m|\033[0m unknown network \033[1;30m|\033[0m '
self.nickname = rndnick()
self.channels = {'all':list(), 'current':list(), 'users':dict(), 'bad':list()}
self.nicks = {'all':list(), 'chan':dict(), 'check':list(), 'bad':list()}
self.loops = {'init':None, 'chan':None, 'nick':None, 'pm':None}
self.jthrottle = throttle.join
self.nthrottle = throttle.private
self.reader = None
self.write = None
async def sendmsg(self, target, msg):
await self.raw(f'PRIVMSG {target} :{msg}')
async def run(self):
async with self.semaphore:
try:
await self.connect() # 6697
except Exception as ex:
if settings.errors_conn:
error(self.display + '\033[1;31mdisconnected\033[0m - failed to connect using SSL/TLS!', ex)
await asyncio.sleep(throttle.connect)
try:
await self.connect(True) # 6667
except Exception as ex:
if settings.errors_conn:
error(self.display + '\033[1;31mdisconnected\033[0m - failed to connect!', ex)
async def raw(self, data):
self.writer.write(data[:510].encode('utf-8') + b'\r\n')
await self.writer.drain()
async def connect(self, fallback=False):
if self.proxy:
options = {
'proxy' : aiosocks.Socks5Addr(self.proxy.split(':')[0], int(self.proxy.split(':')[1])),
'proxy_auth' : None,
'dst' : (self.server,6667) if fallback else (self.server,6697),
'limit' : 1024,
'ssl' : None if fallback else ssl_ctx(),
'family' : 2
}
self.reader, self.writer = await asyncio.wait_for(aiosocks.open_connection(**options), throttle.timeout)
else:
options = {
'host' : self.server,
'port' : 6667 if fallback else 6697,
'limit' : 1024,
'ssl' : None if fallback else ssl_ctx(),
'family' : 2
}
self.reader, self.writer = await asyncio.wait_for(asyncio.open_connection(**options), throttle.timeout)
del options
await self.raw('USER {0} 0 * :{1}'.format(rndnick(), rndnick()))
await self.raw('NICK ' + self.nickname)
await self.listen()
for item in self.loops:
if self.loops[item]:
self.loops[item].cancel()
debug(self.display + 'finished knocking')
async def loop_initial(self):
try:
await asyncio.sleep(throttle.delay)
mail = rndnick() + '@' + random.choice(('gmail.com','hotmail.com','yahoo.com','outlook.com','protonmail.com','mail.com',rndnick()+random.choice(('com','org','net'))))
cmds = [f'PRIVMSG NickServ :REGISTER {rndnick()} {mail}', 'LIST']
for command in cmds:
try:
await self.raw(command)
except:
break
else:
await asyncio.sleep(3)
if not self.channels['all']:
error(self.display + '\033[31merror\033[0m - no channels found')
await self.raw('QUIT')
except asyncio.CancelledError:
pass
except Exception as ex:
error(self.display + '\033[31merror\033[0m - loop_initial', ex)
async def loop_channels(self):
try:
while self.channels['all']:
while len(self.channels['current']) >= throttle.channels:
await asyncio.sleep(1)
await asyncio.sleep(self.jthrottle)
chan = random.choice(self.channels['all'])
self.channels['all'].remove(chan)
try:
await self.raw('JOIN ' + chan)
except:
break
if settings.chan_first:
self.loops['pm'] = asyncio.create_task(self.loop_private())
while self.nicks['check']:
await asyncio.sleep(1)
self.loops['nick'].cancel()
self.loops['pm'].cancel()
await self.raw('QUIT')
except asyncio.CancelledError:
pass
except Exception as ex:
error(self.display + '\033[31merror\033[0m - loop_channels', ex)
async def loop_nick(self):
try:
while True:
await asyncio.sleep(throttle.nick)
self.nickname = rndnick()
await self.raw('NICK ' + self.nickname)
except asyncio.CancelledError:
pass
except Exception as ex:
error(self.display + '\033[31merror\033[0m - loop_nick', ex)
async def loop_private(self):
try:
while True:
if self.nicks['check']:
nick = random.choice(self.nicks['check'])
self.nicks['check'].remove(nick)
try:
msg = random.choice(messages)
if type(msg) == list:
for i in msg:
if nick in self.nicks['bad']:
self.nicks['bad'].remove(nick)
break
else:
await self.sendmsg(nick, confuse(i))
await asyncio.sleep(throttle.message)
else:
await self.sendmsg(nick, confuse(msg))
except:
break
else:
del nick
await asyncio.sleep(throttle.nicks)
else:
await asyncio.sleep(1)
except asyncio.CancelledError:
pass
except Exception as ex:
error(self.display + '\033[31merror\033[0m - loop_private', ex)
async def listen(self):
while True:
try:
if self.reader.at_eof():
break
data = await asyncio.wait_for(self.reader.readuntil(b'\r\n'), throttle.ztimeout)
line = data.decode('utf-8').strip()
args = line.split()
event = args[1].upper()
if event in bad.chan and len(args) >= 4:
chan = args[3]
if chan in self.channels['users']:
del self.channels['users'][chan]
if chan in self.nicks['chan']:
del self.nicks['chan'][chan]
error(f'{self.display}\033[31merror\033[0m - {chan}', bad.chan[event])
elif line.startswith('ERROR :'):
check = [check for check in bad.error if check in line.lower()]
if check:
raise Exception(bad.error[check[0]])
elif args[0] == 'PING':
await self.raw('PONG ' + args[1][1:])
elif event == '001': #RPL_WELCOME
host = args[0][1:]
if len(host) > 25:
self.display = f'{self.server.ljust(18)} \033[1;30m|\033[0m {host[:22]}... \033[1;30m|\033[0m '
else:
self.display = f'{self.server.ljust(18)} \033[1;30m|\033[0m {host.ljust(25)} \033[1;30m|\033[0m '
debug(self.display + f'\033[1;32mconnected\033[0m')
self.loops['init'] = asyncio.create_task(self.loop_initial())
elif event == '315' and len(args) >= 3: #RPL_ENDOFWHO
chan = args[3]
await asyncio.sleep(throttle.jdelay)
msg = random.choice(messages)
if type(msg) == list:
for i in msg:
if chan in self.channels['bad']:
self.channels['bad'].remove(chan)
break
else:
await self.sendmsg(chan, confuse(i))
await asyncio.sleep(throttle.message)
else:
await self.sendmsg(chan, confuse(msg))
if settings.exploits:
pass # TODO: add exploits
if settings.mass_hl:
self.nicks['chan'][chan] = ' '.join(self.nicks['chan'][chan])
if len(self.nicks['chan'][chan]) <= 400:
await self.sendmsg(chan, self.nicks['chan'][chan])
else:
while len(self.nicks['chan'][chan]) > 400:
if chan in self.channels['bad']:
self.channels['bad'].remove(chan)
break
else:
segment = self.nicks['chan'][chan][:400]
segment = segment[:-len(segment.split()[len(segment.split())-1])]
await self.sendmsg(chan, segment)
self.nicks['chan'][chan] = self.nicks['chan'][chan][len(segment):]
await asyncio.sleep(throttle.message)
await self.raw(f'PART {chan} :{settings.part_msg}')
self.channels['current'].remove(chan)
del self.nicks['chan'][chan]
if chan in self.channels['bad']:
self.channels['bad'].remove(chan)
elif event == '322' and len(args) >= 4: # RPL_LIST
chan = args[3]
users = args[4]
if len(self.channels['all']) >= 20000:
error(self.display + 'LIST tarpit detected!') # Make it wuddup
error(self.display + 'LIST tarpit detected!') # stand out pi55
error(self.display + 'LIST tarpit detected!') # more n3t
self.snapshot['TARPIT'] = True
await self.raw('QUIT')
if users != '0': # no need to JOIN empty channels...
if chan not in ('#dronebl','#help','#opers'): # lets avoid the channels that are going to get use banned/blacklisted
self.channels['all'].append(chan)
self.channels['users'][chan] = users
elif event == '323': # RPL_LISTEND
if self.channels['all']:
debug(self.display + '\033[36mLIST\033[0m found \033[93m{0}\033[0m channel(s)'.format(str(len(self.channels['all']))))
self.loops['chan'] = asyncio.create_task(self.loop_channels())
self.loops['nick'] = asyncio.create_task(self.loop_nick())
if not settings.chan_first:
self.loops['pm'] = asyncio.create_task(self.loop_private())
elif event == '352' and len(args) >= 8: # RPL_WHORPL
chan = args[3]
nick = args[7]
self.nicks['chan'][chan].append(nick)
if nick not in self.nicks['all']+[self.nickname,]:
self.nicks['all'].append(nick)
self.nicks['check'].append(nick)
elif event == '366' and len(args) >= 4: # RPL_ENDOFNAMES
chan = args[3]
self.nicks['chan'][chan] = list()
self.channels['current'].append(chan)
if chan in self.channels['users']:
debug('{0}\033[32mJOIN\033[0m {1} \033[1;30m(found \033[93m{2}\033[0m users)\033[0m'.format(self.display, chan, self.channels['users'][chan]))
del self.channels['users'][chan]
await self.raw('WHO ' + chan)
elif event == '404' and len(args) >= 5: # ERR_CANNOTSENDTOCHAN
chan = args[3]
msg = ' '.join(args[4:])[1:]
error(self.display + '\033[31merror\033[0m - failed to knock ' + chan, msg)
if chan not in self.channels['bad']:
self.channels['bad'].append(chan)
elif event == '421' and len(args) >= 3: # ERR_UNKNOWNCOMMAND
msg = ' '.join(args[2:])
if 'You must be connected for' in msg:
error(self.display + '\033[31merror\033[0m - delay found', msg)
elif event == '433': # ERR_NICKINUSE
self.nickname = rndnick()
await self.raw('NICK ' + self.nickname)
elif event == '439' and len(args) >= 11: # ERR_TARGETTOOFAST
target = args[3]
msg = ' '.join(args[4:])[1:]
seconds = args[10]
if target[:1] in ('#','&'):
self.channels['all'].append(target)
if seconds.isdigit():
self.jthrottle = throttle.seconds if int(seconds) > throttle.seconds else int(seconds)
else:
self.nicks['check'].append(target)
if seconds.isdigit():
self.nthrottle = throttle.seconds if int(seconds) > throttle.seconds else int(seconds)
error(self.display + '\033[31merror\033[0m - delay found for ' + target, msg)
elif event == '465': # ERR_YOUREBANNEDCREEP
check = [check for check in bad.error if check in line.lower()]
if check:
raise Exception(bad.error[check[0]])
elif event == '464': # ERR_PASSWDMISMATCH
raise Exception('Network has a password')
elif event == '487': # ERR_MSGSERVICES
if '"/msg NickServ" is no longer supported' in line: # TODO: need to do this for ChanServ aswell
await self.raw('/NickServ REGISTER {0} {1}'.format(rndnick(), f'{rndnick()}@{rndnick()}.com'))
elif args[1] in ('716','717'): # RPL_TARGUMODEG / RPL_TARGNOTIFY
nick = args[2] #TODO: verify this is the correct arguement
if nick not in self.nicks['bad']:
self.nicks['bad'].append(nick)
elif event == 'KICK' and len(args) >= 4:
chan = args[2]
kicked = args[3]
if kicked == self.nickname:
if chan in self.channels['current']:
self.channels['current'].remove(chan)
elif event == 'KILL':
nick = args[2]
if nick == self.nickname:
raise Exception('KILL')
elif event == 'MODE' and len(args) == 4:
nick = args[2]
if nick == self.nickname:
mode = args[3][1:]
if mode == '+r':
chan = settings.register_chan + '_' + str(random.randint(10,99))
await self.raw('JOIN ' + chan)
await self.raw(f'TOPIC {chan} :' + settings.register_chan_topic)
await self.sendmsg('ChanServ', 'REGISTER ' + chan)
await self.sendmsg('ChanServ', f'SET {chan} KEEPTOPIC ON')
await self.sendmsg('ChanServ', f'SET {chan} NOEXPIRE ON')
await self.sendmsg('ChanServ', f'SET {chan} PERSIST ON')
await self.sendmsg('ChanServ', f'SET {chan} DESCRIPTION ' + settings.register_chan_topic)
await self.raw('PART ' + chan)
elif event in ('NOTICE','PRIVMSG') and len(args) >= 4:
nick = args[0].split('!')[1:]
target = args[2]
msg = ' '.join(args[3:])[1:]
if target == self.nickname:
for i in ('proxy','proxys','proxies'):
if i in msg.lower():
check = [x for x in ('bopm','hopm') if x in line]
if check:
error(f'{self.display}\033[93m{check.upper()} detected\033[0m')
else:
error(self.display + '\033[93mProxy Monitor detected\033[0m')
for i in ('You must have been using this nick for','You must be connected for','not connected long enough','Please wait', 'You cannot list within the first'):
if i in msg:
error(self.display + '\033[31merror\033[0m - delay found', msg)
break
if msg[:8] == '\001VERSION':
version = random.choice(('http://www.mibbit.com ajax IRC Client','mIRC v6.35 Khaled Mardam-Bey','xchat 0.24.1 Linux 2.6.27-8-eeepc i686','rZNC Version 1.0 [02/01/11] - Built from ZNC','thelounge v3.0.0 -- https://thelounge.chat/'))
await self.raw(f'NOTICE {nick} \001VERSION {version}\001')
elif '!' not in args[0]:
if 'dronebl.org/lookup' in msg:
error(self.display + '\033[93mDroneBL detected\033[0m')
raise Exception('DroneBL')
else:
if [i for i in ('You\'re banned','You are permanently banned','You are banned','You are not welcome','Temporary K-line') if i in msg]:
raise Exception('K-Lined')
except (UnicodeDecodeError, UnicodeEncodeError):
pass
except Exception as ex:
error(self.display + '\033[1;31mdisconnected\033[0m', ex)
break
async def main_b(targets):
sema = asyncio.BoundedSemaphore(throttle.pthreads) # B O U N D E D S E M A P H O R E G A N G
jobs = list()
for target in targets:
jobs.append(asyncio.ensure_future(check_proxy(sema, target)))
await asyncio.gather(*jobs)
async def main_a(targets):
sema = asyncio.BoundedSemaphore(throttle.threads) # B O U N D E D S E M A P H O R E G A N G
jobs = list()
if settings.proxies:
proxies = None
del all_proxies[:len(all_proxies)]
del good_proxies[:len(good_proxies)]
while not good_proxies:
debug('scanning for fresh Socks5 proxies...')
proxies = get_proxies()
if proxies:
debug(f'testing {len(proxies):,} proxies...')
await main_b(proxies)
if not good_proxies:
await asyncio.sleep(300)
else:
await asyncio.sleep(300)
debug(f'found {len(good_proxies):,} proxies')
for target in targets:
try:
ipaddress.IPv4Address(target)
except:
error('invalid ip address', target)
else:
if settings.proxies:
for proxy in good_proxies:
jobs.append(asyncio.ensure_future(probe(sema, target, proxy).run()))
if not settings.proxies_only:
jobs.append(asyncio.ensure_future(probe(sema, target).run()))
random.shuffle(jobs)
await asyncio.gather(*jobs)
# Main
print('#'*56)
print('#{:^54}#'.format(''))
print('#{:^54}#'.format('EFknockr (internet relay chat beacon)'))
print('#{:^54}#'.format('Developed by acidvegas in Python'))
print('#{:^54}#'.format('https://git.acid.vegas/efknockr'))
print('#{:^54}#'.format(''))
print('#'*56)
if True:
raise SystemExit('those who are not skids may figure out how to use this...') # ;) by removing this you agree to only test this on your own server(s) LOLOLOOL
if settings.proxies:
try:
import aiosocks
except ImportError:
raise SystemExit('missing required library \'aiosocks\' (https://pypi.org/project/aiosocks/)')
if len(sys.argv) != 2:
raise SystemExit('error: invalid arguments')
targets_file = sys.argv[1]
if not os.path.isfile(targets_file):
raise SystemExit('error: invalid file path')
targets = [line.rstrip() for line in open(targets_file).readlines() if line and line not in bad.donotscan]
del targets_file
debug(f'loaded {len(targets):,} targets')
while True:
asyncio.run(main_a(targets))
debug('EFknockr has finished knocking!!')
if not settings.daemon:
break