吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1943|回复: 26
收起左侧

[Python 原创] 使用python让你的远程桌面更安全【防火墙自动拉黑多次远程登录失败的ip】

[复制链接]
Light紫星 发表于 2024-10-10 14:25
朋友最近申请了公网ip,但是发现被人频繁尝试登录,于是我想起来之前另一个朋友弄过自动拉黑ip的,问了他一下是通过python和计划任务的触发器实现的,于是请教gpt,写了个脚本实现了相关操作

代码如下,实现的效果就是在几分钟内尝试登录多少次,就会自动封禁ip,24小时后解除(这个解除是触发器触发的时候进行检测的,所以只有下次登录的时候触发一下才能解除)

然后搜索 计划任务程序
创建一个计划任务,
在触发器里可以手动编辑xml,输入如下内容,可以根据你自己的需求来定义,
然后安装python,在操作里面选择启动程序,启动python如C:\Python39\python.exe ,添加参数如 D:\zixing\safe\secwall.py ,起始于如 D:\zixing\safe
其他配置根据你的需求来,然后就可以测试一下远程连接失败N次后是否会被防火墙屏蔽(当然前提是开了防火墙才可以)

[Asm] 纯文本查看 复制代码
<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">*[System[(Level=1  or Level=2 or Level=3 or Level=4 or Level=0 or Level=5) and (EventID=4625)]]</Select>
  </Query>
</QueryList>




[Python] 纯文本查看 复制代码
import subprocess
import re
from datetime import datetime, timedelta
import json
import os

LOG_FILE = "ip_attempts.json"
BLOCK_RULES_FILE = "blocked_ips.json"
MAX_ATTEMPTS = 3
TIME_WINDOW_MINUTES = 3


def load_json(file):
    if os.path.exists(file):
        with open(file, "r") as f:
            return json.load(f)
    return {}


def save_json(data, file):
    with open(file, "w") as f:
        json.dump(data, f)


def get_failed_login_events():
    command = 'wevtutil qe Security "/q:*[System[EventID=4625]]" /rd:true /f:text'
    try:
        output = subprocess.check_output(command, shell=True).decode(
            "gbk", errors="ignore"
        )
    except subprocess.CalledProcessError as e:
        print(f"Error reading event log: {e}")
        return []

    return output.split("\n\n")


def parse_event(event):
    ip_pattern = re.compile(r"源网络地址:\s+(?P<ip>\d+\.\d+\.\d+\.\d+)")
    time_pattern = re.compile(r"Date:\s+(?P<datetime>[\d\-T:.]+)\d*Z")

    ip_match = ip_pattern.search(event)
    time_match = time_pattern.search(event)

    if ip_match and time_match:
        ip = ip_match.group("ip")
        event_time = time_match.group("datetime")
        event_time = event_time[:23]  # 截取前23个字符(YYYY-MM-DDTHH:MM:SS.sss)
        event_time = datetime.fromisoformat(event_time)
        return ip, event_time
    return None, None


def block_ip(ip, blocked_ips):
    rule_name = f"Block {ip} for 24 hours"
    command = f'netsh advfirewall firewall add rule name="{rule_name}" dir=in action=block remoteip={ip} enable=yes'
    try:
        subprocess.check_call(command, shell=True)
        expire_time = (datetime.now() + timedelta(hours=24)).isoformat()
        blocked_ips[ip] = expire_time
        print(f"IP {ip} 被阻止到 {expire_time}")
    except subprocess.CalledProcessError as e:
        print(f"Error blocking IP {ip}: {e}")


def remove_expired_blocks(blocked_ips):
    now = datetime.now()
    for ip, expire_time in list(blocked_ips.items()):
        if datetime.fromisoformat(expire_time) <= now:
            rule_name = f"Block {ip} for 24 hours"
            command = f'netsh advfirewall firewall delete rule name="{rule_name}"'
            try:
                subprocess.check_call(command, shell=True)
                print(f"IP {ip} 的阻止已移除")
                del blocked_ips[ip]
            except subprocess.CalledProcessError as e:
                print(f"Error removing block for IP {ip}: {e}")


def remove_old_attempts(ip_attempts):
    now = datetime.now()
    cutoff_time = now - timedelta(minutes=TIME_WINDOW_MINUTES)

    for ip in list(ip_attempts.keys()):
        ip_attempts[ip] = [
            ts for ts in ip_attempts[ip] if datetime.fromisoformat(ts) > cutoff_time
        ]
        if not ip_attempts[ip]:
            del ip_attempts[ip]


