等保主机一键巡检--linux系统【保姆级带你瞎写点东西,再吐槽吐槽】

#先说好,这玩意要是能做到全覆盖全兼容,咱们等保就没活干了,根据实际情况选择合适的方法次啊是上乘啊啊啊啊啊。这个文章是记录脚本撰写过程。脚本采用python语言完成。

首先,对于我的脚本,我要设计一个酷炫的开头页面。我要打印一个酷炫的字符,就像那些酷炫的脚本一样。就叫NCC哈哈哈,没有啥意义,咱也要有自己的b格。看我画的还不错把~ ^_^

banner = r"""
======================================================================
    ____  ==  ___  ==  ==     ______   =====    _______     ======
   /    \    /  / ====    ` _____ /  ==      ` _____ /   ===========
  /  /\  \  /  / == ==  /  /     ======    /  /         ==========
 /  /  \  \/  / ====== |  |     == =====  |  |         =========
/  /    \    /  =====  \   `-____  ====   \   `-____   Author:NCC
`_/      `__/    ===    `-_____ /   ===    `-_____ /   data:2024-9-19
=====================================================================
"""
print(banner)

然后我们先把系统框架搭建出来,提示是否一键执行巡检,做一个小的操作台出来。既然是一键巡检,这里需要将问你要一下主机的账号和密码,有些操作需要超级权限才能做,这里看着权限脚本会自动给。

这里输入密码感觉需要将它匿名起来,然后要求输入两次核对一下密码感觉会好一点。可以参考下文章:[145]python实现控制台密码星号输入_python input 显示 *号-CSDN博客

可以采用getpass进行,但是再使用pycharm需要设置一下”在输出控制台中模拟终端“。解决pycharm不支持getpass.getpass及类似需要输入但不支持的问题_python getpass.getpass没反应-CSDN博客

新版的pycharm要找一下这个设置,和旧版的有点不一样。

这部分代码为:

def login():
    print("请输入您主机的用户名和密码\n"'\033[91m' + "!!仅用于系统检测!!" + '\033[0m')
    login_name = input('\033[92m' + "请输入用户名(无则直接回车,下同):" + '\033[0m')
    login_pwd1 = getpass.getpass('\033[92m'"请输入密码:" + '\033[0m')
    login_pwd2 = getpass.getpass('\033[92m'"请再输入一次密码:" + '\033[0m')
    while login_pwd1 != login_pwd2:
        print("刚刚两次输入的密码不相同哦")
        login_pwd1 = getpass.getpass('\033[92m'"请输入密码:" + '\033[0m')
        login_pwd2 = getpass.getpass('\033[92m'"请再输入一次密码:" + '\033[0m')
    return login_name, login_pwd1

现在可以开始写一些测试的函数了,首先等保的第一项就是对身份进行验证。这部分需要掌握re库的使用,需要查看一些配置然后匹配嘛。需要学习re的可以去看看下面这个佬的文章。python——正则表达式(re模块)详解_python re正则-CSDN博客

回到我们等保,我们需要关注的点是主机的身份鉴别配置。比方说在这里的一项要求是:应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换。

测评要求就需要我们查看身份是否有重复的,密码是否是简单甚至是空口令。以及是否系统采用了一些身份鉴别策略。

一般会使用命令来查看登陆用户的一些信息,比如说查看影子文件,在这里你可以看到以下几个字段。

用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段

Linux /etc/shadow(影子文件)内容详解_etc shadow-CSDN博客

命令:

cat /etc/shadow

这里我们能够看到用户名,以及加密后的密钥,以及他的一些账号设置。图片上面可以看到只有第一行的root当中没有*或者!的符号,其他的那些实际上是系统用户,那么他们的密码是锁定的,例如,bin用户的密码字段显示为*,表示这个账户可能被锁定,无法登录。

根据以上特点,于是我们编写如下脚本对代码进行处理:
 

    account_list = []
    cmd = os.popen("echo %s | sudo -S cat /etc/shadow"%(psd)).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 = '存在的账户:{0}\n空口令用户:{1}\n'.format(account_list, anonymous_account)

然后对于这里的密码弱口令问题,这里保存的密码是单向不可逆的。目前 Linux 的密码采用的是 SHA512 散列加密算法,原来采用的是 MD5 或 DES 加密算法。SHA512 散列加密算法的加密等级更高,也更加安全。在 CentOS 7 中,密码部分采用SHA-512 加密算法进行加密。CentOS 7.6 下如何查看当前用户密码的加密算法是什么?_如何查看centos是否采用sha512校验-CSDN博客

