主机一键巡检脚本--基于python实现

linux版本

# -*- coding:utf-8 -*- -
import os
import re

banner = """\033[1;34m
 __   __  _____   _   _  __     __  _____ 
 \ \ / / |_   _| | \ | | \ \   / / |_   _|
  \ V /    | |   |  \| |  \ \_/ /    | |  
   > <     | |   | . ` |   \   /     | |  
  / . \   _| |_  | |\  |    | |     _| |_ 
 /_/ \_\ |_____| |_| \_|    |_|    |_____|
                                                                       
    linux自动化巡检工具                             Version:1.0
    Company:xxx有限公司                Author:dqq\033[0m
"""
print(banner)
def get_cpu():  # 检查cpu
    global last_worktime, last_idletime
    f = open("/proc/stat", "r")
    line = ""
    while not "cpu " in line: line = f.readline()
    f.close()
    spl = line.split(" ")
    worktime = int(spl[2]) + int(spl[3]) + int(spl[4])
    idletime = int(spl[5])
    dworktime = (worktime - last_worktime)
    didletime = (idletime - last_idletime)
    rate = float(dworktime) / (didletime + dworktime)
    last_worktime = worktime
    last_idletime = idletime
    if (last_worktime == 0): return 0
    return rate


def get_mem_usage_percent():  # 检查内存
    try:
        f = open('/proc/meminfo', 'r')
        for line in f:
            if line.startswith('MemTotal:'):
                mem_total = int(line.split()[1])
            elif line.startswith('MemFree:'):
                mem_free = int(line.split()[1])
            elif line.startswith('Buffers:'):
                mem_buffer = int(line.split()[1])
            elif line.startswith('Cached:'):
                mem_cache = int(line.split()[1])
            elif line.startswith('SwapTotal:'):
                vmem_total = int(line.split()[1])
            elif line.startswith('SwapFree:'):
                vmem_free = int(line.split()[1])
            else:
                continue
        f.close()
    except:
        return None
    physical_percent = usage_percent(mem_total - (mem_free + mem_buffer + mem_cache), mem_total)
    virtual_percent = 0
    if vmem_total > 0:
        virtual_percent = usage_percent((vmem_total - vmem_free), vmem_total)
    return physical_percent, virtual_percent


def usage_percent(use, total):  # 百分比
    try:
        ret = (float(use) / total) * 100
    except ZeroDivisionError:
        raise Exception("ERROR - zero division error")
    return ret

def ostype():#判断系统类型和版本
    a=os.popen("lsb_release -a").read()
    b=os.popen("cat /etc/redhat-release").read()
    os_info=a+b
    sysnum = int(re.findall(r' (\d+?)\.', os_info, re.S)[0])#取出版本号
    system=''
    try:
        system=re.search('CentOS', os_info).group()
    except:
        pass
    try:
        system=re.search('Ubuntu', os_info).group()
    except:
        pass
    try:
        system=re.search('openSUSE', os_info).group()
    except:
        pass
    try:
        system=re.search('Red Hat', os_info).group()
    except:
        pass
    try:
        system=re.search('Debian', os_info).group()
    except:
        pass
    return system,sysnum

def account_check():#检查账户情况
    account_list = []
    cmd = os.popen("cat /etc/shadow").read()
    user_list = re.split(r'\n', cmd)
    for i in user_list:
        try:
            c = re.search(r'\*|!', i).group()
        except:
            try:
                ok_user = re.findall(r'(.+?):', i)[0]
                account_list.append(ok_user)
            except:
                pass
    anonymous_account = os.popen("awk -F: 'length($2)==0 {print $1}' /etc/shadow").read()
    account = '存在的账户:\n{0}\n空口令用户:\n{1}\n'.format(account_list, anonymous_account)
    return account

def process():#列出在当前环境中运行的进程,不包含环境信息

    process =os.popen("ps -ef").read()
    return process

def service(system,sysnum):#列出开启的服务
    service=''
    if system=='Ubuntu' or system=='Debian':
        service=os.popen("service --status-all | grep +").read()
    elif system=='openSUSE':
        service = os.popen("service --status-all | grep running").read()
    elif system=='CentOS' or system=='Red Hat':
        if sysnum<7:
            service1 = os.popen("chkconfig --list |grep 2:启用").read()
            service2 = os.popen("chkconfig --list |grep 2:on").read()
            service=service1+'\n'+service2
        else:
            service = os.popen("systemctl list-units --type=service --all |grep running").read()
    return service

