def check_passwd_file_status(self): message = {} message['status'] = 0 message['data'] = {} files = ['/etc/passwd', '/etc/shadow'] ID = 1 for file in files: if not os.path.exists(file): continue command = f"ls -l {file} 2> /dev/null | " + " awk '{print $1}'" content = runCommand(command).decode('utf-8') if len(content): continue if file == '/etc/passwd' and content != '-rw-r--r--': message['status'] = 1 message['data'][ID] = { 'file': '/etc/passwd', 'content': content } if file == '/etc/shadow' and content != '----------': message['status'] = 1 message['data'][ID] = { 'file': '/etc/passwd', 'content': content } return message
def check_current_user(self): ''' 检查当前登陆的用户 ''' message = {} message['status'] = 0 message['current_user'] = [] command = "who" result = runCommand(command).strip().decode('utf-8') if result: message['status'] = 1 userinfo = {} for info in resutl: current_user = info.split()[0] login_time = info.split()[2] + " " + info.split()[3] userinfo['current_user'] = current_user userinfo['login_time'] = login_time remote_ip = info.split()[-1].replace('(', '').replace(')', '') if remote_ip == ":0": userinfo['remote_ip'] = 'localhost' else: userinfo['remote_ip'] = remote_ip message['current_user'].append(userinfo) return message
def check_network_link(self): ''' 查看网络链接状态 ''' message = {} message['data'] = {} command = "netstat -antp 2> /dev/null | grep 'ESTABLISHED \| SYN_SENT \|SYN_RECEIVED' | awk '{print $1,$5,$7}'" content = runCommand(command).decode('utf-8').splitlines() if content: message['status'] = 1 ID = 1 for line in content: LinkMethod = line.split(' ')[0] IP, Port = line.split(' ')[1].replace("\n", "").split(':') PID = line.split(' ')[2].split('/')[0] IP_Information = collect_ip_information(IP) message['data'][str(ID)] = {} message['data'][str(ID)]['LinkMethod'] = LinkMethod message['data'][str(ID)]['IP'] = IP message['data'][str(ID)]['Port'] = Port message['data'][str(ID)]['IP_Information'] = IP_Information message['data'][str(ID)]['PID'] = PID ID += 1 else: message['status'] = 0 return message
def check_network_promisc(self): message = {} command = "ifconfig 2>/dev/null| grep PROMISC | grep RUNNING" content = runCommand(command).decode('utf-8').splitlines() if len(content) > 0: message['status'] = 1 else: message['status'] = 0 return message
def check_moved_files(self): message = {} message['moved_files'] = [] command = f"find {self.directory_to_check} -newermt '{self.start_time}' ! -newermt '{self.end_time}' 2>/dev/null" files = runCommand(command).strip().decode('utf-8').split() message['file_count'] = len(files) # 去除找到的目录 for file in files: if os.path.isfile(file): message['moved_files'].append(file) return message
def check_reverse_shell_status(self): message = {} for file in os.listdir('/proc/'): if file.isdigit(): filepath = os.path.join('%s%s%s' % ('/proc/', file, '/cmdline')) content = runCommand(f"strings {filepath} 2> /dev/null").decode('utf-8') info = analysis_string(content) if info: message[filepath] = [file,info] return message
def check_ssh_wrapper(self): message = {} message['status'] = 0 command = "file /usr/sbin/sshd 2>/dev/null" content = runCommand(command).decode('utf-8') if len(content): if ('ELF' not in content) and ('executable' not in content): message['status'] = 1 return message
def check_TMOUT(self): ''' 检查是否设置账号主动注销 ''' message = {} message['status'] = 1 message['filepath'] = self.config_content['TMOUT']['file'] if not os.path.exists(message['filepath']): message['status'] = 0 return message message['TMOUT_Time'] = runCommand( "cat /etc/profile | grep TMOUT | awk -F[=] '{print $2}'").strip( ).decode('utf-8') # 提取TMOUT设置的时间 return message
def check_password_policy(self): ''' 查看账户策略限制 ''' message = {} message['status'] = 1 message['filepath'] = self.config_content['policy']['policyfilepath'] if not os.path.exists(message['filepath']): message['status'] = 0 return message message['pass_max'] = runCommand( "cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v ^# | awk '{print $2}'" ).strip().decode('utf-8') # 口令最大生存周期 message['pass_min'] = runCommand( "cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v ^# | awk '{print $2}'" ).strip().decode('utf-8') # 口令最小生存周期 message['pass_len'] = runCommand( "cat /etc/login.defs | grep PASS_MIN_LEN | grep -v ^# | awk '{print $2}'" ).strip().decode('utf-8') # 口令最小长度 message['pass_age'] = runCommand( "cat /etc/login.defs | grep PASS_WARN_AGE | grep -v ^# | awk '{print $2}'" ).strip().decode('utf-8') # 口令过期警告时间天数 return message
def check_sudo_status(self): message = {} message['status'] = 0 message['data'] = {} ID = 1 files = self.config_content['SUDO']['files'].split(':') for file in files: command = f"cat {file} 2> /dev/null | grep -v '#' | grep '[ALL=(ALL)|ALL=(ALL:ALL)]' | " + " awk '{print $1}'" content = runCommand(command).decode('utf-8').splitlines() for user in content: if user[0] != '%' and user.replace("\n", "") != 'root': message['status'] = 1 message['data'][ID] = {'file': file, 'content': 'user'} ID += 1 return message
def check_suid_status(self): message = {} message['status'] = 0 message['data'] = {} ID = 1 directory = self.config_content['SUID']['directory'] exclude_command = self.config_content['SUID']['exclude'] command = f"find {directory} ! -path '/proc/*' -type f -perm -4000 2>/dev/null | grep -vE '{exclude_command}'" content = runCommand(command).decode('utf-8').splitlines() if content: message['status'] = 1 for line in content: message['data'][ID] = {'content': line} ID += 1 return message
def check_hide_files_status(self): ''' 检测是否存在可疑隐藏文件 ''' message = {} message['evil_file'] = [] message['wrong_file'] = [] command = f'find {self.hidden_directory} ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/private/*" -name ".*" 2>/dev/null' files = runCommand(command).decode('utf-8').splitlines() for file in files: if file == '/usr/share/man/man1/..1.gz': continue else: content = analysis_file(file) if content: message['evil_file'].append(file + ". 内容为 : " + content) else: continue return message
def check_work_status(self): cpu_message = [] memory_message = [] max_cpu = self.config_content['work_status']['max_cpu'] max_mem = self.config_content['work_status']['max_mem'] normal_service = self.config_content['work_status']['normal_service'] current_pid = os.getpid() # 用户 PID CPU使用率 内存使用率 COMMAND command = f"ps aux | grep -v PID | sort -rn -k +3 | head | awk '{{print $1,$2,$3,$4,$11}}'| grep -v '{normal_service}'" content = runCommand(command).decode('utf-8').splitlines() for line in content: info = line.strip().split(' ') if int(info[1]) != current_pid: if float(info[2]) >= max_cpu: cpu_message.append(info) if float(info[3]) >= max_mem: memory_message.append(info) return cpu_message,memory_message
def analysis_file(file): ''' 恶意文件分析 ''' try: if not os.path.exists(file): return # 文件不存在 if os.path.isdir(file): return # 文件为目录 if os.path.getsize(file) == 0: return # 文件为空 if round(os.path.getsize(file) / float(1024 * 1024)) > 10: return # 文件太大 command = f"strings {file} 2> /dev/null" content = runCommand(command).decode('utf-8').splitlines() for line in content: if check_shell(line): return line # 返回反弹Shell内容 else: return # 正常 except: return # 出现错误
def check_hidden_process(self): ''' 比较ps -ef 和 /proc 目录下所有进程 找出隐藏的进程 ''' message = [] try: # ps -ef 来获取所有pid号 command = "ps -ef 2>/dev/null | awk 'NR>1{print $2}'" command_processes = runCommand(command).decode('utf-8').splitlines() # 扫描 /proc目录 file_processes = [] if not os.path.exists('/proc/'): return message for file in os.listdir('/proc'): if file.isdigit(): file_processes.append(file) # 比较 hidden_processes = list(set(pid_pro_file).difference(set(pid_process))) message = message + hidden_processes except: pass finally: return message