那么我们这里写一个简单口令匹配,将常用弱口令明文转换成加密密文,然后附带在脚本文件的环境目录当中。常见的弱口令字典1000~一石三鸟-CSDN博客这样就可以快速匹配了。

python中采用的加密模块是hashlib:Python hashlib库解析:数据安全加密必备指南 - 知乎 (zhihu.com)

写一个脚本转换如下:

import hashlib

# 用于存储加密后的内容
encrypted_contents = []

with open('弱口令-明文.txt', 'r') as file:
    line = file.readline()
    while line:
        # 去除行末的换行符
        clean_line = line.strip()
        # 计算 SHA-256 哈希值
        sha256_hash = hashlib.sha256(clean_line.encode()).hexdigest()
        # 将加密后的内容添加到列表中
        encrypted_contents.append(sha256_hash + '\n')
        line = file.readline()

# 将加密后的内容写入新文件
with open('encrypted.txt', 'w') as output_file:
    output_file.writelines(encrypted_contents)

转换后的密文截图如下:

到这然后我们写一个自动匹配算法,就可以啦!?

真的就可以了么?

少年,要是你聪明认真的话,你应该知道咱们的sha512是有加盐的步骤的

深入解析Linux系统中/etc/shadow文件密码的加密方式 (baidu.com)

然后你也会发现你看你影子文件的几个密文,他长短可能还不一样,可能还不是512位的。在下面的博文中或许你会找到答案。

Linux shadow文件中密码的加密方式 - gxy* - 博客园 (cnblogs.com)

(上面的博主的研究思路和求知精神令我崇拜,真的是大佬呜呜呜

所以嘛哈哈,对于自动化弱口令这里开一个坑嘻嘻,我先完成全部脚本。我得好好学学linux那本书了 开始发癫

那么回到我们脚本制作,对于用户身份信息还需要考虑是否具有登录失败处理功能,应配置并启用结束会话、限制非法登录次数和当登录连接超时自动退出等相关措施;

这个可以查看策略文件:

cat /etc/pam.d/system-auth

这里写一个简单的匹配:在两个文件当中查找下是否有匹配的字段。

import os

def check_parameters():
    system_auth_command = "cat /etc/pam.d/system-auth"
    profile_command = "cat /etc/profile"
    system_auth_output = os.popen(system_auth_command).read()
    profile_output = os.popen(profile_command).read()
    system_auth_pattern = "auth required pam_tally2.so onerr=fail deny=[0-9]+ unlock_time=[0-9]+ even_deny_root root_unlock_time=[0-9]+"
    profile_pattern = "export TMOUT=[0-9]+"
    system_auth_match = False
    profile_match = False
    if system_auth_pattern in system_auth_output:
        system_auth_match = True
    if profile_pattern in profile_output:
        profile_match = True
    return system_auth_match, profile_match

后面是查询一下主机在远程链接的时候有没有开启一些加密服务,比方说有如下步骤:

访谈系统管理员,进行远程管理的方式。
1)以root身份登录进入Linux查看是否运行了sshd服务,service - status-all | grep sshd
查看相关的端口是否打开,netstat -an|grep 22
若未使用SSH方式进行远程管理,则查看是否使用了Telnet 方式进行远程管理
service - -status-all|grep running, 查看是否存在Telnet服务
2)可使用wireshark等抓包工具,查看协议是否为加密
3)本地化管理,N/A

2、3步骤需要使用工具,这里先写1的查询脚本。

这个地方可以直接查看使用命令:systemctl status sshd.service 查看服务状态,下面的就算是开启了

def check_remote_access():
    # 检查 SSHD 服务是否运行
    sshd_status = os.popen("systemctl status sshd.service").read()
    sshd_running = "Active: active (running)" in sshd_status
    # 检查 SSH 端口(22)是否打开
    port_status = os.popen("netstat -an|grep 22").read()
    port_open = len(port_status) > 0
    # 检查 Telnet 服务是否运行
    telnet_status = os.popen("service --status-all|grep running").read()
    telnet_running = "telnet" in telnet_status
    return sshd_running, port_open, telnet_running

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亚里士多没有德775

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值