def GET(self, protocol=None, nsfm="false", **kwargs): """Get list of active sessions""" sql = ''' SELECT host, port, session_id as id, protocol, owner, title, users, password, nsfm, started, usernames FROM drawpile_sessions WHERE unlisted=false AND last_active >= current_timestamp - interval %s''' params = [settings.SESSION_TIMEOUT] if protocol: sql += " AND protocol=%s" params.append(protocol) if nsfm.lower() != 'true' and nsfm != '': sql += " AND nsfm=false" sql += " ORDER BY title ASC" with settings.db() as conn: with conn.cursor() as cur: cur.execute(sql, params) columns = tuple(x[0] for x in cur.description) sessions = [Session(**dict(zip(columns, row))) for row in cur] return [s.to_json() for s in sessions]
def GET(self, protocol=None, nsfm="false", **kwargs): """Get list of active sessions""" sql = ''' SELECT host, port, session_id as id, protocol, owner, title, users, password, nsfm, started FROM drawpile_sessions WHERE unlisted=false AND last_active >= current_timestamp - interval %s''' params = [settings.SESSION_TIMEOUT] if protocol: sql += " AND protocol=%s" params.append(protocol) if nsfm.lower() != 'true' and nsfm != '': sql += " AND nsfm=false" sql += " ORDER BY title ASC" with settings.db() as conn: with conn.cursor() as cur: cur.execute(sql, params) columns = tuple(x[0] for x in cur.description) sessions = [Session(**dict(zip(columns, row))) for row in cur] return [s.to_json() for s in sessions]
def DELETE(self): """Unlist this announcement""" with settings.db() as conn: with conn.cursor() as cur: self._check_update_key(cur) cur.execute( 'UPDATE drawpile_sessions SET unlisted=true WHERE id=%s', [self.pk]) cherrypy.response.status = 204
def PUT(self): """Refresh this announcement""" data = cherrypy.request.json with settings.db() as conn: with conn.cursor() as cur: self._check_update_key(cur) set_sql = ['last_active = current_timestamp'] params = [] if data.get('title', None): set_sql.append('title=%s') params.append(data['title']) if data.get('users', None): set_sql.append('users=%s') params.append(data['users']) if data.get('password', None): set_sql.append('password=%s') params.append(data['password']) if data.get('owner', None): set_sql.append('owner=%s') params.append(data['owner']) if data.get('nsfm', 'false').lower() != 'false' or is_nsfm_title(data.get('title', '')): set_sql.append('nsfm=true') if 'usernames' in data: set_sql.append('usernames=%s') params.append(sanitize_usernames(data['usernames'])) sql = 'UPDATE drawpile_sessions SET ' +\ ', '.join(set_sql) +\ ' WHERE id=%s' params.append(self.pk) cur.execute(sql, params) return {'status': 'ok'}
def PUT(self): """Refresh this announcement""" data = cherrypy.request.json with settings.db() as conn: with conn.cursor() as cur: self._check_update_key(cur) set_sql = ['last_active = current_timestamp'] params = [] if data.get('title', None): set_sql.append('title=%s') params.append(data['title']) if data.get('users', None): set_sql.append('users=%s') params.append(data['users']) if data.get('password', None): set_sql.append('password=%s') params.append(data['password']) if data.get('owner', None): set_sql.append('owner=%s') params.append(data['owner']) if data.get('nsfm', 'false').lower() != 'false' or is_nsfm_title(data.get('title', '')): set_sql.append('nsfm=true') sql = 'UPDATE drawpile_sessions SET ' +\ ', '.join(set_sql) +\ ' WHERE id=%s' params.append(self.pk) cur.execute(sql, params) return {'status': 'ok'}
def process_data(thread_name, working_queue): while not exit_flag: queue_lock.acquire() if not work_queue.empty(): work = working_queue.get() plugin_id = work['plugin_id'] target_host = work['target_host'] target_port = work['target_port'] target_protocol = work['target_protocol'] message = '%s for Plugin ID: %s; Host: %s; Port: %s\n%s' % (thread_name, plugin_id, target_host, target_port, time_elapsed()) print(good_msg(message)) # Start processing the stuff here conn = settings.db() mycursor = conn.cursor(prepared=True) sql = 'SELECT * FROM `plugin` INNER JOIN `command` ON `plugin`.`command_id` = `command`.`command_id` WHERE `plugin`.`plugin_id` = %s' mycursor.execute(sql, (plugin_id, )) result = mycursor.fetchall() parent_directory = autorun_output_file_path + "/" + str(plugin_id) + "/" if not (os.path.isdir(parent_directory)): os.mkdir(parent_directory) if mycursor.rowcount == 0: if plugin_id not in error_plugin_list: error_plugin_list.append(plugin_id) error(plugin_id, target_host, target_port, target_protocol) error_file = parent_directory + "ERROR_" + str(plugin_id) + ".txt" if not (os.path.isfile(error_file)): f = open(error_file, "a+") f.write("Error Plugin ID: " + str(plugin_id) + " is missing from database.") f.close() else: if result[0][1] != 1: if isinstance(result[0][3], str): command = result[0][3] + ' 2>&1' else: command = result[0][3].decode('utf-8') + ' 2>&1' destination_text_file_path = parent_directory + str(plugin_id)+'_' + str(target_host)+'_'+str(target_port) + '.txt' if '\r' in command: command = command.replace('\r', '') if '\n' in command: command = command.replace('\n', '') if 'IP_ADDRESS' in command: command = command.replace('IP_ADDRESS', str(target_host)) if 'PORT' in command: command = command.replace('PORT', str(target_port)) if 'PLUGIN' in command: command = command.replace('PLUGIN', str(plugin_id)) if 'RANDOM_PATH' in command: target_txt_file = '%s_%s_%s_TEMP.txt' % (plugin_id, target_host, target_port) random_path = '"' + parent_directory + target_txt_file + '"' command = command.replace('RANDOM_PATH', random_path) task_left = work_queue.qsize() task_completed = total_tasks - task_left if not (os.path.exists(destination_text_file_path)): # Do not change this part, create a file for better debugging when a thread hangs/wont terminate f = open(destination_text_file_path, "w") f.write("[Command] " + command + '\n\n') f.write(subprocess.check_output(command, shell=True).decode()) f.close() message = 'Completed command for Plugin ID: %s; Host: %s; Port: %s; Task Left: %s; Task Completed: %s\n%s' % (plugin_id, target_host, target_port, task_left, task_completed, time_elapsed()) print(good_msg(message)) else: message = 'Skipped executing Plugin ID: %s because the validation check already exists for specific host: %s:%s\n%s' % (plugin_id, target_host, target_port, time_elapsed()) print(warning_msg(message)) mycursor.close() conn.close() # End processing the stuff here queue_lock.release() time.sleep(1)
def create(cls, data, client_ip): # Validate data if not SESSION_ID_RE.match(data['id']): raise cherrypy.HTTPError(422, "BADDATA:Invalid ID") host = data.get('host', client_ip) # TODO validate host name if 'port' not in data: port = 27750 else: if not data['port'].isdigit(): raise cherrypy.HTTPError(422, "BADDATA:Invalid port number") port = int(data['port']) if port <= 0 or port >= 65536: raise cherrypy.HTTPError(422, "BADDATA:Invalid port number") sql = '''INSERT INTO drawpile_sessions (host, port, session_id, protocol, owner, title, users, password, nsfm, update_key, client_ip) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id''' with settings.db() as conn: with conn.cursor() as cur: # Rate limiting cur.execute('''SELECT COUNT(id) FROM drawpile_sessions WHERE client_ip=%s AND last_active >= current_timestamp - interval %s''', [client_ip, settings.SESSION_TIMEOUT] ) count = cur.fetchone()[0] if count > settings.RATELIMIT: raise cherrypy.HTTPError( 429, "You have announced too many sessions ({0}) too quickly!".format(count)) # Check for duplicates cur.execute('''SELECT COUNT(id) FROM drawpile_sessions WHERE host=%s AND port=%s AND session_id=%s AND unlisted=false AND last_active >= current_timestamp - interval %s''', [host, port, data['id'], settings.SESSION_TIMEOUT] ) count = cur.fetchone()[0] if count > 0: raise cherrypy.HTTPError( 422, "DUPLICATE:session already listed") # OK: insert entry update_key = ''.join(random.SystemRandom().choice( string.ascii_uppercase + string.digits) for _ in range(16)) try: cur.execute(sql, ( host, port, data['id'], data['protocol'], data['owner'], data.get('title', ''), data['users'], data.get('password', False), data.get('nsfm', False) or is_nsfm_title(data.get('title', '')), update_key, client_ip )) except KeyError as ke: raise cherrypy.HTTPError(422, "BADDATA:" + str(ke)) pk = cur.fetchone()[0] return (pk, update_key)
def create(cls, data, client_ip): # Validate data if not SESSION_ID_RE.match(data['id']): raise cherrypy.HTTPError(422, "BADDATA:Invalid ID") host = data.get('host', client_ip) # TODO validate host name if 'port' not in data: port = 27750 else: if not data['port'].isdigit(): raise cherrypy.HTTPError(422, "BADDATA:Invalid port number") port = int(data['port']) if port <= 0 or port >= 65536: raise cherrypy.HTTPError(422, "BADDATA:Invalid port number") sql = '''INSERT INTO drawpile_sessions (host, port, session_id, protocol, owner, title, users, usernames, password, nsfm, update_key, client_ip) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id''' with settings.db() as conn: with conn.cursor() as cur: # Rate limiting cur.execute('''SELECT COUNT(id) FROM drawpile_sessions WHERE client_ip=%s AND last_active >= current_timestamp - interval %s''', [client_ip, settings.SESSION_TIMEOUT] ) count = cur.fetchone()[0] if count > settings.RATELIMIT: raise cherrypy.HTTPError( 429, "You have announced too many sessions ({0}) too quickly!".format(count)) # Check for duplicates cur.execute('''SELECT COUNT(id) FROM drawpile_sessions WHERE host=%s AND port=%s AND session_id=%s AND unlisted=false AND last_active >= current_timestamp - interval %s''', [host, port, data['id'], settings.SESSION_TIMEOUT] ) count = cur.fetchone()[0] if count > 0: raise cherrypy.HTTPError( 422, "DUPLICATE:session already listed") # OK: insert entry update_key = ''.join(random.SystemRandom().choice( string.ascii_uppercase + string.digits) for _ in range(16)) try: cur.execute(sql, ( host, port, data['id'], data['protocol'], data['owner'], data.get('title', ''), data['users'], sanitize_usernames(data.get('usernames', [])), data.get('password', False), data.get('nsfm', False) or is_nsfm_title(data.get('title', '')), update_key, client_ip )) except KeyError as ke: raise cherrypy.HTTPError(422, "BADDATA:" + str(ke)) pk = cur.fetchone()[0] return (pk, update_key)
import web import os, sys lib_path = os.path.abspath('../') sys.path.append(lib_path) from models import database, profile from settings import db, render db = db() render = render() class hello: def GET(self): password = db.query("SELECT * FROM profile")[0] halo = profile.getUser() return render.index(halo=halo, password = password) class page: def GET(self): return render.page()
def main(input_file, mid_file): conn = settings.db() mycursor = conn.cursor(prepared=True) plugin_output = '' tree = ET.parse(input_file) root = tree.getroot()[1] total_hosts = len(root) for i in range(0, total_hosts): target_ip = root[i].attrib['name'] total_findings = len(root[i]) for j in range(1, total_findings): duplicate = 0 output = list() risk_factor = root[i][j].find('risk_factor').text if (risk_factor != 'None'): plugin_output = '' plugin_id = root[i][j].attrib['pluginID'] sql = 'SELECT * FROM `plugin` INNER JOIN `command` ON `plugin`.`command_id` = `command`.`command_id` WHERE `plugin`.`plugin_id` = %s' mycursor.execute(sql, (plugin_id, )) result = mycursor.fetchall() workbook = load_workbook(filename=mid_file) ws = workbook['Items'] row_count = ws.max_row + 1 for row in range(2, row_count): if ws.cell(row=row, column=1).value == plugin_id: affected_host = str(target_ip) + ':' + root[i][ j].attrib['port'] + ' (' + root[i][j].attrib[ 'protocol'].upper() + ')' if mycursor.rowcount > 0: if result[0][1] == 1: plugin_output = 'For ' + affected_host + ':\r\n' if root[i][j].find('plugin_output') != None: current_plugin_output = root[i][j].find( 'plugin_output').text while ' ' in current_plugin_output: current_plugin_output = current_plugin_output.replace( ' ', ' ') plugin_output += current_plugin_output else: plugin_output += 'No POC available for this plugin' ws.cell(row=row, column=4).value += '\r\n' + affected_host if len(ws.cell(row=row, column=9).value) > 30000: num = 10 while True: if isinstance( ws.cell(row=row, column=num).value, str): if len(ws.cell(row=row, column=num).value) < 30000: ws.cell( row=row, column=num ).value += plugin_output + '\r\n' break else: num += 1 else: ws.cell(row=row, column=num ).value = plugin_output + '\r\n' break else: if 'Please refer to PoC folder' not in ws.cell( row=row, column=9).value: ws.cell( row=row, column=9).value += '\r\n' + plugin_output duplicate = 1 workbook.save(filename=mid_file) break if duplicate == 0: name = root[i][j].attrib['pluginName'] description = root[i][j].find('description').text while ' ' in description: description = description.replace(' ', ' ') if root[i][j].find('cvss3_temporal_score') != None: cvss_score = root[i][j].find( 'cvss3_temporal_score').text elif root[i][j].find('cvss3_base_score') != None: cvss_score = root[i][j].find('cvss3_base_score').text elif root[i][j].find('cvss_temporal_score') != None: cvss_score = root[i][j].find( 'cvss_temporal_score').text elif root[i][j].find('cvss_base_score') != None: cvss_score = root[i][j].find('cvss_base_score').text else: if root[i][j].attrib['severity'] == 4: cvss_score = 10 elif root[i][j].attrib['severity'] == 3: cvss_score = 8.9 elif root[i][j].attrib['severity'] == 2: cvss_score = 6.9 else: cvss_score = 3.9 if float(cvss_score) < 4: severity = 'Low' elif float(cvss_score) < 7: severity = 'Medium' elif float(cvss_score) < 9: severity = 'High' else: severity = 'Critical' affected_host = str(target_ip) + ':' + root[i][j].attrib[ 'port'] + ' (' + root[i][j].attrib['protocol'].upper( ) + ')' if mycursor.rowcount > 0: if result[0][1] == 1: plugin_output = 'For ' + affected_host + ':\r\n' if root[i][j].find('plugin_output') != None: current_plugin_output = root[i][j].find( 'plugin_output').text while ' ' in current_plugin_output: current_plugin_output = current_plugin_output.replace( ' ', ' ') plugin_output += current_plugin_output else: plugin_output += 'No POC available for this plugin' else: plugin_output = 'Please refer to PoC folder' else: print( 'This plugin is not in database, please tell the developer to add this plugin in (%s)' % (plugin_id)) remediation = root[i][j].find('solution').text status = 'Not Solved' output = [ plugin_id, name, description, affected_host, remediation, float(cvss_score), severity, status, plugin_output ] output_to_xlsx(output, mid_file) output_file = mid_file[4:] sort(mid_file, output_file) mycursor.close() conn.close()