主機一鍵巡檢腳本--基於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

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