def startup(system,sysnum):#列出启动项
    startup=''
    if system=='CentOS' or system=='Red Hat':
        if sysnum<7:
            startup=os.popen("cat /etc/rc.d/rc.local").read()
        else:
            startup = os.popen("systemctl list-unit-files | grep enabled").read()
    elif system=='Ubuntu' or system=='Debian':
        if sysnum < 14:
            startup1 = os.popen("chkconfig |grep on").read()
            startup2 = os.popen("chkconfig |grep 启用").read()
            startup = startup1+startup2
        else:
            startup = os.popen("systemctl list-unit-files | grep enabled").read()
    elif system == 'openSUSE':
        startup1 = os.popen("chkconfig |grep on").read()
        startup2 = os.popen("chkconfig |grep 启用").read()
        startup = startup1 + startup2
    return startup

def timingtask():#列出定时任务
    timingtask = []
    cmd = os.popen("cat /etc/shadow").read()
    user_list = re.split(r'\n', cmd)
    for i in user_list:
        try:
            c = re.search(r'\*|!', i).group()
        except:
            try:
                ok_user = re.findall(r'(.+?):', i)[0]
                task = os.popen("crontab -l -u " + ok_user).read()
                timingtask.append(task)
            except:
                pass
    return timingtask

def seclog_time():#登录日志存留时间
    cmd = os.popen("cat /etc/logrotate.conf").read()
    try:
        seclog=''
        cycle = re.findall(r'# rotate log files weekly\n(.+?)\n', cmd, re.S)[0]  # 周期
        num = re.findall(r'\d+', str(re.findall(r'# keep 4 weeks worth of backlogs\n(.+?)\n', cmd, re.S)))[0]  # 次数
        print('轮转周期:{0}\n轮转次数:{1}'.format(cycle,num))
        if cycle == 'weekly':
            if int(num) < 26:
                seclog = '日志存留不足180天'
            else:
                seclog = '日志存留时间符合要求'
        elif cycle == 'monthly':
            if int(num) < 6:
                seclog = '日志存留不足180天'
            else:
                seclog = '日志存留时间符合要求'
        elif cycle == 'quarterly':
            if int(num) < 2:
                seclog = '日志存留不足180天'
            else:
                seclog = '日志存留时间符合要求'
        return seclog
    except:
        seclog = '日志轮转配置读取出错'
        return seclog



def seclog_login(system):#登录ip记录
    succeed=failed=''
    if system=='CentOS' or system=='Red Hat':
        succeed='\n成功登录:\n'+os.popen("cat /var/log/secure*|awk '/Accepted/{print $(NF-3)}'|sort|uniq -c|awk '{print $2\"|次数=\"$1;}'").read()
        failed='\n失败登录:\n'+os.popen("cat /var/log/secure*|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $2\"|次数=\"$1;}'").read()
    elif system=='Ubuntu' or system=='Debian':
        succeed = os.popen(
            "cat /var/log/auth.log|awk '/Accepted/{print $(NF-3)}'|sort|uniq -c|awk '{print $2\"|次数=\"$1;}'").read()
        failed = os.popen(
            "cat /var/log/auth.log|awk '/authentication failure/{print $(NF-1)}'|sort|uniq -c|awk '{print $2\"|次数=\"$1;}'").read()
        succeed='\n成功登录:\n'+re.sub("rhost=\|次数=\d|ruser=\|次数=\d|rhost=","",succeed)
        failed = '\n失败登录:\n'+re.sub("rhost=\|次数=\d|ruser=\|次数=\d|rhost=", "", failed)
    elif system == 'openSUSE':
        succeed = '\n成功登录:\n'+os.popen(
            "cat /var/log/messages|awk '/Accepted/{print $(NF-3)}'|sort|uniq -c|awk '{print $2\"|次数=\"$1;}'").read()
        failed = '\n失败登录:\n'+os.popen(
            "cat /var/log/messages|awk '/failure/{print $(NF)}'|sort|uniq -c|awk '{print $2\"|次数=\"$1;}'").read()
    return succeed,failed

def firewall(system,sysnum):#查看防火墙状态
    firewall=''
    if system=='CentOS' or system=='Red Hat':
        if sysnum<7:
            firewall=os.popen("service iptables status").read()
        else:
            firewall = os.popen("systemctl status firewalld").read()
    elif system == 'Ubuntu' or system == 'Debian':
        firewall = os.popen("ufw status").read()
    elif system == 'openSUSE':
        firewall = os.popen("chkconfig -list | grep fire").read()
    return firewall

######以上为函数部分#####
if os.popen("whoami").read()!='root\n':
    print('请在root用户权限下运行...')
    exit()
