Server IP : 104.21.38.3 / Your IP : 172.70.189.105 Web Server : Apache System : Linux krdc-ubuntu-s-2vcpu-4gb-amd-blr1-01.localdomain 5.15.0-142-generic #152-Ubuntu SMP Mon May 19 10:54:31 UTC 2025 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/server/panel/class_v2/ |
Upload File : |
# coding: utf-8 # +------------------------------------------------------------------- # | aaPanel # +------------------------------------------------------------------- # | Copyright (c) 2015-2099 aaPanel(www.aapanel.com) All rights reserved. # +------------------------------------------------------------------- # | Author: lkq <[email protected]> # | # | 日志分析工具 # +------------------------------------------------------------------- import os import time import public from public.validate import Param class log_analysis: path = '/www/server/panel/script/' log_analysis_path = '/www/server/panel/script/log_analysis.sh' def __init__(self): if not os.path.exists(self.path + '/log/'): os.makedirs(self.path + '/log/') if not os.path.exists(self.log_analysis_path): log_analysis_data = r'''help(){ echo "Usage: ./action.sh [options] [FILE] [OUTFILE] " echo "Options:" echo "xxx.sh san_log [FILE] Get the log list with the keywords xss|sql|mingsense information|php code execution in the successful request [OUTFILE] 11" echo "xxx.sh san [FILE] Get list of logs with sql keyword in successful request [OUTFILE] 11 " } if [ $# == 0 ] then help exit fi if [ ! -e $2 ] then echo -e "$2: log file does not exist" exit fi if [ ! -d "log" ] then mkdir log fi echo "[*] Starting ..." if [ $1 == "san_log" ] then echo "1">./log/$3 echo "Start getting xss cross-site scripting attack logs..." grep -E ' (200|302|301|500|444|403|304) ' $2 | grep -i -E "(javascript|data:|alert\(|onerror=|%3Cimg%20src=x%20on.+=|%3Cscript|%3Csvg/|%3Ciframe/|%3Cscript%3E).*?HTTP/1.1" >./log/$3xss.log echo "Analysis logs have been saved to./log/$3xss.log" echo "Scan to attack count: "`cat ./log/$3xss.log |wc -l` echo "20">./log/$3 echo "Start getting sql injection attack logs..." echo "Analysis logs have been saved to./log/$3sql.log" grep -E ' (200|302|301|500|444|403) ' $2 | grep -i -E "(from.+?information_schema.+|select.+(from|limit)|union(.*?)select|extractvalue\(|case when|extractvalue\(|updatexml\(|sleep\().*?HTTP/1.1" > ./log/$3sql.log echo "Scan to attack count: "`cat ./log/$3sql.log |wc -l` echo "40">./log/$3 echo -e "Start getting related logs such as file traversal/code execution/scanner information/configuration files" grep -E ' (200|302|301|500|444|403) ' $2 | grep -i -E "(\.\.|WEB-INF|/etc|\w\{1,6\}\.jsp |\w\{1,6\}\.php|\w+\.xml |\w+\.log |\w+\.swp |\w*\.git |\w*\.svn |\w+\.json |\w+\.ini |\w+\.inc |\w+\.rar |\w+\.gz |\w+\.tgz|\w+\.bak |/resin-doc).*?HTTP/1.1" >./log/$3san.log echo "Analysis logs have been saved to./log/$3san.log" echo "Scan to attack count: "`cat ./log/$3san.log |wc -l` echo "50">./log/$3 echo -e "Start getting the php code execution scan log" grep -E ' (200|302|301|500|444|403) ' $2 | grep -i -E "(gopher://|php://|file://|phar://|dict://data://|eval\(|file_get_contents\(|phpinfo\(|require_once\(|copy\(|\_POST\[|file_put_contents\(|system\(|base64_decode\(|passthru\(|\/invokefunction\&|=call_user_func_array).*?HTTP/1.1" >./log/$3php.log echo "Analysis logs have been saved to./log/$3php.log" echo "Scan to attack count: "`cat ./log/$3php.log |wc -l` echo "60">./log/$3 echo -e "The number and value of the most visited ip is being counted" # cat $2|awk -F" " '{print $1}'|sort|uniq -c|sort -nrk 1 -t' '|head -100 awk '{print $1}' $2 |sort|uniq -c |sort -nr |head -100 >./log/$3ip.log echo "80">./log/$3 echo -e "The number and value of the url of the most visited request interface is being counted" awk '{print $7}' $2 |sort|uniq -c |sort -nr |head -100 >./log/$3url.log echo "100">./log/$3 elif [ $1 == "san" ] then echo "1">./log/$3 echo "Start getting xss cross-site scripting attack logs..." grep -E ' (200|302|301|500|444|403|304) ' $2 | grep -i -E "(javascript|data:|alert\(|onerror=|%3Cimg%20src=x%20on.+=|%3Cscript|%3Csvg/|%3Ciframe/|%3Cscript%3E).*?HTTP/1.1" >./log/$3xss.log echo "Analysis logs have been saved to./log/$3xss.log" echo "Scan to attack count: "`cat ./log/$3xss.log |wc -l` echo "20">./log/$3 echo "Start getting sql injection attack logs..." echo "Analysis logs have been saved to./log/$3sql.log" grep -E ' (200|302|301|500|444|403) ' $2 | grep -i -E "(from.+?information_schema.+|select.+(from|limit)|union(.*?)select|extractvalue\(|case when|extractvalue\(|updatexml\(|sleep\().*?HTTP/1.1" > ./log/$3sql.log echo "Scan to attack count: "`cat ./log/$3sql.log |wc -l` echo "40">./log/$3 echo -e "Start getting related logs such as file traversal/code execution/scanner information/configuration files" grep -E ' (200|302|301|500|444|403) ' $2 | grep -i -E "(\.\.|WEB-INF|/etc|\w\{1,6\}\.jsp |\w\{1,6\}\.php|\w+\.xml |\w+\.log |\w+\.swp |\w*\.git |\w*\.svn |\w+\.json |\w+\.ini |\w+\.inc |\w+\.rar |\w+\.gz |\w+\.tgz|\w+\.bak |/resin-doc).*?HTTP/1.1" >./log/$3san.log echo "Analysis logs have been saved to./log/$3san.log" echo "Scan to attack count: "`cat ./log/$3san.log |wc -l` echo "60">./log/$3 echo -e "Start getting the php code execution scan log" grep -E ' (200|302|301|500|444|403) ' $2 | grep -i -E "(gopher://|php://|file://|phar://|dict://data://|eval\(|file_get_contents\(|phpinfo\(|require_once\(|copy\(|\_POST\[|file_put_contents\(|system\(|base64_decode\(|passthru\(|\/invokefunction\&|=call_user_func_array).*?HTTP/1.1" >./log/$3php.log echo "Analysis logs have been saved to./log/$3php.log" echo "Scan to attack count: "`cat ./log/$3php.log |wc -l` echo "100">./log/$3 else help fi echo "[*] shut down" ''' public.WriteFile(self.log_analysis_path, log_analysis_data) def get_log_format(self, path): ''' @获取日志格式 ''' f = open(path, 'r') data = None for i in f: data = i.split() break f.close() if not data: return False if not public.check_ip(data[0]): return False if len(data) < 6: return False return True def log_analysis(self, get): ''' 分析日志 @param path:需要分析的日志 @return 返回具体的分析结果 @ 需要使用异步的方式进行扫描 ''' # 校验参数 try: get.validate([ Param('action').String(), Param('path').String(), ], [ public.validate.trim_filter(), ]) except Exception as ex: public.print_log("error info: {}".format(ex)) return public.return_message(-1, 0, str(ex)) path = get.path log_path = public.Md5(path) serverType = public.get_webserver() if serverType == "nginx": pass elif serverType == 'apache': #path = path.strip("-access_log") + '-access_log' pass elif serverType == 'openlitespeed': # path = path.strip("_ols.access_log") + '_ols.access_log' # return public.ReturnMsg(False, 'openlitespeed is not supported yet') return public.fail_v2('openlitespeed is not supported yet') # public.print_log("path1:{}".format(path)) # public.print_log("serverType:{}".format(serverType)) if not os.path.exists(path): return public.return_message(-1, 0, public.lang("No log file")) if os.path.getsize(path) > 9433107294: return public.return_message(-1, 0, public.lang("The log file is too large!")) if os.path.getsize(path) < 10: return public.return_message(-1, 0, public.lang("log is empty")) # public.print_log("log_path{}".format(log_path)) # public.print_log("self.log_analysis_path{}".format(self.log_analysis_path)) # public.print_log("path{}".format(path)) if self.get_log_format(path): public.ExecShell( "cd %s && bash %s san_log %s %s &" % (self.path, self.log_analysis_path, path, log_path)) else: public.ExecShell("cd %s && bash %s san %s %s &" % (self.path, self.log_analysis_path, path, log_path)) speed = self.path + '/log/' + log_path+".time" public.WriteFile(speed,str(time.time())+"[]"+time.strftime('%Y-%m-%d %X',time.localtime())+"[]"+"0") return public.return_message(0, 0, public.lang("Start scan successful")) def speed_log(self, get): ''' 扫描进度 @param path:扫描的日志文件 @return 返回进度 ''' # 校验参数 try: get.validate([ Param('path').String(), ], [ public.validate.trim_filter(), ]) except Exception as ex: public.print_log("error info: {}".format(ex)) return public.return_message(-1, 0, str(ex)) path = get.path.strip() log_path = public.Md5(path) speed = self.path + '/log/' + log_path if os.path.getsize(speed) < 1: return public.return_message(-1, 0, public.lang("log is empty")) if not os.path.exists(speed): return public.return_message(-1, 0, public.lang("The directory was not scanned")) try: data = public.ReadFile(speed) data = int(data) if data==100: time_data,start_time,status=public.ReadFile(self.path + '/log/' + log_path+".time").split("[]") public.WriteFile(speed+".time",str(time.time()-float(time_data)) + "[]" + start_time + "[]" + "1") return public.return_message(0,0, data) except: return public.return_message(0, 0, 0) def get_log_count(self, path, is_body=False): count = 0 if is_body: if not os.path.exists(path): return '' data = '' with open(path, 'r') as f: for i in f: count += 1 data = data.replace('<', '<').replace('>', '>') + i.replace('<', '<').replace('>', '>') if count >= 300: break return data else: if not os.path.exists(path): return count with open(path, 'rb') as f: for i in f: count += 1 return count def get_result(self, get): ''' 扫描结果 @param path:扫描的日志文件 @return 返回结果 ''' path = get.path.strip() log_path = public.Md5(path) speed = self.path + '/log/' + log_path result = {} if os.path.exists(speed): result['is_status'] = True else: result['is_status'] = False if os.path.exists(speed+".time"): time_data, start_time, status = public.ReadFile(self.path + '/log/' + log_path + ".time").split("[]") if status == '1' or start_time==1: result['time']=time_data result['start_time']=start_time else: result['time'] = "0" result['start_time'] = "2022/2/22 22:22:22" if 'time' not in result: result['time'] = "0" result['start_time'] = "2022/2/22 22:22:22" result['xss'] = self.get_log_count(speed + 'xss.log') result['sql'] = self.get_log_count(speed + 'sql.log') result['san'] = self.get_log_count(speed + 'san.log') result['php'] = self.get_log_count(speed + 'php.log') result['ip'] = self.get_log_count(speed + 'ip.log') result['url'] = self.get_log_count(speed + 'url.log') return public.return_message(0,0,result) def get_detailed(self, get): # 校验参数 try: get.validate([ Param('path').String(), Param('type').String(), ], [ public.validate.trim_filter(), ]) except Exception as ex: public.print_log("error info: {}".format(ex)) return public.return_message(-1, 0, str(ex)) path = get.path.strip() log_path = public.Md5(path) speed = self.path + '/log/' + log_path type_list = ['xss', 'sql', 'san', 'php', 'ip', 'url'] if get.type not in type_list: return public.return_message(-1, 0, public.lang("Type mismatch")) if not os.path.exists(speed + get.type + '.log'): return public.return_message(-1, 0, public.lang("Record does not exist")) return public.return_message(0,0,self.get_log_count(speed + get.type + '.log', is_body=True))