User:a proofreader/Anti-phish script/kickbot.py
Jump to navigation
Jump to search
This is a bot written in Python, using the Twisted library. If it has operator status, it will kick anyone who posts RuneScape phishing links.
The following would run the bot under the nickname KickBot in the channels #wikia-runescape, and #cvn-wikia-runescape, with all channel messages logged into logfile.txt.
$ python kickbot.py --nickname KickBot --user KickBotIdent --password KickBotPassword --realname KickBot --channels #wikia-runescape,#cvn-wikia-runescape --filename logfile.txt
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
import time
import sys
import re
phishing_regex = re.compile(r"(http://|www.)[^/ ]*\.?runescape\.com\.(?!au(?!\.))" # unexpected dot after .com, exception for .com.au, [[wikipedia:.au#Second-level domains]]
+ "|(http://|www\.)[^/ ]*(?!runescape)r[-\.]?u[-\.]?n[-\.]?e[-\.]?s[-\.]?c[-\.]?a[-\.]?p[-\.]?e[-\.]" # not runescape (matched above), but something containing a dash or dot (more aggressive)
+ "|(http://|www\.)runescape\.co\.(?!uk(?!\.))" # runescape.co.tld, excluding runescape.co.uk (legit)
+ "|(http://|www\.)[^/ ]*(?!runescape-wiki)(-runescape|runescape-)[^/ ]*/" # dashes instead of dots at expected places
, re.IGNORECASE)
class MessageLogger:
def __init__(self, file):
self.file = file
def log(self, message):
timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))
self.file.write('%s %s\n' % (timestamp, message))
self.file.flush()
def close(self):
self.file.close()
class KickBot(irc.IRCClient):
def __init__(self, nickname,
password=None, realname=None, username=None):
self.nickname = nickname
self.password = password
self.realname = realname
self.username = username
def connectionMade(self):
irc.IRCClient.connectionMade(self)
self.logger = MessageLogger(open(self.factory.filename, "a"))
self.logger.log("[connected at %s]" %
time.asctime(time.localtime(time.time())))
def connectionLost(self, reason):
irc.IRCClient.connectionLost(self, reason)
self.logger.log("[disconnected at %s]" %
time.asctime(time.localtime(time.time())))
self.logger.close()
def signedOn(self):
self.join(self.reactor.channels)
def joined(self, channel):
self.logger.log("[I have joined %s]" % channel)
def privmsg(self, user, channel, msg):
nick = user.split("!", 1)[0]
lnick = nick.lower()
self.logger.log("<%s> %s" % (nick, msg))
#Is it in a query?
if channel == self.nickname:
self.msg(nick, "hi")
if (lnick !== "bullbot" and
lnick !== "evilbot" and lnick !== "runescript" and
phishing_regex.search(msg)):
self.kick("#wikia-runescape", nick, "Phishing link detected")
self.logger.log("[I have kicked %s from %s (Phishing link detected)]" % (nick, channel))
action = privmsg
class KickBotFactory(protocol.ClientFactory):
def __init__(self, nickname, password=None, realname=None, username=None,
channels="#wikia-runescape", filename=None):
self.nickname = nickname
self.password = password
self.realname = realname
self.username = username
self.channels = channels
self.filename = filename
def buildProtocol(self, addr):
p = KickBot(self.nickname, self.password, self.realname, self.username)
p.factory = self
return p
def clientConnectionLost(self, connector, reason):
connector.connect()
def clientConnectionFailed(self, connector, reason):
print "connection failed:", reason
reactor.stop()
if __name__ == "__main__":
try:
import argparse
except ImportError:
print "Python 2.7 is required for this script to work."
sys.exit(2)
parser = argparse.ArgumentParser()
parser.add_argument("--nickname", help="Nickname for the bot to use")
parser.add_argument("--realname", help="Realname for the bot to use")
parser.add_argument("--password", help="Password for the bot to use")
parser.add_argument("--username", help="Username for the bot to use")
parser.add_argument("--channels", help="Channel(s) the bot should join")
parser.add_argument("--filename", help="Filename for the bot to log under")
args = parser.parse_args()
factory = KickBotFactory(args.nickname, args.password, args.realname,
args.username, args.channels, args.filename)
reactor.connectTCP("irc.freenode.net", 6667, factory)
reactor.run()