last_worktime=0
last_idletime=0
statvfs = os.statvfs('/')
total_disk_space = statvfs.f_frsize * statvfs.f_blocks
free_disk_space = statvfs.f_frsize * statvfs.f_bfree
disk_usage = (total_disk_space - free_disk_space) * 100.0 / total_disk_space
disk_usage = int(disk_usage)
disk_tip = "硬盘空间使用率:"+str(disk_usage)+"%"
mem_usage = get_mem_usage_percent()
mem_usage = int(mem_usage[0])
mem_tip = "物理内存使用率:"+str(mem_usage)+"%"
cpu_usage = int(get_cpu()*100)
cpu_tip = "CPU使用率:"+str(cpu_usage)+"%"
load_average = os.getloadavg()
load_tip = "系统负载:"+str(load_average)+'\n判断:系统负载中三个数值中有一个超过3就是高'
system=ostype()[0]
sysnum=ostype()[1]
print('【系统状态】')
print(disk_tip)
print(mem_tip)
print(cpu_tip)
print(load_tip)
print('\n【账户情况】')
print(account_check())
print('【运行的进程】\n')
print(process())
print('\n【开启的服务】\n')
print(service(system,sysnum))
print('\n【启动项】\n')
print(startup(system,sysnum))
print('\n【定时任务】\n')
for timingtask in timingtask():
    print(timingtask)
print('\n【登录日志】\n')
print('日志存留时间:')
print(seclog_time())
print(seclog_login(system)[0])
print(seclog_login(system)[1])
print('\n【防火墙状态】:\n')
print(firewall(system,sysnum))

window版本

# company:宁波壹安科技
# author:说书人

import os
import re
import psutil

banner = """\033
 __   __  _____   _   _  __     __  _____ 
 \ \ / / |_   _| | \ | | \ \   / / |_   _|
  \ V /    | |   |  \| |  \ \_/ /    | |  
   > <     | |   | . ` |   \   /     | |  
  / . \   _| |_  | |\  |    | |     _| |_ 
 /_/ \_\ |_____| |_| \_|    |_|    |_____|
                                                                       
    windows自动化巡检工具                             Version:1.0
    Company:xx科技有限公司                Author:dqq\033
"""
print(banner)
def cpu():  # cpu使用率
    print('获取CPU信息...')
    cpu = 'CPU使用率:{}{}\n'.format(str(psutil.cpu_percent(1)), '%')
    return cpu


def mem():  # 内存使用率
    print('获取内存信息...')
    mem = '内存使用率:{}{}\n'.format(str(psutil.virtual_memory()[2]), '%')
    return mem


def disk():  # 磁盘使用率
    print('获取磁盘信息...')
    disk = '磁盘使用率:{}{}'.format(psutil.disk_usage('/')[3], '%')
    return disk


def account():  # 本地账户检查
    print('检查本地账户情况...')
    try:
        admin_info = os.popen('net localgroup administrators').read()
        administrators = re.findall(r'-\n(.+?)命令成功完成', admin_info, re.S)[0]  # 管理组
        users_info = os.popen('net localgroup users').read()
        users = re.findall(r'-\n(.+?)命令成功完成', users_info, re.S)[0]  # 用户组
        guest_info = os.popen('net user guest').read()
        guest = re.findall(r'帐户启用(.+?)帐户到期', guest_info, re.S)[0].replace(' ', '').replace('\n', '')  # guest账户是否禁止
        if guest == 'No':
            guest_able = 'guest账户已禁用'
        elif guest == 'Yes':
            guest_able = '注意,guest账户未禁用!'
        account = '管理组:\n{}\n用户组:\n{}\n{}'.format(administrators, users, guest_able)
        return account
    except:
        print('无法获取本地账户信息')


def tasklist():  # 获取进程列表
    print('获取进程列表...')
    try:
        tasklist = os.popen('tasklist').read()
        return tasklist
    except:
        print('无法获取进程列表信息')


def service():  # 获取已启用的服务
    print('获取服务列表...')
    try:
        service = os.popen('net start').read()
        return service
    except:
        print('无法获取服务列表信息')


def schtasks():  # 获取计划任务
    print('获取计划任务...')
    try:
        schtasks_info = os.popen('schtasks.exe').read()
        schtasks = re.findall(r'\n(.+?)文件夹:', schtasks_info, re.S)[0]
        return schtasks
    except:
        print('无法获取计划任务信息')


def firewall():  # 获取防火墙信息
    print('获取防火墙信息...')
    try:
        firewall_info = os.popen('netsh firewall show state').read()
        firewall = re.findall(r'\n(.+?)重要信息', firewall_info, re.S)[0]
        return firewall
    except:
        print('无法获取防火墙信息')


