diff --git a/GScan.py b/GScan.py index ec75c37..243b822 100644 --- a/GScan.py +++ b/GScan.py @@ -12,6 +12,7 @@ from lib.Log_Analysis import * from lib.Rootkit_Analysis import * from lib.Webshell_Analysis import * +from lib.Init import * # 作者:咚咚呛 # 版本:v0.1 @@ -42,6 +43,8 @@ print(u'\033[1;32m开始扫描当前系统安全状态...\033[0m') # 主机信息获取 Host_Info().run() + # 系统初始化检查 + SYS_INIT().run() # 文件类安全检测 File_Analysis().run() # 主机历史操作类扫描 diff --git a/README.md b/README.md index be7f660..ec6bc34 100644 --- a/README.md +++ b/README.md @@ -140,70 +140,75 @@ | 检测项 | GScan | chkrootkit | rkhunter | lynis | |:-------------|:---------: |:------: |:------: |:---------: | | 对比版本 | v0.1 | v0.53 | v1.4.6 | v2.7.1 | -| 【检测前检查项】文件alias检查 | x | √ | x | x | -| 【检测前检查项】系统重要文件完整性检测 | x | √ | x | x | -| 【主机文件检测】系统重要文件权限检测 | x | √ | √ | x | -| 【主机文件检测】文件恶意特征扫描 | √ | x | x | x | -| 【主机文件检测】文件境外IP特征扫描 | √ | x | x | x | -| 【主机文件检测】敏感目录mount隐藏检测 | x | x | √ | √ | -| 【主机操作检测】境外IP操作记录检测 | √ | x | x | x | -| 【主机操作检测】可疑操作或异常检测 | x | √ | x | x | -| 【主机进程检测】CPU&内存使用异常检测 | √ | x | x | √ | -| 【主机进程检测】I/O异常检测 | x | x | x | √ | -| 【主机进程检测】隐藏进程检测 | √ | x | √ | x | -| 【主机进程检测】反弹shell进程检测 | √ | x | x | x | -| 【主机进程检测】可疑进程名称检测 | √ | x | x | x | -| 【主机进程检测】进程exe恶意特征检测 | √ | x | x | x | -| 【主机进程检测】僵尸进程检测 | x | x | x | √ | -| 【主机进程检测】可疑的较大共享内存检测 | x | x | √ | x | -| 【主机进程检测】内存恶意特征检测 | x | x | x | x | -| 【网络链接检测】境外IP链接检测 | √ | x | x | x | -| 【网络链接检测】恶意特征链接检测 | √ | √ | √ | x | +| 【检测前检查项】文件alias检查 | √ | √ | | | +| 【检测前检查项】系统重要文件完整性检测 | | √ | | | +| 【主机文件检测】系统重要文件权限检测 | | √ | √ | | +| 【主机文件检测】文件恶意特征扫描 | √ | | | | +| 【主机文件检测】文件境外IP特征扫描 | √ | | | | +| 【主机文件检测】敏感目录mount隐藏检测 | | | √ | √ | +| 【主机操作检测】境外IP操作记录检测 | √ | | | | +| 【主机操作检测】可疑操作或异常检测 | √ | √ | | | +| 【主机进程检测】CPU&内存使用异常检测 | √ | | | √ | +| 【主机进程检测】I/O异常检测 | | | | √ | +| 【主机进程检测】隐藏进程检测 | √ | | √ | | +| 【主机进程检测】反弹shell进程检测 | √ | | | | +| 【主机进程检测】可疑进程名称检测 | √ | | | | +| 【主机进程检测】进程exe恶意特征检测 | √ | | | | +| 【主机进程检测】僵尸进程检测 | | | | √ | +| 【主机进程检测】可疑的较大共享内存检测 | | | √ | | +| 【主机进程检测】内存恶意特征检测 | | | | | +| 【网络链接检测】境外IP链接检测 | √ | | | | +| 【网络链接检测】恶意特征链接检测 | √ | √ | √ | | | 【网络链接检测】网卡混杂模式检测 | √ | √ | √ | √ | -| 【常规后门检测】LD_PRELOAD后门检测 | √ | x | √ | x | -| 【常规后门检测】LD_AOUT_PRELOAD后门检测 | √ | x | √ | x | -| 【常规后门检测】LD_ELF_PRELOAD后门检测 | √ | x | √ | x | -| 【常规后门检测】LD_LIBRARY_PATH后门检测 | √ | x | √ | x | -| 【常规后门检测】ld.so.preload后门检测 | √ | x | √ | x | -| 【常规后门检测】PROMPT_COMMAND后门检测 | √ | x | x | x | -| 【常规后门检测】Crontab后门检测 | √ | x | x | x | -| 【常规后门检测】alias后门检测 | √ | x | √ | x | -| 【常规后门检测】SSH后门检测 | √ | x | x | x | -| 【常规后门检测】SSH Wrapper后门检测 | √ | x | x | x | -| 【常规后门检测】inetd.conf后门检测 | √ | x | √ | x | -| 【常规后门检测】xinetd.conf后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/etc/init.d/)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/etc/rc.d/)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/etc/rc.local)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/usr/local/etc/rc.d)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/usr/local/etc/rc.local)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/etc/conf.d/local.start)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/etc/inittab)后门检测 | √ | x | √ | x | -| 【常规后门检测】系统启动项(/etc/systemd/system)后门检测 | √ | x | √ | x | -| 【账户安全检测】root权限账户检测 | √ | x | √ | √ | -| 【账户安全检测】空口令账户检测 | √ | x | √ | √ | -| 【账户安全检测】sudoers文件检测 | √ | x | x | √ | -| 【账户安全检测】用户组文件检测 | x | x | √ | √ | -| 【账户安全检测】密码文件检测 | x | x | √ | √ | -| 【账户安全检测】用户免密登录公钥检测 | √ | x | √ | x | -| 【日志安全检测】secure日志安全检测 | √ | x | x | x | -| 【日志安全检测】wtmp日志安全检测 | √ | √ | x | x | -| 【日志安全检测】utmp日志安全检测 | √ | √ | x | x | -| 【日志安全检测】lastlog日志安全检测 | √ | √ | x | x | -| 【安全配置检测】DNS设置检测 | √ | x | x | √ | -| 【安全配置检测】防火墙设置检测 | √ | x | x | √ | -| 【安全配置检测】hosts安全检测 | √ | x | x | √ | -| 【Rootkit检测】已知Rootkit文件特征检测 | √ | √ | √ | x | -| 【Rootkit检测】已知Rootkit LKM类特征检测 | √ | √ | √ | x | -| 【Rootkit检测】恶意软件类特征检测 | √ | x | √ | x | -| 【WEBShell检测】Nginx服务WebShell检测 | √ | x | x | x | -| 【WEBShell检测】Apache服务WebShell检测 | √ | x | x | x | -| 【WEBShell检测】Tomcat服务WebShell检测 | √ | x | x | x | -| 【WEBShell检测】Jetty服务WebShell检测 | √ | x | x | x | -| 【WEBShell检测】Resin服务WebShell检测 | √ | x | x | x | -| 【WEBShell检测】Jenkins服务WebShell检测 | √ | x | x | x | -| 【WEBShell检测】其他默认web目录WebShell检测 | √ | x | x | x | -| 【漏洞类检查】服务漏洞或配置错误检查 | x | x | x | √ | +| 【常规后门检测】LD_PRELOAD后门检测 | √ | | √ | | +| 【常规后门检测】LD_AOUT_PRELOAD后门检测 | √ | | √ | | +| 【常规后门检测】LD_ELF_PRELOAD后门检测 | √ | | √ | | +| 【常规后门检测】LD_LIBRARY_PATH后门检测 | √ | | √ | | +| 【常规后门检测】ld.so.preload后门检测 | √ | | √ | | +| 【常规后门检测】PROMPT_COMMAND后门检测 | √ | | | | +| 【常规后门检测】Cron后门检测(/var/spool/cron/) | √ | | | | +| 【常规后门检测】Cron后门检测(/etc/cron.d/) | √ | | | | +| 【常规后门检测】Cron后门检测(/etc/cron.daily/) | √ | | | | +| 【常规后门检测】Cron后门检测(/etc/cron.weekly/) | √ | | | | +| 【常规后门检测】Cron后门检测(/etc/cron.hourly/) | √ | | | | +| 【常规后门检测】Cron后门检测(/etc/cron.monthly/) | √ | | | | +| 【常规后门检测】alias后门检测 | √ | | √ | | +| 【常规后门检测】SSH后门检测 | √ | | | | +| 【常规后门检测】SSH Wrapper后门检测 | √ | | | | +| 【常规后门检测】inetd.conf后门检测 | √ | | √ | | +| 【常规后门检测】xinetd.conf后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/etc/init.d/)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/etc/rc.d/)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/etc/rc.local)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/usr/local/etc/rc.d)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/usr/local/etc/rc.local)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/etc/conf.d/local.start)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/etc/inittab)后门检测 | √ | | √ | | +| 【常规后门检测】系统启动项(/etc/systemd/system)后门检测 | √ | | √ | | +| 【账户安全检测】root权限账户检测 | √ | | √ | √ | +| 【账户安全检测】空口令账户检测 | √ | | √ | √ | +| 【账户安全检测】sudoers文件检测 | √ | | | √ | +| 【账户安全检测】用户组文件检测 | | | √ | √ | +| 【账户安全检测】密码文件检测 | √ | | √ | √ | +| 【账户安全检测】用户免密登录公钥检测 | √ | | √ | | +| 【日志安全检测】secure日志安全检测 | √ | | | | +| 【日志安全检测】wtmp日志安全检测 | √ | √ | | | +| 【日志安全检测】utmp日志安全检测 | √ | √ | | | +| 【日志安全检测】lastlog日志安全检测 | √ | √ | | | +| 【安全配置检测】DNS设置检测 | √ | | | √ | +| 【安全配置检测】防火墙设置检测 | √ | | | √ | +| 【安全配置检测】hosts安全检测 | √ | | | √ | +| 【Rootkit检测】已知Rootkit文件特征检测 | √ | √ | √ | | +| 【Rootkit检测】已知Rootkit LKM类特征检测 | √ | √ | √ | | +| 【Rootkit检测】恶意软件类特征检测 | √ | | √ | | +| 【WEBShell检测】Nginx服务WebShell检测 | √ | | | | +| 【WEBShell检测】Apache服务WebShell检测 | √ | | | | +| 【WEBShell检测】Tomcat服务WebShell检测 | √ | | | | +| 【WEBShell检测】Jetty服务WebShell检测 | √ | | | | +| 【WEBShell检测】Resin服务WebShell检测 | √ | | | | +| 【WEBShell检测】Jenkins服务WebShell检测 | √ | | | | +| 【WEBShell检测】其他默认web目录WebShell检测 | √ | | | | +| 【漏洞类检查】服务漏洞或配置错误检查 | | | | √ | diff --git a/lib/Backdoor_Analysis.py b/lib/Backdoor_Analysis.py index 8f6a2d6..c0b8ac3 100644 --- a/lib/Backdoor_Analysis.py +++ b/lib/Backdoor_Analysis.py @@ -13,7 +13,7 @@ # 4、LD_LIBRARY_PATH后门检测 # 5、ld.so.preload后门检测 # 6、PROMPT_COMMAND后门检测 -# 7、crontab后门检测 +# 7、cron后门检测 # 8、alias后门 # 9、ssh后门 ln -sf /usr/sbin/sshd /tmp/su; /tmp/su -oPort=5555; # 10、SSH Server wrapper 后门,替换/user/sbin/sshd 为脚本文件 @@ -109,10 +109,8 @@ def check_PROMPT_COMMAND(self): try: infos = os.popen("echo $PROMPT_COMMAND").read().splitlines() for info in infos: - suspicious2, malice2 = self.analysis_strings('PROMPT_COMMAND backdoor', 'ROMPT_COMMAND', info, - '[1]echo $PROMPT_COMMAND') - if suspicious2: suspicious = True - if malice2: malice = True + suspicious, malice = self.analysis_strings('PROMPT_COMMAND backdoor', 'ROMPT_COMMAND', info, + '[1]echo $PROMPT_COMMAND') return suspicious, malice except: return suspicious, malice @@ -127,9 +125,7 @@ def check_cron(self): files = [os.path.join(cron, i) for i in os.listdir(cron) if (not os.path.isdir(os.path.join(cron, i)))] for file in files: for i in open(file, 'r'): - suspicious2, malice2 = self.analysis_strings('crontab backdoor', file, i, '[1]cat %s' % file) - if suspicious2: suspicious = True - if malice2: malice = True + suspicious, malice = self.analysis_strings('cron backdoor', file, i, '[1]cat %s' % file) return suspicious, malice except: return suspicious, malice @@ -140,9 +136,7 @@ def check_alias(self): try: infos = os.popen("alias").read().splitlines() for info in infos: - suspicious2, malice2 = self.analysis_strings('alias backdoor', "", info, '[1]alias') - if suspicious2: suspicious = True - if malice2: malice = True + suspicious, malice = self.analysis_strings('alias backdoor', "", info, '[1]alias') return suspicious, malice except: return suspicious, malice @@ -239,15 +233,17 @@ def check_startup(self): except: return suspicious, malice - # 分析一串字符串是否包含反弹shell或者存在的文件路径 + # 分析一串字符串是否包含反弹shell、获取对应字串内可能存在的文件,并判断文件是否存在恶意特征。 def analysis_strings(self, name, file, contents, solve): suspicious, malice = False, False try: content = contents.replace('\n', '') + # 反弹shell类 if check_shell(content): self.backdoor.append( {u'异常类型': name, u'文件': file, u'异常信息': content, u'类型特征': u'反弹shell类', u'手工确认': solve}) malice = True + # 境外IP操作类 elif check_contents_ip(content): self.backdoor.append( {u'异常类型': name, u'文件': file, u'异常信息': content, u'类型特征': u'境外IP信息', u'手工确认': solve}) @@ -292,7 +288,7 @@ def run(self): suspicious, malice = self.check_PROMPT_COMMAND() result_output_tag(suspicious, malice) - string_output(u' [7]crontab 后门检测') + string_output(u' [7]cron定时任务后门检测') suspicious, malice = self.check_cron() result_output_tag(suspicious, malice) @@ -320,9 +316,8 @@ def run(self): suspicious, malice = self.check_startup() result_output_tag(suspicious, malice) - #结果内容输出到文件 - result_output_file(u'后门检查异常如下:',self.backdoor) - + # 结果内容输出到文件 + result_output_file(u'后门检查异常如下:', self.backdoor) if __name__ == '__main__': diff --git a/lib/Init.py b/lib/Init.py new file mode 100644 index 0000000..8b4e7e2 --- /dev/null +++ b/lib/Init.py @@ -0,0 +1,80 @@ +# coding:utf-8 +from __future__ import print_function +from subprocess import Popen, PIPE +import os +from lib.common import * + + +# 作者:咚咚呛 +# 系统初始化检测 +# 1、文件alias配置检测 + + +class SYS_INIT: + def __init__(self): + # 异常后门列表 + self.backdoor_info = [] + + def check_alias_conf(self): + suspicious, malice = False, False + try: + files = ['/root/.bashrc', '/root/.bash_profile', '/etc/bashrc'] + + for dir in os.listdir('/home/'): + suspicious2, malice2 = self.alias_file_analysis(os.path.join('%s%s%s' % ('/home/', dir, '/.bashrc'))) + if suspicious2: suspicious = True + if malice2: malice = True + + for dir in os.listdir('/home/'): + suspicious2, malice2 = self.alias_file_analysis( + os.path.join('%s%s%s' % ('/home/', dir, '/.bash_profile'))) + if suspicious2: suspicious = True + if malice2: malice = True + + for file in files: + suspicious2, malice2 = self.alias_file_analysis(file) + if suspicious2: suspicious = True + if malice2: malice = True + + return suspicious, malice + except: + return suspicious, malice + + # 分析环境变量alias配置文件的信息 + def alias_file_analysis(self, file): + suspicious, malice = False, False + try: + # 程序需要用到的系统命令 + syscmds = ['ps', 'strings', 'netstat', 'find', 'echo', 'iptables', 'lastlog', 'who', 'ifconfig'] + if not os.path.exists(file): return suspicious, malice + with open(file) as f: + for line in f: + if line[:5] == 'alias': + for syscmd in syscmds: + if 'alias ' + syscmd + '=' in line: + self.backdoor_info.append( + {u'异常类型': u'系统重要命令被设置alias', u'异常信息': line, + u'排查参考命令': u'[1]alias [2]cat %s' % file}) + suspicious = True + return suspicious, malice + except: + return suspicious, malice + + def run(self): + print(u'\n检测系统初始化扫描') + file_write(u'\n检测系统初始化扫描\n') + + string_output(u' [1]alias检查') + suspicious, malice = self.check_alias_conf() + result_output_tag(suspicious, malice) + + # 检测结果输出到文件 + result_output_file(u'系统初始化检查:', self.backdoor_info) + + +if __name__ == '__main__': + init = SYS_INIT() + init.run() + print(u"可疑alias配置如下:") + for info in init.backdoor_info: + print(info) diff --git a/lib/Proc_Analysis.py b/lib/Proc_Analysis.py index 7b21ffa..8e46f38 100644 --- a/lib/Proc_Analysis.py +++ b/lib/Proc_Analysis.py @@ -47,19 +47,7 @@ def exe_analysis(self): def shell_analysis(self): suspicious, malice = False, False try: - p1 = Popen("ps -ef", stdout=PIPE, shell=True) - p2 = Popen("grep -v 'grep'", stdin=p1.stdout, stdout=PIPE, shell=True) - p3 = Popen("awk '{print $1\" \"$2\" \"$3\" \"$8}'", stdin=p2.stdout, stdout=PIPE, shell=True) - shell_process = p3.stdout.readlines() - # shell_process = os.popen( - # "ps -ef|grep -v 'grep'|awk '{print $1\" \"$2\" \"$3\" \"$8}'").readlines() - for pro in shell_process: - if check_shell(pro): - pro_info = pro.strip().split(' ', 3) - self.process_backdoor.append( - {u'异常类型': u'进程反弹shell特征', u'进程用户': pro_info[0], u'进程pid': pro_info[1], u'父进程ppid': pro_info[2], - u'进程cmd': pro_info[3].replace("\n", ""), u'恶意特征': u'反弹shell'}) - malice = True + return suspicious, malice except: return suspicious, malice @@ -175,7 +163,9 @@ def run(self): result_output_tag(suspicious, malice) # 检测结果输出到文件 - result_output_file(u'恶意进程如下::', self.process_backdoor) + result_output_file(u'恶意进程如下:', self.process_backdoor) + + if __name__ == '__main__': diff --git a/lib/User_Analysis.py b/lib/User_Analysis.py index d61a77a..6d35ad4 100644 --- a/lib/User_Analysis.py +++ b/lib/User_Analysis.py @@ -1,6 +1,6 @@ # coding:utf-8 from __future__ import print_function -import os, optparse, time, sys, json +import os from lib.common import * @@ -11,6 +11,7 @@ # 2、查看系统中是否存在空口令账户 # 3、查看sudoers文件权限,是否存在可直接sudo获取root的账户 # 4、查看各账户下登录公钥 +# 5、密码文件权限检测 class User_Analysis: def __init__(self): @@ -85,12 +86,33 @@ def file_analysis(self, file, user): if len(shell_process): authorized_key = ' & '.join(shell_process).replace("\n", "") self.user_malware.append({u'用户': user.replace("\n", ""), u'异常描述': u'存在免密登录的证书', - u'证书客户端名称': authorized_key}) + u'证书客户端名称': authorized_key}) suspicious = True return suspicious, malice except: return suspicious, malice + # 密码文件检测 + def passwd_file_analysis(self): + suspicious, malice = False, False + try: + files = ['/etc/passwd', '/etc/shadow'] + for file in files: + if not os.path.exists(file): continue + shell_process = os.popen("ls -l " + file + "|awk '{print $1}'").read().splitlines() + if len(shell_process) != 1: continue + if file == '/etc/passwd' and shell_process[0] != '-rw-r--r--': + self.user_malware.append( + {u'文件': file, u'异常描述': u'passwd文件权限变更,不为-rw-r--r--', u'排查参考命令': u'ls -l /etc/passwd'}) + suspicious = True + elif file == '/etc/shadow' and shell_process[0] != '----------': + self.user_malware.append( + {u'文件': file, u'异常描述': u'shadow文件权限变更,不为----------', u'排查参考命令': u'ls -l /etc/shadow'}) + suspicious = True + return suspicious, malice + except: + return suspicious, malice + def run(self): print(u'\n开始账户类安全扫描') file_write(u'\n开始账户类安全扫描\n') @@ -115,7 +137,6 @@ def run(self): result_output_file(u'可疑账户类信息如下:', self.user_malware) - if __name__ == '__main__': infos = User_Analysis() infos.run()