def DownloadModsecJson(): a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) except: b = 'NO' if b == 'YES': random = randint(0, 999999999) query = db(db.production.id_rand == request.args[0]).select( db.production.app_name, db.production.id_rand) out1 = subprocess.Popen([ '/usr/bin/tar', '-czf', '/home/www-data/waf2py_community/applications/Waf2Py/static/logs/modsec_logs_' + query[0]['app_name'] + '_' + str(random) + '.tar.gz', '-C', '/opt/waf/nginx/var/log/' + query[0]['app_name'] + '/', query[0]['app_name'] + '_audit.log' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg, err = out1.communicate() r = A('Modsecurity_logs.tar.gz', _href='/Waf2Py/static/logs/modsec_logs_' + query[0]['app_name'] + '_' + str(random) + '.tar.gz') else: session.flash = T('Error in data supplied') r = '' return r
def DebugLogs(): a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) except: b = 'NO' if b == 'YES': query = db(db.production.id_rand == request.args[0]).select( db.production.app_name) # - %s' %(session['auth']['user']['first_name']) query[0] cmd = 'tac /opt/waf/nginx/var/log/' + query[0][ 'app_name'] + '/' + query[0]['app_name'] + '_debug.log | head -400' out1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg, err = out1.communicate() access_list = [] #print err for i in msg: access_list.append(dict(access_log=i)) else: access_list.append('Error in data suplied') return response.json({'debug_logs': debug_list})
def DeleteRoute(): # Check vars a = stuffs.Filtro().CheckStr(request.vars['id']) if a != 'YES': session.flash = T('Error in data supplied') return query = db(db.routes.id_rand == request.vars['id']).select( db.routes.ip, db.routes.gw_ip, db.routes.iface) process = subprocess.Popen([ 'sudo', '/sbin/route', 'del', query[0]['ip'], 'gw', query[0]['gw_ip'], 'dev', query[0]['iface'] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) process, err = process.communicate() if err: session.flash = err return db(db.routes.id_rand == request.vars['id']).delete() # redirect(URL('Routes')) session.flash = T('Route Deleted') return
def DownloadDebug(): a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) except: b = 'NO' if b == 'YES': random = randint(0, 999999999) query = db(db.production.id_rand == request.args[0]).select( db.production.app_name, db.production.id_rand) print query out1 = subprocess.Popen([ '/usr/bin/zip', '-j', '/home/www-data/waf2py_community/applications/Waf2Py/static/logs/debug_logs_' + query[0]['app_name'] + '_' + str(random) + '.zip', '/opt/waf/nginx/var/log/' + query[0]['app_name'] + '/' + query[0]['app_name'] + '_debug.log' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg, err = out1.communicate() r = A('Debug_logs.zip', _href='/Waf2Py/static/logs/debug_logs_' + query[0]['app_name'] + '_' + str(random) + '.zip') else: session.flash = 'Error in data supplied' r = '' return r
def AddInterface(): n = network.Network() iface_names = n.iface_names() a = stuffs.Filtro() #b = a.CheckStrIP(request.vars['ip']) ip = IS_IPADDRESS()(request.vars['ip'])[1] #mask = a.CheckStrIP(request.vars['mask']) mask = IS_IPADDRESS()(request.vars['mask'])[1] if ip == None and mask == None and request.vars['name'] in iface_names: query = db(db.system.iface_ip == request.vars['ip']).select( db.system.iface_ip, db.system.iface_name) if not query: try: c = n.AddIface(request.vars['ip'], request.vars['mask'], request.vars['name'], db) if 'Interface' in c['message']: session.flash = T('Interface Added') + '!' db.system.insert(iface_ip=str(request.vars['ip']), iface_name=c['device']) else: session.flash = c['message'] except Exception as e: session.flash = str(e) else: session.flash = T('Virtual IP exist') else: session.flash = T('Error in data suplied') return dict()
def AddInterface(): n = network.Network() iface_names = n.iface_names() a = stuffs.Filtro() b = a.CheckStrIP(request.vars['ip']) mask = a.CheckStrIP(request.vars['mask']) if b == 'YES' and mask == 'YES' and request.vars[ 'name'] in iface_names and len(request.vars['ip']) <= 45: query = db(db.system.iface_ip == request.vars['ip']).select( db.system.iface_ip, db.system.iface_name) if not query: try: c = n.AddIface(request.vars['ip'], request.vars['mask'], request.vars['name']) if 'Interface' in c['message']: session.flash = 'Interface Added!' db.system.insert(iface_ip=str(request.vars['ip']), iface_name=c['device']) else: session.flash = c['message'] except Exception as e: response.flash = str(e) #print e else: session.flash = 'Virtual IP exist' else: response.flash = 'Error in data suplied' return dict()
def ExcludedRules(): a = stuffs.Filtro() b = a.CheckStr(request.args[0]) rule_list = [] if b == 'YES': query = db(db.exclusions.id_rand == request.args[0]).select( db.exclusions.attack_name, db.exclusions.id_rand, db.exclusions.rules_id, db.exclusions.type, db.exclusions.user, db.exclusions.local_path, ) if query: for row in query: #print row['attack_name'] rule_list.append( dict(attack_name=row['attack_name'], rule_id=row['rules_id'], id_rand=row['id_rand'], tipo=row['type'], path=row['local_path'], user=row['user'])) else: rule_list.append('There are no excluded rules') else: rule_list.append('Error in data supplied') return response.json({'rules': rule_list})
def AddGateway(): #Get IP Default Gateway cmd_ipgateway = "/sbin/ip route | awk '/default/ { print $3 }'" default_gateway = subprocess.Popen(cmd_ipgateway, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) default_gateway, err = default_gateway.communicate() if err: response.flash = err return #Check vars a = stuffs.Filtro().CheckStrIP(request.vars['ip']) b = stuffs.Filtro().CheckStrIP(request.vars['gateway']) c = stuffs.Filtro().CheckName(request.vars['iface']) #eprint str(default_gateway.splitlines()[0]) + " " + request.vars['gateway'] #Validate vars if a == 'YES' and b == 'YES' and c == 'YES' and str( default_gateway.splitlines()[0]) != str(request.vars['gateway']): process = subprocess.Popen([ 'sudo', '/sbin/route', 'add', request.vars['ip'], 'gw', request.vars['gateway'], 'dev', request.vars['iface'] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) process, err = process.communicate() if err: response.flash = err return a = stuffs.Stuffs().password() db.routes.insert(id_rand=a, ip=request.vars['ip'], gw_ip=request.vars['gateway'], iface=request.vars['iface']) else: session.flash = 'Error in data supplied' return #redirect(URL('Routes')) session.flash = "Routes Added" return
def SaveProtocols(): import changeconfig a = stuffs.Filtro() b = a.CheckStr(request.vars['id']) if b != 'YES': return query = db(db.production.id_rand == request.vars['id']).select( db.production.nginx_conf_data, db.production.app_name) text = "" array = ['unchecked', 'unchecked', 'unchecked'] if request.vars['1'] == "true": text = text + " TLSv1" array[0] = 'checked' if request.vars['2'] == "true": text = text + " TLSv1.1" array[1] = 'checked' if request.vars['3'] == "true": text = text + " TLSv1.2" array[2] = 'checked' if text == "": response.flash = "Error" return #print array text = text + ";" try: change = changeconfig.Change() r = change.Text(query[0]['nginx_conf_data'], 'ssl_protocols', " ssl_protocols%s" % (text)) DataNginx = '\n'.join(r['new_list']) AppName = query[0]['app_name'] UpdateFiles = stuffs.CreateFiles() UpdateFiles.CreateNginxFiles(ProdNginxAvail, AppName, DataNginx) u = stuffs.Nginx() u.Reload() db.certificate.update_or_insert( db.certificate.id_rand == request.vars['id'], protocol=array) db(db.production.id_rand == request.vars['id']).update( nginx_conf_data='\n'.join(r['new_list'])) except Exception as e: response.flash = e return response.flash = "Changed Protocol SSL" return
def CipherPrefer(): import changeconfig a = stuffs.Filtro() b = a.CheckStr(request.vars['id']) if b != 'YES': return query = db(db.production.id_rand == request.vars['id']).select( db.production.nginx_conf_data, db.production.app_name) text = "" if request.vars['status'] == "On": text = text + " on" db.certificate.update_or_insert( db.certificate.id_rand == request.vars['id'], prefer_cipher="checked") elif request.vars['status'] == "Off": text = text + " off" db.certificate.update_or_insert( db.certificate.id_rand == request.vars['id'], prefer_cipher="unchecked") else: response.flash = "Error" return text = text + ";" try: change = changeconfig.Change() r = change.Text(query[0]['nginx_conf_data'], 'ssl_prefer_server_ciphers', " ssl_prefer_server_ciphers%s" % (text)) DataNginx = '\n'.join(r['new_list']) AppName = query[0]['app_name'] UpdateFiles = stuffs.CreateFiles() UpdateFiles.CreateNginxFiles(ProdNginxAvail, AppName, DataNginx) u = stuffs.Nginx() u.Reload() db(db.production.id_rand == request.vars['id']).update( nginx_conf_data='\n'.join(r['new_list'])) except Exception as e: response.flash = e return response.flash = "Changed SSL prefer server ciphers SSL" return
def DenyPaths(): # print request.vars a = stuffs.Filtro() r = '' try: b = a.CheckStr(request.vars['id']) except Exception as error: r = error b = 'NO' response.flash = T('Error in data supplied') path_list = [] count_safe = 0 go_ahead = '' if b == 'YES': for i in request.vars.keys(): if len(request.vars[i]) == 0: response.flash = "Paths can't be empty" break elif 'path' in i: path_list.append(request.vars[i]) count_safe += 1 if count_safe <= 20: # increase here if you want more than 20 paths to deny... go_ahead = 'YES' else: go_ahead = 'NO' if b == 'YES' and go_ahead == 'YES': # falta hacer que se guarden en la db y se muestren en la vista paths = '\n'.join(path_list) db(db.production.id_rand == request.vars['id']).update( paths_denied=paths) total_deny = '' for path in path_list: # print 'path: ', path total_deny += "location %s {\nreturn 403;}\n" % (path) # print 'total: ', total_deny name = db(db.production.id_rand == request.vars['id']).select( db.production.app_name) f = open( DenyPathsDir + name[0]['app_name'] + '/' + name[0]['app_name'] + '_denyPaths.conf', 'w') f.write(total_deny) f.close() r = stuffs.Nginx() r.Reload() response.flash = 'Configuration was saved' r = 'Configuration was saved' else: response.flash = T('Error in data supplied') if r == '': r = 'Error in data supplied' return r
def ExcludeLocal(): a = stuffs.Filtro() try: b = a.CheckStr(request.vars['id_rand']) c = a.CheckRule(request.vars['ruleid']) d = a.CheckName(request.vars['attack_name']) f = a.CheckPath(request.vars['path']) except: b = 'NO' if b == 'YES' and c == 'YES' and d == 'YES' and f == 'YES': data = db((db.exclusions.id_rand == request.vars['id_rand']) & (db.exclusions.type == 1) & (db.exclusions.rules_id == request.vars['ruleid']) & (db.exclusions.local_path == request.vars['path'])).select(db.exclusions.rules_id, db.exclusions.local_path) modsec_conf = db(db.production.id_rand == request.vars['id_rand']).select(db.production.app_name, db.production.modsec_conf_data) if not data: #random custom_id custom_id = randint(0, 99999999) #add rule id to exclusions in db db.exclusions.insert(rules_id=request.vars['ruleid'], id_rand=request.vars['id_rand'], custom_id=custom_id, local_path=request.vars['path'], type=1, attack_name=request.vars['attack_name'], user=session['auth']['user']['username']) #get updated rules id rulesid = db((db.exclusions.id_rand == request.vars['id_rand']) & (db.exclusions.type == 1)).select(db.exclusions.rules_id, db.exclusions.local_path, db.exclusions.custom_id) #Recreate the rules rules = '#ExclusionLocal\n' for i in rulesid: rules = rules + "SecRule REQUEST_URI \"@beginswith "+i['local_path']+"\" \"id:"+str(i['custom_id'])+",phase:1,pass,nolog, ctl:ruleRemoveById="+i['rules_id']+"\"\n" rules_list = rules #replace old rules with new ones replace = re.sub(r'^(##\w+Local\w+##\n).*(##\w+Local\w+##)', r'\1%s\2' %(rules_list.decode("utf-8")), modsec_conf[0]['modsec_conf_data'], flags=re.S | re.M) db(db.production.id_rand == request.vars['id_rand']).update(modsec_conf_data=replace)#'\n'.join(r)) db.commit() UpdateFiles = stuffs.CreateFiles() try: UpdateFiles.CreateModsecConf('prod', modsec_conf[0]['app_name'], replace) a = stuffs.Nginx() b = a.Reload() #NewLogApp(db2, auth.user.username, "Mode: prod " + data[0]['app_name']) except Exception as e: #NewLogError(db2, auth.user.username, "Mode: " + str(e)) session.flash = e response.flash = 'Rule has been excluded locally' r = 'Rule has been excluded locally' else: response.flash = 'Rule ID or Path already excluded' r = 'Rule ID already excluded' else: response.flash = 'Error in data supplied' r = 'Error in data supplied' #print b,c,d,f return response.json(r)
def ExcludeGlobal(): #import changeconfig a = stuffs.Filtro() try: b = a.CheckStr(request.vars['id_rand']) c = a.CheckRule(request.vars['ruleid']) d = a.CheckName(request.vars['attack_name']) except: b = 'NO' if b == 'YES' and c == 'YES' and d == 'YES': data = db((db.exclusions.id_rand == request.vars['id_rand']) & (db.exclusions.type == 0) & (db.exclusions.rules_id == request.vars['ruleid'])).select(db.exclusions.rules_id) modsec_conf = db(db.production.id_rand == request.vars['id_rand']).select(db.production.app_name, db.production.modsec_conf_data) if not data: #add rule id to exclusions in db db.exclusions.insert(rules_id=request.vars['ruleid'], id_rand=request.vars['id_rand'], type=0, attack_name=request.vars['attack_name'], user=session['auth']['user']['username']) #get updated rules id rulesid = db((db.exclusions.id_rand == request.vars['id_rand']) & (db.exclusions.type == 0)).select(db.exclusions.rules_id) #change = changeconfig.Change() rules = '#ExclusionGLobally\n' for i in rulesid: rules = rules + "SecRuleRemoveById " + str(i['rules_id']) + '\n' rules_list = rules replace = re.sub(r'^(##\w+Global\w+##\n).*(##\w+Global\w+##)', r'\1%s\2' %(rules_list.decode("utf-8")), modsec_conf[0]['modsec_conf_data'], flags=re.S | re.M) db(db.production.id_rand == request.vars['id_rand']).update(modsec_conf_data=replace)#'\n'.join(r)) db.commit() UpdateFiles = stuffs.CreateFiles() try: UpdateFiles.CreateModsecConf('prod', modsec_conf[0]['app_name'], replace) a = stuffs.Nginx() b = a.Reload() #NewLogApp(db2, auth.user.username, "Mode: prod " + data[0]['app_name']) except Exception as e: #NewLogError(db2, auth.user.username, "Mode: " + str(e)) session.flash = e response.flash = 'Rule has been excluded globally' r = 'Rule has been excluded globally' else: response.flash = 'Rule ID already excluded' r = 'Rule ID already excluded' else: response.flash = 'Error in data supplied' r = 'Error in data supplied' return response.json(r)
def SavedCipher(): import changeconfig a = stuffs.Filtro() b = a.CheckStr(request.vars['id']) if b != 'YES': response.flash = "Error" return if any(c in str(request.vars['ciphers']) for c in "\"/',%#$=*()[]{}?¿|&<>¨~°^ ."): response.flash = "Error" return query = db(db.production.id_rand == request.vars['id']).select( db.production.nginx_conf_data, db.production.app_name) text = request.vars['ciphers'] text2 = "'" + text + "';" try: change = changeconfig.Change() r = change.Text(query[0]['nginx_conf_data'], 'ssl_ciphers', " ssl_ciphers %s" % (text2)) DataNginx = '\n'.join(r['new_list']) AppName = query[0]['app_name'] UpdateFiles = stuffs.CreateFiles() UpdateFiles.CreateNginxFiles(ProdNginxAvail, AppName, DataNginx) u = stuffs.Nginx() u.Reload() db.certificate.update_or_insert( db.certificate.id_rand == request.vars['id'], ciphers=text) db(db.production.id_rand == request.vars['id']).update( nginx_conf_data='\n'.join(r['new_list'])) except Exception as e: response.flash = e return response.flash = "Changed SSL Cipher" return
def DelInterface(): a = stuffs.Filtro() b = a.CheckStrIP(request.vars['iface_ip']) if b == 'YES': #get ip data query = db(db.system.iface_ip == request.vars['iface_ip']).select( db.system.used_by, db.system.iface_name) gw = os.popen("route | awk '{print $8}'") for i in gw: try: if query[0]['iface_name'] in i: session.flash = "You CAN'T DELETE Main Interface >:(" redirect(URL('VirtualIps')) except: redirect(URL('VirtualIps')) try: #check if ip is being used a = query[0]['used_by'] if a != None: session.flash = "Interface is being used by %s" % (a) r = "Interface is being used by %s" % (a) else: subprocess.Popen( ['sudo', 'ifconfig', query[0]['iface_name'], 'down'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) db(db.system.iface_ip == request.vars['iface_ip']).delete() session.flash = 'Virtual Ip removed' r = 'Virtual Ip removed' except: session.flash = 'Error in data supplied' r = 'Error in data supplied' return response.json(data=r)
def DownloadLogZip(): import random import string import time import os a = stuffs.Filtro() try: #print request.args[1] b = a.CheckStr(request.args[0]) c = a.CheckStr35(request.args[1]) #print b,c except: b = 'NO' c = 'NO' if b == 'YES' and c == 'YES': chars = string.letters + string.digits pwdSize = 10 rand = ''.join((random.choice(chars)) for x in range(pwdSize)) log_name = db((db.logs_file.id_rand == request.args[0]) & (db.logs_file.id_rand2 == request.args[1])).select( db.logs_file.log_name) app_name = db(db.production.id_rand == request.args[0]).select( db.production.app_name) cmd = '/bin/cp ' + WafLogsPath + app_name[0][ 'app_name'] + '/' + log_name[0][ 'log_name'] + ' ' + DownloadLogPath + rand + log_name[0][ 'log_name'] out1 = os.system(cmd) if out1 == 0: redirect(URL('static', 'logs/' + rand + log_name[0]['log_name'])) else: session.flash = 'Error in data supplied' redirect(URL('default', 'Websites')) else: session.flash = 'Error in data supplied' redirect(URL('default', 'Websites'))
def AddHeaders(): a = stuffs.Filtro() # print request.vars check_list = [] try: b = a.CheckStr(request.vars['id']) except Exception as debug: d = debug r = debug b = 'NO' response.flash = T('Error in data supplied') # something strange happens below, is more slow when POST contains no data ....... if b == 'YES': if len(request.vars) == 1 and request.vars.keys()[0] == 'id': db(db.production.id_rand == request.vars['id']).update( extra_headers="") nginx_conf = db( db.production.id_rand == request.vars['id']).select( db.production.app_name, db.production.nginx_conf_data) replace = re.sub( r'(^ ##startInsertHead\w+##\n).*(^ ##endInsertHead\w+##)', r'\1%s\2' % (''), nginx_conf[0]['nginx_conf_data'], flags=re.S | re.M) db(db.production.id_rand == request.vars['id']).update( nginx_conf_data=replace) # '\n'.join(r)) db.commit() UpdateFiles = stuffs.CreateFiles() # try: # get the new conf nginx_conf = db( db.production.id_rand == request.vars['id']).select( db.production.app_name, db.production.nginx_conf_data) UpdateFiles.CreateNginxFiles(ProdNginxAvail, nginx_conf[0]['app_name'], nginx_conf[0]['nginx_conf_data']) response.flash = 'Configuration was saved' r = stuffs.Nginx() r.Reload() r = 'Configuration was saved' else: for test in request.vars.keys(): if test != 'id': if len(request.vars[test]) == 2: check_list.append('YES') else: check_list.append('NO') response.flash = T('Error in data supplied') if request.vars[test][1] == "": check_list.append('NO') response.flash = 'Header must have a value!' else: check_list.append('YES') if len(request.vars[test][0]) != 0: check_list.append('YES') else: response.flash = 'Header name can\'t be empty!' check_list.append('NO') r = '' if 'NO' not in check_list and len(check_list) > 1: cookies = [] cookies_list = '' for i in request.vars.keys(): if 'cookie' in i: cookies.append(' add_header ' + '"' + request.vars[i][0] + '" "' + request.vars[i][1] + '";\n') cookies_list = cookies_list + \ request.vars[i][0] + ' ' + request.vars[i][1] + '\n' else: pass db(db.production.id_rand == request.vars['id']).update( extra_headers=cookies_list) nginx_conf = db( db.production.id_rand == request.vars['id']).select( db.production.app_name, db.production.nginx_conf_data) replace = re.sub( r'(^ ##startInsertHead\w+##\n).*(^ ##endInsertHead\w+##)', r'\1%s\2' % (''.join(cookies)), nginx_conf[0]['nginx_conf_data'], flags=re.S | re.M) db(db.production.id_rand == request.vars['id']).update( nginx_conf_data=replace) # '\n'.join(r)) db.commit() UpdateFiles = stuffs.CreateFiles() try: # get the new conf nginx_conf = db( db.production.id_rand == request.vars['id']).select( db.production.app_name, db.production.nginx_conf_data) UpdateFiles.CreateNginxFiles(ProdNginxAvail, nginx_conf[0]['app_name'], nginx_conf[0]['nginx_conf_data']) response.flash = 'Configuration was saved' r = stuffs.Nginx() r.Reload() r = 'Configuration was saved' # NewLogApp(db2, auth.user.username, "Mode: prod " + data[0]['app_name']) except Exception as e: # NewLogError(db2, auth.user.username, "Mode: " + str(e)) session.flash = e r = e else: # print 'not continue' r = 'Error in data supplied' return response.json(r)
def SaveCerts(): a = stuffs.Filtro() b = a.CheckStr(request.vars['id']) if b != 'YES': return query = db(db.production.id_rand == request.vars['id']).select( db.production.nginx_conf_data, db.production.app_name) aux = SslPATH + query[0]['app_name'] try: f = open('%s%s/cert_check.pem.chain' % (SslPATH, query[0]['app_name']), 'w') f.write(request.vars['cert']) f.close() f = open('%s%s/privkey_check.pem' % (SslPATH, query[0]['app_name']), 'w') f.write(request.vars['key']) f.close() if request.vars['chain']: f = open( '%s%s/cert_check.pem.chain' % (SslPATH, query[0]['app_name']), 'a') f.write('\n') f.write(request.vars['chain']) f.close() check_process = subprocess.Popen( ['openssl', 'x509', '-in', aux + '/cert_check.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check, err = check_process.communicate() if err: rm_cert = subprocess.Popen(['rm', aux + '/cert_check.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) rm_privkey = subprocess.Popen(['rm', aux + '/privkey_check.pem'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) response.flash = err return check_process = subprocess.Popen([ 'openssl', 'rsa', '-check', '-in', aux + '/privkey_check.pem', '-noout' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check, err = check_process.communicate() if err: rm_cert = subprocess.Popen(['rm', aux + '/cert_check.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) rm_privkey = subprocess.Popen(['rm', aux + '/privkey_check.pem'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) response.flash = err return mv_cert = subprocess.Popen( ['mv', aux + '/cert_check.pem.chain', aux + '/cert.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) mv_priv = subprocess.Popen( ['mv', aux + '/privkey_check.pem', aux + '/privkey.pem'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) db.certificate.update_or_insert( db.certificate.id_rand == request.vars['id'], id_rand=request.vars['id'], cert=request.vars['cert'], chain=request.vars['chain'], privkey=request.vars['key'], protocol=['checked', 'checked', 'checked'], prefer_cipher='checked', ciphers='EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH') except Exception as e: response.flash = e #print query[0]['nginx_conf_data'] response.flash = "Certificate saved" return
def WafLogs(): a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) query = db(db.production.id_rand == request.args[0]).select( db.production.app_name) if not query: n = True else: n = False except: b = 'NO' if b == 'YES' and n == False: id_rand = request.args[0] subprocess.Popen([ 'sudo', 'chown', '-R', 'www-data.www-data', '/opt/waf/nginx/var/log/' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess.Popen( ['sudo', 'chmod', '755', '-R', '/opt/waf/nginx/var/log/'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) query = db(db.production.id_rand == request.args[0]).select( db.production.app_name) # Access Logs cmd = 'tac /opt/waf/nginx/var/log/' + \ query[0]['app_name']+'/'+query[0]['app_name'] + \ '_access.log | head -1000' out1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg, err = out1.communicate() # print err access_list = [] for i in str(msg, 'utf-8', errors='ignore').splitlines(): access_list.append(i) # Error Logs cmd2 = 'tac /opt/waf/nginx/var/log/' + \ query[0]['app_name']+'/'+query[0]['app_name'] + \ '_error.log | head -1000' out2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg2, err2 = out2.communicate() # print err2 error_list = [] for e in str(msg2, 'utf-8', errors='ignore').splitlines(): error_list.append(e) # Modsec Json Logs cmd2 = 'tac /opt/waf/nginx/var/log/' + \ query[0]['app_name']+'/'+query[0]['app_name'] + \ '_audit.log | head -1000' out2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg2, err2 = out2.communicate() # print err2 modsec_list = [] for e in str(msg2, 'utf-8', errors='ignore').splitlines(): modsec_list.append(e) # Debug Logs cmd3 = 'tac /opt/waf/nginx/var/log/' + \ query[0]['app_name']+'/'+query[0]['app_name'] + \ '_debug.log | head -1000' out3 = subprocess.Popen(cmd3, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg3, err3 = out3.communicate() # print err2 debug_list = [] for f in str(msg3, 'utf-8', errors='ignore').splitlines(): debug_list.append(f) # Download Logs logs_file = db(db.logs_file.id_rand == request.args[0]).select( db.logs_file.id_rand, db.logs_file.log_name, db.logs_file.size, db.logs_file.type, db.logs_file.date, db.logs_file.id_rand2) summary_stats = db( db.summary.id_rand == request.args[0]).select().first() else: response.flash = T('Error in data supplied') redirect(URL('default', 'Websites')) id_rand = '#' return dict(page=query[0]['app_name'] + " " + T("Logs"), title="", icon="", summary=summary_stats, logs_file=logs_file, access_logs=access_list, error_logs=error_list, debug_logs=debug_list, id_rand=id_rand, modsec_json_logs=modsec_list)
def WafLogs_frame(): import re import GeoIP import json gi = GeoIP.open( "/home/www-data/waf2py_community/applications/Waf2Py/geoip/GeoIP.dat", GeoIP.GEOIP_STANDARD) gi_city = GeoIP.open( "/home/www-data/waf2py_community/applications/Waf2Py/geoip/GeoLiteCity.dat", GeoIP.GEOIP_STANDARD) a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) except: b = 'NO' logs_dict = {} logs_list = [] if b == 'YES': query = db(db.production.id_rand == request.args[0]).select( db.production.app_name, db.production.id_rand) cmd = "tac /opt/waf/nginx/var/log/%s/%s_audit.log | head -1000" % ( query[0]['app_name'], query[0]['app_name']) out1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg = out1.communicate()[0] logs_list = [] for i in str(msg, 'utf-8', errors='ignore').splitlines(): ii = json.loads(i) # print(i) k = i.rfind("}}") # This can be better if gi_city.record_by_addr( ii['transaction']['client_ip']) is not None: c = gi_city.record_by_addr(ii['transaction']['client_ip']) city = c['city'] else: city = 'Not in GeoIp Database ' if gi.country_code_by_addr( ii['transaction']['client_ip']) is not None: country_code = gi.country_code_by_addr( ii['transaction']['client_ip']) else: country_code = 'Not in GeoIp Database ' if gi.country_name_by_addr( ii['transaction']['client_ip']) is not None: country_name = gi.country_name_by_addr( ii['transaction']['client_ip']) else: country_name = 'Not in GeoIp Database ' if city == None or country_code == None or country_name == None: city = 'Not in GeoIp Database' new_string = i[:k] + ', "country_code":' + '"' + country_code + \ '", "city":"'+city+'"'+',"country":"' + \ country_name + '"}}' + i[k+2:] logs_list.append(new_string.replace('\n', '').replace('\r', '')) return response.json({'data': logs_list})
def SaveCerts(): a = stuffs.Filtro() b = a.CheckStr(request.vars['id']) if b != 'YES': response.flash = 'Invalid ID' return query = db(db.production.id_rand == request.vars['id']).select( db.production.nginx_conf_data, db.production.app_name).first() aux = SslPATH + query.app_name if query: #if not request.vars['cert'] or request.vars['key'] or request.vars['chain']: # response.flash = 'Updated certificates configuration' if request.vars['cert']: f = open('%s%s/cert_check.pem.chain' % (SslPATH, query.app_name), 'w') f.write(request.vars['cert']) f.close() if request.vars['key']: f = open('%s%s/privkey_check.pem' % (SslPATH, query.app_name), 'w') f.write(request.vars['key']) f.close() if request.vars['chain']: f = open('%s%s/cert_check.pem.chain' % (SslPATH, query.app_name), 'a') f.write('\n') f.write(request.vars['chain']) f.close() if request.vars['cert']: #check if certificate is ok check_process = subprocess.Popen( ['openssl', 'x509', '-in', aux + '/cert_check.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check, err = check_process.communicate() #delete certificate and key if they are wrong if err: rm_cert = subprocess.Popen( ['rm', aux + '/cert_check.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) rm_privkey = subprocess.Popen( ['rm', aux + '/privkey_check.pem'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) response.flash = err return if request.vars['key']: #check if key is ok check_process = subprocess.Popen([ 'openssl', 'rsa', '-check', '-in', aux + '/privkey_check.pem', '-noout' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check, err = check_process.communicate() #delete certificate and key if they are wrong if err: rm_cert = subprocess.Popen( ['rm', aux + '/cert_check.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) rm_privkey = subprocess.Popen( ['rm', aux + '/privkey_check.pem'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) response.flash = err return if request.vars['cert'] and request.vars['key']: #if certificates are ok they are renamed mv_cert = subprocess.Popen( ['mv', aux + '/cert_check.pem.chain', aux + '/cert.pem.chain'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) mv_priv = subprocess.Popen( ['mv', aux + '/privkey_check.pem', aux + '/privkey.pem'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) #save certificates in db db.certificate.update_or_insert( db.certificate.id_rand == request.vars['id'], id_rand=request.vars['id'], cert=request.vars['cert'], chain=request.vars['chain'], privkey=request.vars['key'], protocol=['checked', 'checked', 'checked', 'checked'], prefer_cipher='checked', ciphers='EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH') #this case need a commit or sometimes does not save de data #db.commit() response.flash = "Certificate saved" else: response.flash = 'Application does not exist'
def DeleteRule(): import changeconfig a = stuffs.Filtro() #print request.vars['type'] try: b = a.CheckStr(request.vars['id_rand']) c = a.CheckRule(request.vars['ruleid']) d = int(request.vars['type']) except: b = 'NO' if b == 'YES' and c == 'YES' and request.vars['type'] == '0': #remove rule from exclusions table db((db.exclusions.id_rand == request.vars['id_rand']) & (db.exclusions.rules_id == request.vars['ruleid']) & (db.exclusions.type == 0)).delete() modsec = db(db.production.id_rand == request.vars['id_rand']).select( db.production.modsec_conf_data, db.production.app_name, db.production.mode) #change configuration #Change return a dictionary with status message and the new list whith changed configuration ex: {'newconf_list': 'data', 'message':'success or error'} change = changeconfig.Change() alter = change.Text(modsec[0]['modsec_conf_data'], 'SecRuleRemoveById ' + request.vars['ruleid'], '') db(db.production.id_rand == request.vars['id_rand']).update( modsec_conf_data='\n'.join(alter['new_list'])) #get new modsec conf new_modsec = db( db.production.id_rand == request.vars['id_rand']).select( db.production.modsec_conf_data) UpdateFiles = stuffs.CreateFiles() try: UpdateFiles.CreateModsecConf('prod', modsec[0]['app_name'], new_modsec[0]['modsec_conf_data']) stuffs.Nginx().Reload() #NewLogApp(db2, auth.user.username, "Mode: prod " + data[0]['app_name']) except Exception as e: #NewLogError(db2, auth.user.username, "Mode: " + str(e)) session.flash = e response.flash = 'Rule deleted succesfully' r = 'Rule deleted succesfully' elif b == 'YES' and c == 'YES' and request.vars['type'] == '1': db((db.exclusions.id_rand == request.vars['id_rand']) & (db.exclusions.rules_id == request.vars['ruleid']) & (db.exclusions.type == 1)).delete() modsec = db(db.production.id_rand == request.vars['id_rand']).select( db.production.modsec_conf_data, db.production.app_name, db.production.mode) #change configuration #Change return a dictionary with status message and the new list whith changed configuration ex: {'newconf_list': 'data', 'message':'success or error'} change = changeconfig.Change() alter = change.Text(modsec[0]['modsec_conf_data'], 'ctl:ruleRemoveById=' + request.vars['ruleid'], '') db(db.production.id_rand == request.vars['id_rand']).update( modsec_conf_data='\n'.join(alter['new_list'])) #get new modsec conf new_modsec = db( db.production.id_rand == request.vars['id_rand']).select( db.production.modsec_conf_data) UpdateFiles = stuffs.CreateFiles() try: UpdateFiles.CreateModsecConf('prod', modsec[0]['app_name'], new_modsec[0]['modsec_conf_data']) stuffs.Nginx().Reload() #NewLogApp(db2, auth.user.username, "Mode: prod " + data[0]['app_name']) except Exception as e: #NewLogError(db2, auth.user.username, "Mode: " + str(e)) session.flash = e response.flash = 'Rule deleted succesfully' r = 'Rule deleted succesfully' else: r = 'Error in data supplied' return response.json(r)
def WafLogs(): a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) query = db(db.production.id_rand == request.args[0]).select( db.production.app_name) if not query: n = True else: n = False except: b = 'NO' if b == 'YES' and n == False: id_rand = request.args[0] subprocess.Popen([ 'sudo', 'chown', '-R', 'www-data.www-data', '/opt/waf/nginx/var/log/' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess.Popen( ['sudo', 'chmod', '755', '-R', '/opt/waf/nginx/var/log/'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) query = db(db.production.id_rand == request.args[0]).select( db.production.app_name) #Access Logs cmd = 'tac /opt/waf/nginx/var/log/' + query[0][ 'app_name'] + '/' + query[0]['app_name'] + '_access.log | head -300' out1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg, err = out1.communicate() #print err access_list = [] for i in msg.splitlines(): access_list.append(i) #Error Logs cmd2 = 'tac /opt/waf/nginx/var/log/' + query[0][ 'app_name'] + '/' + query[0]['app_name'] + '_error.log | head -300' out2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg2, err2 = out2.communicate() #print err2 error_list = [] for e in msg2.splitlines(): error_list.append(e) #Error Logs cmd3 = 'tac /opt/waf/nginx/var/log/' + query[0][ 'app_name'] + '/' + query[0]['app_name'] + '_debug.log | head -300' out3 = subprocess.Popen(cmd3, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg3, err3 = out3.communicate() #print err2 debug_list = [] for f in msg3.splitlines(): debug_list.append(f) #Download Logs logs_file = db(db.logs_file.id_rand == request.args[0]).select( db.logs_file.id_rand, db.logs_file.log_name, db.logs_file.size, db.logs_file.type, db.logs_file.date, db.logs_file.id_rand2) #Count Criticals, medium, notice, alert, error. summary = {} for severity in ['CRITICAL', 'WARNING', 'ALERT', 'NOTICE', 'ERROR']: cmd4 = 'grep -Eho "\[severity \\"' + severity + '\\"" /opt/waf/nginx/var/log/' + query[ 0]['app_name'] + '/' + query[0][ 'app_name'] + '_debug.log | wc -l' #print 'Cmd: ', cmd4 out4 = subprocess.Popen(cmd4, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg4, err4 = out4.communicate() #print msg4 summary[severity] = msg4 #Count access logs cmd5 = '/usr/bin/wc -l < /opt/waf/nginx/var/log/' + query[0][ 'app_name'] + '/' + query[0]['app_name'] + '_access.log' out5 = subprocess.Popen(cmd5, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg5, err5 = out5.communicate() requests = msg5.replace("\n", "") #print "request", len(requests) if len(requests) == 0: requests = 0 #print "request",requests db2(db2.defend_log_summary.id_rand == request.args[0]).update( id_rand=request.args[0], app_name=query[0]['app_name'], critical=summary['CRITICAL'], warning=summary['WARNING'], notice=summary['NOTICE'], error=summary['ERROR'], requests=requests) #alert = summary['ALERT'], else: response.flash = 'Error in data supplied' redirect(URL('default', 'Websites')) id_rand = '#' return dict(page=query[0]['app_name'] + " Logs", title="", icon="", summary=summary, logs_file=logs_file, access_logs=access_list, error_logs=error_list, debug_logs=debug_list, id_rand=id_rand)
def WafLogs_frame(): import re a = stuffs.Filtro() try: b = a.CheckStr(request.args[0]) except: b = 'NO' logs_dict = {} logs_list = [] if b == 'YES': query = db(db.production.id_rand == request.args[0]).select( db.production.app_name, db.production.id_rand) cmd = "cd /opt/waf/nginx/var/log/%s/audit_logs/; ls -dt -1 $PWD/**/**/* | head -200" % ( query[0]['app_name']) out1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) msg = out1.communicate()[0] for i in msg.splitlines(): #print i p = subprocess.Popen(['cat', i], stdout=subprocess.PIPE, stderr=subprocess.PIPE) logs_data, err_logs = p.communicate() if '[id "' in logs_data and '[file "/opt/waf/nginx/etc/' in logs_data and '[msg "' in logs_data: try: uri_path = re.search('^([A-Z]\w+) ([\/[\w+].* )', logs_data, re.MULTILINE).group(2) except Exception as e: #print e uri_path = "I couldn't detect the path :/" #get the block with the attack info attack_info = re.search(r'^--\w+-H--\n(.*)\n\n--\w+-Z--\n', logs_data, flags=re.S | re.M).group(0) #get date and the attacker ip first_block = re.search(r'^--\w+-A--\n(.*)\n--\w+-B--\n', logs_data, flags=re.S | re.M).group(0) date = re.search('\d+\/\w+\/\d+:\d\d:\d\d:\d\d', first_block).group(0) attacker_ip = re.search('\d+\.\d+\.\d+\.\d+', first_block).group(0) #get headers try: headers = re.search(r'^--\w+-B--\n(.*)\n--\w+-E--\n', logs_data, flags=re.S | re.M).group(0) except: headers = re.search(r'^--\w+-B--\n(.*)\n--\w+-H--\n', logs_data, flags=re.S | re.M).group(0) #get body try: body = re.search(r'^--\w+-E--\n(.*)\n--\w+-H--\n', logs_data, flags=re.S | re.M).group(0) except: body = '\n**Empty Body**' #sometimes severity is not set in the rules, in that case we do a try except try: severity = re.search('"\] \[severity "\w+.*?"\]', attack_info).group(0) severity = severity.replace('"] [severity "', '').replace('"]', '') except: severity = 'No severity set in rules' ruleid = re.search('"\] \[id "\d+.*?"\]', attack_info).group(0) ruleid = ruleid.replace('"] [id "', '').replace('"]', '') title = re.search('\[msg "\w+.*?"\]', attack_info).group(0) title = title.replace('[msg "', '').replace('"]', '') try: #some rules does not have "data" attack = re.search('\[data "\w+.*?"\]', attack_info).group(0) attack = attack.replace('[data "', '') attack = attack[:-2] except: attack = '' logs_list.append( dict(titulo=title, fecha=date, headers=headers, body=unicode(body, errors='ignore'), ataque=attack, modsec_info=attack_info, rule=ruleid, severidad=severity, attacker=attacker_ip, data='logs_data', path=uri_path, randid=query[0]['id_rand'])) else: pass else: redirect(URL('WafLogs')) return response.json({'data': logs_list})