密码的暴力破解及自动阻断

一,项目背景;

暴露在公网云上的服务器,会存在大量的暴力破解;

解决办法:

  1. 更换端口;
  2. 买云防护,waf

暴力破解的自动阻断;

使用python中的re模块和subprocess模块

二,使用到python中的模块

1,re模块

re模块是Python中用于处理正则表达式的模块。正则表达式是一种用于匹配字符串模式的强大工具,可以用于搜索、替换和分割字符串。

re模块提供了一系列函数,可以用来对字符串进行正则表达式的操作,包括匹配、搜索、替换等功能。一些常用的函数包括:

1. re.match(pattern, string):尝试从字符串的起始位置匹配一个模式,如果匹配成功返回一个匹配对象,否则返回None。

2. re.search(pattern, string):在字符串中搜索匹配模式的第一个位置,如果匹配成功返回一个匹配对象,否则返回None。

3. re.findall(pattern, string):在字符串中搜索匹配模式的所有位置,并返回所有匹配的字符串组成的列表。

4. re.sub(pattern, repl, string):用指定的替换字符串替换字符串中所有匹配模式的子串。

5. re.split(pattern, string):根据匹配模式分割字符串,并返回分割后的子串列表。

使用re模块需要先导入re模块,例如:import re。

然后可以通过re.compile()函数编译正则表达式模式,然后使用上述函数进行字符串操作。

(1),findall() 函数

找到匹配到的所有子串,并返回一个列表,如果没有匹配到就返回空;

>>> import re
>>> s = 'hello 520'
>>> re.findall('hello',s)
['hello']
>>> re.findall('520',s)
['520']
>>> re.findall('l',s)
['l', 'l']

(2),search() 函数

扫描整个字符串,并且返回第一个,如果没有成功匹配就返回空;

>>> re.search('hello',s)
<re.Match object; span=(0, 5), match='hello'>
>>> m = re.search('hello',s)
>>> m.group()
'hello'
>>> m.span()
(0, 5)
>>> n = re.search('l',s)
>>> n.group()
'l'

(3),匹配元字符

\d            匹配所有数字0-9
\D            匹配非数字
\w            匹配所有单词字符,包括大小写 数字 下划线 中文
\W            匹配剩下的,空格 换行符 特殊字符

(4),匹配字符集

字符的集合,用[]表示
字符集内用“^”表示“非”
\d=[0-9]
\D=[^0-9]
\w!=[a-zA-Z_0-9] 还有中文

(5),匹配标定的字符数量

{}内部表示长度

import re
s = 'https www baidu com'
re.findall('[a-z]{3}',s)
['htt', 'www', 'bai', 'com']

2,subprocess模块

需求:执行命令并且将输出劫持实现日志的监控;

用于启动新的进程的模块,它可以用于执行外部命令,获取进程的输出,多进程的协同;

多进程协同在python中有三种方式:

  • os.system函数;阻塞式
  • multiprocessing模块;密集型的计算
  • subprocess模块

subprocess模块是Python中用于创建和管理子进程的模块。通过subprocess模块,可以在Python程序中启动新的进程,与新的进程进行交互,并获取新进程的输出。

subprocess模块提供了多个函数,用于执行外部命令,例如:

(1),subprocess.Popen

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)

启动一个新的进程,并返回一个Popen对象,可以通过该对象与新进程进行交互。

(2),subprocess.run

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False)

运行指定的命令,等待命令完成,并返回一个CompletedProcess对象。

(3),subprocess.check_output

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

运行指定的命令,并返回命令的输出结果。

(4),subprocess.call

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

运行指定的命令,等待命令完成,并返回命令的返回值。

使用subprocess模块可以执行系统命令、调用外部程序,并获取输出结果。需要注意的是,在执行外部命令时,应该谨慎处理输入参数,以防止命令注入等安全问题。

三,Linux的日志

1,常见日志的目录

  1. /var/log------日志任务
  2. /var/log/cron------记录系统定时任务
  3. /var/log/cups------打印信息的日志
  4. /var/log/message------记录系统重要信息的日志
  5. /var/log/btmp------登录失败
  6. /var/log/lastlog------最后一次登录
  7. /var/log/wtmp------登录成功的日志
  8. /var/log/secure------登录日志
  9. /var/log/utmp------目前登录用户的信息
  10. /etc/hosts.deny------hosts黑名单
  11. /etc/hosts.allow------hosts白名单

2,日志分析

常用到的Linux命令;

  1. find
  2. grep
  3. awk
  4. sed
  5. cat
  6. tail
  7. head

3,黑白名单的设置

/etc/hosts.deny------hosts黑名单

/etc/hosts.allow------hosts白名单

配置的格式:

服务:地址:允许/封禁

服务:ssh,ftp,telnet,http,https

如:all:192.168.xxx.xxx:deny   全部封禁

       all:192.168.xxx.xxx:allow   白名单

地址:

192.168.1.10

192.168.1.10/24 或者 192.168.1.*   封掉整个C段

四,逻辑结构

实现暴力破解的自动阻断;

步骤:

  • 第一步:打开安全日志;
  • 第二步:对安全日志进行实时的监控;
  • 第三步:解析日志的内容,找出正在爆破的IP;
  • 第四步:设置一个阀值,超过阀值之后直接对IP进行封禁;

五,项目实现

源代码:

import re
import subprocess
import time

# 打开安全日志
logFile = '/var/log/secure'
# 设置黑名单
hostDeny = '/etc/hosts.deny'

# 封禁阀值
password_wrong_num = 5

# 获取已经加入黑名单的IP,转换为字典
def getDenies():
    deniedDict = {}
    list = open(hostDeny).readlines()
    for ip in list:
        group = re.search(r'(\d+\.\d+\.\d+\.\d+)',ip)
        if group:
            deniedDict[group[1]] = '1'
    return deniedDict

# 监控方法
def monitorLog(Logfile):
    # 统计错误的次数
    tempIP = {}
    # 已经拉黑的IP
    deniedDict = getDenies()
    # 读取安全日志
    popen = subprocess.Popen('tail -f'+logFile,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
    # 开始监控
    while True:
        time.sleep(0.1)
        line = popen.stdout.readline().strip()
        if line:
            group = re.search('Invalid user \w+ from (\d+\.\d+\.\d+\.\d+)',str(line))
            # 用户不存在直接封
            if group and not deniedDict.get(group[1]):
                subprocess.getoutput('echo \'sshd:{} >> {}'.format(group[1]),hostDeny)
                deniedDict[group[1]] = '1'
                time_str = time.strftime('%Y-%m-%d %H:%M:%s',time.localtime(time.time()))
                print('{} ---add ip :{} to hosts.deny for invalid user'.format(time_str,group[1]))
                continue

            # 用户名存在,密码错误
            group = re.search('Failed password for \w+ from(\d+\.\d+\.\d+\.\d+)',str(line))
            if group:
                ip = group[1]
                # 统计IP错误的次数
                if not tempIP.get(ip):
                    tempIP[ip] = 1
                else:
                    tempIP[ip] = tempIP[ip]+1

                # 如果错误次数大于阀值的时候,直接封禁
                if tempIP[ip] > password_wrong_num and not deniedDict.get(ip):
                    del tempIP[ip]
                    subprocess.getoutput('echo \'sshd:{} >> {}'.format(ip,hostDeny))
                    deniedDict[ip] = '1'
                    time_str = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
                    print('{}---add ip :{} to hosts.deny for invalid password'.format(time_str,ip))


if __name__ == '__main__':
    monitorLog(logFile)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

慕舟舟.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值