def main():
    ip_attempts = load_json(LOG_FILE)
    blocked_ips = load_json(BLOCK_RULES_FILE)
    events = get_failed_login_events()

    for event in events:
        ip, event_time = parse_event(event)
        if ip and event_time:
            if ip not in ip_attempts:
                ip_attempts[ip] = []
            if(event_time.isoformat() not in ip_attempts[ip]):
                ip_attempts[ip].append(event_time.isoformat())

    remove_old_attempts(ip_attempts)
    remove_expired_blocks(blocked_ips)

    to_block = []
    for ip, attempts in ip_attempts.items():
        if len(attempts) >= MAX_ATTEMPTS:
            to_block.append(ip)
        else:
            print(f"IP {ip} 尝试次数: {len(attempts)}")

    for ip in to_block:
        if ip not in blocked_ips:
            block_ip(ip, blocked_ips)
        del ip_attempts[ip]

    save_json(ip_attempts, LOG_FILE)
    save_json(blocked_ips, BLOCK_RULES_FILE)


if __name__ == "__main__":
    main()



secwall.zip (1.49 KB, 下载次数: 30)

免费评分

参与人数 9威望 +1 吾爱币 +19 热心值 +9 收起 理由
junjia215 + 1 + 1 用心讨论,共获提升!
苏紫方璇 + 1 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
闲人来人间 + 1 + 1 我很赞同!
疯轻云淡1986 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
shaosir2024 + 1 + 1 谢谢@Thanks!
zunmx + 1 + 1 我很赞同!
笔墨纸砚 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
GMCN + 1 + 1 很强,mark一下
helian147 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

zunmx 发表于 2024-10-10 14:36
实际上也是通过读取windows日志的,我以前写过一个类似的脚本,只是没有添加防火墙,部分代码附上。
[Python] 纯文本查看 复制代码
import win32evtlog
import win32evtlogutil
import re

mapping = {4648: "试图使用显式凭据登录。", 4624: "已成功登录帐户。", 4625: "帐户登录失败。"}


def extract_info(msg, event_time, eventid):
    ip_pattern = r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b'
    ips = re.findall(ip_pattern, msg)
    if len(ips) > 0:
        if eventid in mapping:
            print(event_time, ips, mapping[eventid])
        else:
            print(event_time, ips, eventid)


def ReadLog(logType="Application"):
    py_handle = win32evtlog.OpenEventLog(None, logType)  # 打开日志文件
    numRecords = win32evtlog.GetNumberOfEventLogRecords(py_handle)  # 日志记录的数量
    while True:
        data_list = win32evtlog.ReadEventLog(py_handle,
                                             win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ,
                                             0)
        if not data_list:
            break
        for i in data_list:
            eventid = i.EventID & 0xFFFF  # 事件ID
            if eventid not in mapping.keys(): continue
            msg = win32evtlogutil.SafeFormatMessage(i, logType)  # 日志内容
            win32evtlogutil.FormatMessage(i, logType)
            event_time = i.TimeWritten  # 日志事件事件
            extract_info(msg.strip(), event_time, eventid)
            # print(eventid, msg.strip(), event_time)
    print("TOTAL", numRecords)
    win32evtlog.CloseEventLog(py_handle)  # 关闭句柄


ReadLog("Security")

input()


可以稍微改造一下添加防火墙规则方法。

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
Light紫星 + 3 + 1 用心讨论,共获提升!

查看全部评分

wasm2023 发表于 2024-10-10 15:11
Xiaosesi 发表于 2024-10-10 15:25
TOM小刚 发表于 2024-10-10 15:50
感谢分享,学到了
次森非彼森 发表于 2024-10-10 16:58
有没有linux 的脚本
zunmx 发表于 2024-10-10 17:44

linux的话, 你要说的应该是SSH或者是vnc吧,你可以试试fail2ban, 配置好规则,根据日志banip
ABCDWWWc123 发表于 2024-10-10 18:10
感谢楼主分享的脚步,拉黑ip方便
yunhang 发表于 2024-10-10 19:55
感觉可以直接白名单机制,最方便了 或者改个登陆端口
a147888123 发表于 2024-10-10 22:07
本帖最后由 a147888123 于 2024-10-10 22:09 编辑

何必搞的这么复杂呢,你不如改成更好的方案,就是任何人都是黑名单,只有你自己的IP访问的时候提前把你的IP写到防火墙白名单,让你远程连接,用完后删除你刚才用过的IP,保证谁也连不上,怎么让服务器知道你自己许可的IP去连接了服务器呢,脑洞大开点,可以解决的
这个方案我用了很久了,真好用,我用在自己一个系统上,可惜我们单位天天说要搞网络安全,对我这个方案不敢兴趣
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-15 02:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表