def shorten_url(url): try: res, headers = web.post('http://git.io', 'url=' + web.quote(url), return_headers=True) return headers['location'] except: return url
def url_handler(bot, trigger): """ Check for malicious URLs """ check = True # Enable URL checking strict = False # Strict mode: kick on malicious URL positives = 0 # Number of engines saying it's malicious total = 0 # Number of total engines use_vt = True # Use VirusTotal check = bot.config.safety.enabled_by_default if check is None: # If not set, assume default check = True # DB overrides config: setting = bot.db.get_channel_value(trigger.sender, 'safety') if setting is not None: if setting == 'off': return # Not checking elif setting in ['on', 'strict', 'local', 'local strict']: check = True if setting == 'strict' or setting == 'local strict': strict = True if setting == 'local' or setting == 'local strict': use_vt = False if not check: return # Not overriden by DB, configured default off netloc = urlparse(trigger.group(1)).netloc if any(regex.search(netloc) for regex in known_good): return # Whitelisted apikey = bot.config.safety.vt_api_key try: if apikey is not None and use_vt: payload = {'resource': unicode(trigger), 'apikey': apikey, 'scan': '1'} if trigger not in bot.memory['safety_cache']: result = web.post(vt_base_api_url + 'report', payload) if sys.version_info.major > 2: result = result.decode('utf-8') result = json.loads(result) age = time.time() data = {'positives': result['positives'], 'total': result['total'], 'age': age} bot.memory['safety_cache'][trigger] = data if len(bot.memory['safety_cache']) > 1024: _clean_cache(bot) else: print('using cache') result = bot.memory['safety_cache'][trigger] positives = result['positives'] total = result['total'] except Exception as e: LOGGER.debug('Error from checking URL with VT.', exc_info=True) pass # Ignoring exceptions with VT so MalwareDomains will always work if unicode(netloc).lower() in malware_domains: # malwaredomains is more trustworthy than some VT engines # therefor it gets a weight of 10 engines when calculating confidence positives += 10 total += 10 if positives > 1: # Possibly malicious URL detected! confidence = '{}%'.format(round((positives / total) * 100)) msg = 'link posted by %s is possibly malicious ' % bold(trigger.nick) msg += '(confidence %s - %s/%s)' % (confidence, positives, total) bot.say('[' + bold(color('WARNING', 'red')) + '] ' + msg) if strict: bot.write(['KICK', trigger.sender, trigger.nick, 'Posted a malicious link'])
def url_handler(bot, trigger): """ Check for malicious URLs """ check = True # Enable URL checking strict = False # Strict mode: kick on malicious URL positives = 0 # Number of engines saying it's malicious total = 0 # Number of total engines use_vt = True # Use VirusTotal check = bot.config.safety.enabled_by_default if check is None: # If not set, assume default check = True # DB overrides config: setting = bot.db.get_channel_value(trigger.sender, 'safety') if setting is not None: if setting == 'off': return # Not checking elif setting in ['on', 'strict', 'local', 'local strict']: check = True if setting == 'strict' or setting == 'local strict': strict = True if setting == 'local' or setting == 'local strict': use_vt = False if not check: return # Not overriden by DB, configured default off netloc = urlparse(trigger.group(1)).netloc if any(regex.search(netloc) for regex in known_good): return # Whitelisted apikey = bot.config.safety.vt_api_key try: if apikey is not None and use_vt: payload = {'resource': str(trigger), 'apikey': apikey, 'scan': '1'} if trigger not in bot.memory['safety_cache']: result = web.post(vt_base_api_url + 'report', payload) if sys.version_info.major > 2: result = result.decode('utf-8') result = json.loads(result) age = time.time() data = { 'positives': result['positives'], 'total': result['total'], 'age': age } bot.memory['safety_cache'][trigger] = data if len(bot.memory['safety_cache']) > 1024: _clean_cache(bot) else: print('using cache') result = bot.memory['safety_cache'][trigger] positives = result['positives'] total = result['total'] except Exception: LOGGER.debug('Error from checking URL with VT.', exc_info=True) pass # Ignoring exceptions with VT so MalwareDomains will always work if str(netloc).lower() in malware_domains: # malwaredomains is more trustworthy than some VT engines # therefor it gets a weight of 10 engines when calculating confidence positives += 10 total += 10 if positives > 1: # Possibly malicious URL detected! confidence = '{}%'.format(round((positives / total) * 100)) msg = 'link posted by %s is possibly malicious ' % bold(trigger.nick) msg += '(confidence %s - %s/%s)' % (confidence, positives, total) bot.say('[' + bold(color('WARNING', 'red')) + '] ' + msg) if strict: bot.write([ 'KICK', trigger.sender, trigger.nick, 'Posted a malicious link' ])
def handle_auth_response(): code = bottle.request.query.code state = bottle.request.query.state repo = state.split(':')[0] channel = state.split(':')[1] data = {'client_id': sopel_instance.config.github.client_id, 'client_secret': sopel_instance.config.github.secret, 'code': code} raw = web.post('https://github.com/login/oauth/access_token', data, headers={'Accept': 'application/json'}) try: res = json.loads(raw) if 'scope' not in res: raise ValueError('You\'ve already completed authorization on this repo') if 'write:repo_hook' not in res['scope']: raise ValueError('You didn\'t allow read/write on repo hooks!') access_token = res['access_token'] data = { "name": "web", "active": "true", "events": ["*"], "config": { "url": sopel_instance.config.github.external_url, "content_type": "json" } } raw = web.post('https://api.github.com/repos/{}/hooks?access_token={}'.format(repo, access_token), json.dumps(data)) res = json.loads(raw) if 'ping_url' not in res: if 'errors' in res: raise ValueError(', '.join([error['message'] for error in res['errors']])) else: raise ValueError('Webhook creation failed, try again.') raw, headers = web.get(res['ping_url'] + '?access_token={}'.format(access_token), return_headers=True) title = 'Done!' header = 'Webhook setup complete!' body = 'That was simple, right?! You should be seeing a completion message in {} any second now'.format(channel) flair = 'There\'s no way it was that easy... things are never this easy...' except Exception as e: title = 'Error!' header = 'Webhook setup failed!' body = 'Please try using the link in {} again, something went wrong!'.format(channel) flair = str(e) page = ''' <!DOCTYPE html> <html> <head> <title>{title}</title> <style> body {{ width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }} </style> </head> <body> <h1>{header}</h1> <p>{body}</p> <small><em>{flair}</em></small> </body> </html> ''' return page.format(title=title, header=header, body=body, flair=flair)
def url_handler(bot, trigger): """ Check for malicious URLs """ check = True # Enable URL checking strict = False # Strict mode: kick on malicious URL positives = 0 # Number of engines saying it's malicious total = 0 # Number of total engines use_vt = True # Use VirusTotal check = bot.config.safety.enabled_by_default if check is None: # If not set, assume default check = True # DB overrides config: setting = bot.db.get_channel_value(trigger.sender, "safety") if setting is not None: if setting == "off": return # Not checking elif setting in ["on", "strict", "local", "local strict"]: check = True if setting == "strict" or setting == "local strict": strict = True if setting == "local" or setting == "local strict": use_vt = False if not check: return # Not overriden by DB, configured default off netloc = urlparse(trigger).netloc if any(regex.search(netloc) for regex in known_good): return # Whitelisted apikey = bot.config.safety.vt_api_key try: if apikey is not None and use_vt: payload = {"resource": unicode(trigger), "apikey": apikey, "scan": "1"} if trigger not in bot.memory["safety_cache"]: result = web.post(vt_base_api_url + "report", payload) if sys.version_info.major > 2: result = result.decode("utf-8") result = json.loads(result) age = time.time() data = {"positives": result["positives"], "total": result["total"], "age": age} bot.memory["safety_cache"][trigger] = data if len(bot.memory["safety_cache"]) > 1024: _clean_cache(bot) else: print("using cache") result = bot.memory["safety_cache"][trigger] positives = result["positives"] total = result["total"] except Exception as e: LOGGER.debug("Error from checking URL with VT.", exc_info=True) pass # Ignoring exceptions with VT so MalwareDomains will always work if unicode(netloc).lower() in malware_domains: # malwaredomains is more trustworthy than some VT engines # therefor it gets a weight of 10 engines when calculating confidence positives += 10 total += 10 if positives > 1: # Possibly malicious URL detected! confidence = "{}%".format(round((positives / total) * 100)) msg = "link posted by %s is possibliy malicious " % bold(trigger.nick) msg += "(confidence %s - %s/%s)" % (confidence, positives, total) bot.say("[" + bold(color("WARNING", "red")) + "] " + msg) if strict: bot.write(["KICK", trigger.sender, trigger.nick, "Posted a malicious link"])
def handle_auth_response(): code = bottle.request.query.code state = bottle.request.query.state repo = state.split(':')[0] channel = state.split(':')[1] data = { 'client_id': sopel_instance.config.github.client_id, 'client_secret': sopel_instance.config.github.secret, 'code': code } raw = web.post('https://github.com/login/oauth/access_token', data, headers={'Accept': 'application/json'}) try: res = json.loads(raw) if 'scope' not in res: raise ValueError( 'You\'ve already completed authorization on this repo') if 'write:repo_hook' not in res['scope']: raise ValueError('You didn\'t allow read/write on repo hooks!') access_token = res['access_token'] data = { "name": "web", "active": True, "events": ["*"], "config": { "url": sopel_instance.config.github.external_url, "content_type": "json" } } raw = web.post( 'https://api.github.com/repos/{}/hooks?access_token={}'.format( repo, access_token), json.dumps(data)) res = json.loads(raw) if 'ping_url' not in res: if 'errors' in res: raise ValueError(', '.join( [error['message'] for error in res['errors']])) else: raise ValueError('Webhook creation failed, try again.') raw, headers = web.get(res['ping_url'] + '?access_token={}'.format(access_token), return_headers=True) title = 'Done!' header = 'Webhook setup complete!' body = 'That was simple, right?! You should be seeing a completion message in {} any second now'.format( channel) flair = 'There\'s no way it was that easy... things are never this easy...' except Exception as e: title = 'Error!' header = 'Webhook setup failed!' body = 'Please try using the link in {} again, something went wrong!'.format( channel) flair = str(e) page = ''' <!DOCTYPE html> <html> <head> <title>{title}</title> <style> body {{ width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }} </style> </head> <body> <h1>{header}</h1> <p>{body}</p> <small><em>{flair}</em></small> </body> </html> ''' return page.format(title=title, header=header, body=body, flair=flair)