def CVEcheck():  # 检查补丁情况
    print('检查补丁情况...')
    try:
        systeminfo = os.popen('systeminfo').read()
        if re.search('Server 2003', systeminfo) != None:
            system = 'win2k3'
        elif re.search('XP', systeminfo) != None:
            system = 'winxp'
        elif re.search('Server 2008 R2', systeminfo) != None:
            system = 'win2k8r2'
        elif re.search('Server 2008', systeminfo) != None:
            system = 'win2k8'
        elif re.search('Server 2012 R2', systeminfo) != None:
            system = 'win2k12r2'
        elif re.search('Server 2012', systeminfo) != None:
            system = 'win2k12'
        elif re.search('Server 2019', systeminfo) != None:
            system = 'win2k19'
        else:
            print('识别错误或是其他OS')
            return '识别错误或是其他OS'
        patch_num = os.popen(
            'systeminfo | findstr "KB4012598 KB4012212 KB4012213 KB4500331 KB4499180 KB4499175 KB4512486 KB4512482 KB4512489 KB4511553"').read()
        # 开始检查MS17-010补丁情况
        MS17010 = 'ok'
        if system == 'win2k3' or system == 'winxp' or system == 'win2k8':
            if re.search('KB4012598', patch_num) == None:
                MS17010 = 'MS17-010'
        if system == 'win2k8r2':
            if re.search('kb4012212', patch_num) == None:
                MS17010 = 'MS17-010'
        if system == 'win2k12r2':
            if re.search('kb4012213', patch_num) == None:
                MS17010 = 'MS17-010'

        # 开始检查CVE-2019-0708补丁情况
        CVE20190708 = 'ok'
        if system == 'win2k3' or system == 'winxp':
            if re.search('kb4500331', patch_num) == None:
                CVE20190708 = 'CVE-2019-0708'
        if system == 'win2k8':
            if re.search('kb4499180', patch_num) == None:
                CVE20190708 = 'CVE-2019-0708'
        if system == 'win2k8r2':
            if re.search('kb4499175', patch_num) == None:
                CVE20190708 = 'CVE-2019-0708'

        # 开始检查CVE-2019-1181补丁情况
        CVE20191181 = 'ok'
        if system == 'win2k8r2':
            if re.search('kb4512486', patch_num) == None:
                CVE20191181 = 'CVE-2019-1181'
        if system == 'win2k12':
            if re.search('kb4512482', patch_num) == None:
                CVE20191181 = 'CVE-2019-1181'
        if system == 'win2k12r2':
            if re.search('kb4512489', patch_num) == None:
                CVE20191181 = 'CVE-2019-1181'
        if system == 'win2k19':
            if re.search('kb4511553', patch_num) == None:
                CVE20191181 = 'CVE-2019-1181'

        ispatch =[]
        if MS17010 == CVE20190708 == CVE20191181 == 'ok':
            ispatch.append('检测补丁均存在!')
        if MS17010 == 'MS17-010':
            ispatch.append('MS17-010、')
        if CVE20190708 == 'CVE-2019-0708':
            ispatch.append('CVE-2019-0708、')
        if CVE20191181 == 'CVE-2019-1181':
            ispatch.append('CVE-2019-1181、')
        return ispatch
    except:
        print('无法获取补丁信息')


def eventANDstartup():  # 打开系统日志页面和启动项页面,然后手动查看
    print('为您打开系统日志页面和启动项页面,请手动查看')
    try:
        os.popen('eventvwr')  # 打开日志页面
        os.popen('msconfig')  # 打开启动项页面
    except:
        print('这种情况可能是被杀毒软件啥的拦截了')


cpu = cpu()
mem = mem()
disk = disk()
account = account()
tasklist = tasklist()
service = service()
schtasks = schtasks()
firewall = firewall()
CVEcheck = CVEcheck()
try:
    report = '----------------\n【基础信息】:\n{}{}{}\n----------------\n【账号信息】:\n{}\n----------------\n【防火墙信息】:\n{}\n----------------\n【补丁情况】:\n{}\n----------------\n【进程列表】:\n{}\n----------------\n【服务列表】:\n{}\n----------------\n【计划任务】:\n{}'.format(cpu,mem,disk,account,firewall,CVEcheck,tasklist,service,schtasks)
    with open("主机巡查报告.txt", "a") as f:
        f.write(report)
    print('报告已生成完毕!')
except:
    print('注意查看waf杀软等是否拦截本程序')
eventANDstartup()

参考链接:https://github.com/heikanet/linux_auto_xunjian

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章