病毒攻击PostgreSQL暴力破解系统,防范加固系统方案(内附分析日志脚本)

文摘   2024-10-25 06:00   天津  

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,可以解决你的问题。加群请联系 liuaustin3 ,(共2500人左右 1 + 2 + 3 + 4 +5 + 6 + 7 + 8)(1 2 3 4 5 群均已满,6群停止进人,新人进7群 8 群)


最近国际与安全的网站Hacker New,里面的一篇报道,这里简单的翻译一下

网络安全研究人员解开了一种名为PG_MEM的新型恶意软件,设计用于在暴力破解方式进入PostgreSQL数据库实例后进行加密货币挖矿。

“Aqua安全研究人员Assaf Morag在一份技术报告中表示:暴力破解Postgres的攻击涉及反复尝试猜测数据库凭据,直到获取访问权限,利用弱密码。”

“一旦获得访问权限,攻击者可以利用COPY ... FROM PROGRAM SQL命令在主机上执行任意shell命令,从而允许他们执行恶意活动,如数据窃取或部署恶意软件。”

写到这里,我们针对这样的暴力破解有什么办法,或者有什么方案来让PostgreSQL尽量在安全的状态和设置下工作,是我们第一个要考虑的。

1 使用强密码:这点说起来容易,做起来难。默认PostgreSQL建立用户是不会限制我们输入密码的字符数,和字符的组合难度。这里我们可以先使用PostgreSQL自带的passwordcheck插件来支持这个工作。为什么要使用这个插件,熟悉PostgreSQL的同学都清楚,一般PG的extension 部分都是针对逻辑库的,都需要在创建库后,加载,这个passswordcheck的好处就是,不需要,直接在配置文件该完,马上就可以应用,我们来看看。

shared_preload_libraries = 'passwordcheck'      # (change requires restart)
passwordcheck.level='true'

然后重启数据库,因为要加载到内存中。

postgres=# create user test_password superuser password 'test';
ERROR:  password is too short
postgres=# create user test_password superuser password 'test1234';
CREATE ROLE
postgres=# drop user test_password;
DROP ROLE
postgres=# create user test_password superuser password 'test12';
ERROR:  password is too short
postgres=# create user test_password superuser password 'Test12';
ERROR:  password is too short
postgres=# create user test_password superuser password 'Test1234';
CREATE ROLE
postgres=# create user test_password superuser password 'testtest';
ERROR:  password must contain both letters and nonletters
postgres=# create user test_password superuser password 'testtes@';
CREATE ROLE

在加载后,我们在进行数据库的建立用户的操作,我们可以发现,当前的插件passwordcheck,已经工作,必须8位字符,且其中要求是字母+数字,或字母+特殊符号等。这个插件从一定的角度上避免了,设置的密码不符合一些要求和标准的情况。

2 用户的有效期用户的有效期这个问题是管理上的问题,从PostgreSQL是支持检查用户的预设的有效期,通过有效期来防止一些临时的用户长时间在系统中,这点是一个安全的意识,但需要注意以下的一些账号不要用有效期来控制。

1 核心的应用访问数据库的账号,不能使用过期的账号 2 核心的管理人员不能使用过期账号

其他的临时或非重要的,都可以使用过期的账号的方式来管理。

具体的操作方法

postgres=# create user test_password superuser password 'testtes@' valid until '2024-10-24 08:00:00';
CREATE ROLE
postgres=
postgres=# alter user test_password with valid until '2024-10-24 10:00:00';
ALTER ROLE
postgres=

3 通过auth_delay.so 来对暴力破解密码进行一定的防护,这个功能模块主要的目的是在验证失败后,一定时间后才能在进行验证密码,这样如果是暴力破解密码,则会给暴力破解密码延长暴力破解的时间。

暴力破解最大的干扰项就是一个密码错误的确认时间,我们现在做的就是要加大他每次密码错误的确认时间。

[postgres@postgresql13 ~]$ psql -Utest -h 192.168.198.100 -p 5432 
Password for user test
psql: error: FATAL:  password authentication failed for user "test"
[postgres@postgresql13 ~]$ psql -Utest -h 192.168.198.100 -p 5432 
Password for user test
psql: error: FATAL:  password authentication failed for user "test"
[postgres@postgresql13 ~]$ 

上面就是一个例子,在这里我们设置了auth_delay的设置后,密码输入错误后,至少等待5秒钟,这极大的摧毁了暴力破解中的给数据库系统尝试密码中暴力破解系统的压力。

如何进行设置

shared_preload_libraries = 'auth_delay' # (change requires restart)
auth_delay.milliseconds = 5000

以上在PostgreSQL中的postgresql.conf文件中进行修改,需要重启系统

4 最后我们通过一个脚本来亡羊补牢,通过这个脚本可以快速的分析日志中的关于登陆的异常,比如有人连续登陆失败,或者使用一个账号连续用错误的密码登陆。

不知道如何安装Node.js 可以先看这篇(通过脚本自动管理PG方案)

PostgreSQL 远程管理越来越简单,6个自动化脚本开胃菜

这个脚本通过node.js,加上fs文件模块,来对我们的PostgreSQL中的日志进行分析,通过文件中发现连续的登陆错误的信息,或者黑客尝试暴力破解的信息。通过脚本可以分析出每个数据库账号在一个日志中登陆失败的次数,通过这个来发现异常。他会分析日志中到底发生了多少次以用户登录失败,且主要原因是因为密码错误的问题导致的登陆失败,且在日志中连续5次的密码登陆失败,将会在日志中提出警告,引起管理人员的注意。

小结:随着PostgreSQL越来越热,用的人越来越多,针对PostgreSQL的恶意软件就会越来越多,针对PostgreSQL的账户安全工作,需要更多的关注。

const fs = require('fs');
const readline = require('readline');
const path = require('path');

// 日志文件目录这里修改你的日志文件的目录,同时日志必须是postgresql名开头的日志(拷贝文件时把这行中文去掉)

const logDirPath = '/pgdata/errorlog'

async function analyzeFailedLogins() {
    const logFiles = fs.readdirSync(logDirPath).filter(file => file.startsWith('postgresql'));

    for (const file of logFiles) {
        console.log(`正在分析文件: ${file}`);

        const fileStream = fs.createReadStream(path.join(logDirPath, file));
        const rl = readline.createInterface({
            input: fileStream,
            crlfDelay: Infinity,
        });

        let failedLogins = {};
        let previousUser = null;
        let previousTimestamp = null;
        let failureCount = 0;

        let consecutiveFailures = 0;
        let consecutiveFailureDetails = [];

        for await (const line of rl) {
          
            if (line.includes('password authentication failed') || line.includes('authentication failed')) {
                const matchUser = line.match(/user "([^"]+)"/);
                const matchTime = line.match(/^(\d+-\d+-\d+ \d+:\d+:\d+)/); // 匹配时间戳

                if (matchUser && matchUser[1] && matchTime && matchTime[1]) {
                    const user = matchUser[1];
                    const timestamp = matchTime[1];

                   
                    failedLogins[user] = (failedLogins[user] || 0) + 1;

                   
                    if (user === previousUser && failureCount > 0) {
                        failureCount++;
                        consecutiveFailures++;
                        consecutiveFailureDetails.push({ user, timestamp });
                    } else {
                       
                        if (failureCount >= 5) {
                            console.log(`账号 ${previousUser} 连续登录失败超过 5 次:`);
                            console.table(consecutiveFailureDetails);
                        }

                        previousUser = user;
                        previousTimestamp = timestamp;
                        failureCount = 1;
                        consecutiveFailures = 1;
                        consecutiveFailureDetails = [{ user, timestamp }];
                    }
                }
            } else {
               
                if (failureCount >= 5) {
                    console.log(`账号 ${previousUser} 连续登录失败超过 5 次:`);
                    console.table(consecutiveFailureDetails);
                }
                failureCount = 0;
                previousUser = null;
                consecutiveFailures = 0;
                consecutiveFailureDetails = [];
            }
        }

       
        if (failureCount >= 5) {
            console.log(`账号 ${previousUser} 连续登录失败超过 5 次:`);
            console.table(consecutiveFailureDetails);
        }

        console.log('各账号登录失败统计:');
        for (const user in failedLogins) {
            console.log(`用户: ${user}, 登录失败次数: ${failedLogins[user]}`);
        }

        console.log('-----------------------------');
    }
}

analyzeFailedLogins().catch(err => {
    console.error('分析失败:', err);
});



置顶文章


PostgreSQL 远程管理越来越简单,6个自动化脚本开胃菜

OceanBase  学习记录 -- 安装简易环境

用MySql不是MySQL, 不用MySQL都是MySQL 横批 哼哼哈哈啊啊

17000多张MongoDB表的锅 自动分析删除表数据难题--从头到尾的处理过程(文尾有MongoDB开发规范)

"DBA 是个der" 吵出MySQL主键问题多种解决方案

PolarDB 杀疯了,Everywhere Everytime Everydatabase on Serverless

OceanBase  学习记录 --  开始入门





往期热门文章:


PostgreSQL  哪些版本尽量避免使用,版本更新重点明晰(PG12)

PostgreSQL  15 16 小版本更新信息小结 版本更新是不是挤牙膏

PostgreSQL 14 小版本分析,有那个版本不建议使用

Windows 是MySQL和PostgreSQL高性能数据库的坟墓

PostgreSQL 具有createdb的用户无法创建数据库的原因(之一)

道歉贴,为最近写的一篇“垃圾贴”

PostgreSQL 同样的语句 一会快 一会慢到底怎么回事,
MongoDB  系统IOPS 告警系统处于崩溃,优化语句从1秒优化到1毫秒解决问题

开发问MySQL 大事务证据,一个脚本堵上他的嘴

瞬间成为MongoDB专家,8个脚本都写好了,一用一个不吱声

MySQL还用学吗?这谁问的 “好问题” !

MySQL 8.0x 到 9.0均可能崩溃--云厂商开发指责 MYSQL不测试就推新版本?

MySQL 让你还用5.7 出事了吧,用着用着5.7崩了

MySQL 8.0 小版本更新要点,那个小版本更稳定(8.0.24-8.0.37)

MySQL 8.0 版本更新 要点 列表 (8.0-8.0.23)

DBA 失职导致 PostgreSQL 日志疯涨

微软 “爱” 上PostgreSQL, PG  “嫁给” 微软!

撕逼!PostgreSQL 和 MongoDB 开撕,MySQL却躺枪

阿里云 安全扫描 ,说我PostgreSQL 自建主机极度不安全, 谁的问题?

PostgreSQL 13.0-13.15 功能更新和bug fixed列表

撕逼!PostgreSQL 和 MongoDB 开撕,MySQL却躺枪

云原生数据库是青出于蓝胜于蓝,还是数据库产品的倒退?
专访唐建法-从MongoDB中国第一人到TapData掌门人的故事
MySQL 8.0x 到 9.0均可能崩溃--云厂商开发指责 MYSQL不测试就推新版本?
DISS 阿里云 DAS数据库服务,阿里云数据库服务的毒瘤

临时工说:DBA 7*24H 给2万的工作,到底去不去?

PolarDB 最近遇到加字段加不上的问题 与 使用PolarDB 三年感受与恳谈

PostgreSQL 稳定性平台 PG中文社区大会--杭州来去匆匆

MySQL 让你还用5.7 出事了吧,用着用着5.7崩了

临时工访谈:问金融软件开发总监  哪些业务不用传统数据库
PolarDB  Serverless POC测试中有没有坑与发现的疑问
临时工访谈:PolarDB Serverless  发现“大”问题了  之 灭妖记 续集
临时工访谈:庙小妖风大-PolarDB 组团镇妖 之 他们是第一
PolarDB for PostgreSQL  有意思吗?有意思呀
PolarDB  Serverless POC测试中有没有坑与发现的疑问

MySQL 的SQL引擎很差吗?由一个同学提出问题引出的实验

临时工访谈:从国产数据库 到 普罗大众的产品 !与在美国创业软件公司老板对话

PostgreSQL 如何通过工具来分析PG 内存泄露

MySQL 的SQL引擎很差吗?由一个同学提出问题引出的实验
临时工访谈:我很普通,但我也有生存的权利,大龄程序员 求职贴
临时工说: 快速识别 “海洋贝壳类” 数据库方法速递
临时工说:国产 数据库 销售人员  图鉴
临时工说:DBA 是不是阻碍国产数据库发展的毒瘤 ,是不是?从国产
PostgreSQL   玩PG我们是认真的,vacuum 稳定性平台我们有了
临时工说:裁员裁到 DBA 咋办  临时工教你 套路1 2 3
PolarDB  搞那么多复杂磁盘计费的东西,抽筋了吗?
临时工说:OceanBase 到访,果然数据库的世界很卷,没边
MONGODB  ---- Austindatabases  历年文章合集
MYSQL  --Austindatabases 历年文章合集
POSTGRESQL --Austindatabaes 历年文章整理
POLARDB  -- Ausitndatabases 历年的文章集合
PostgreSQL  查询语句开发写不好是必然,不是PG的锅
SQL SERVER 如何实现UNDO REDO  和PostgreSQL 有近亲关系吗
MongoDB 2023纽约 MongoDB 大会 -- 我们怎么做的新一代引擎 SBE Mongodb 7.0双擎力量(译)
MongoDB 2023年度纽约 MongoDB 年度大会话题 -- MongoDB 数据模式与建模
MongoDB  双机热备那篇文章是  “毒”
MongoDB   会丢数据吗?在次补刀MongoDB  双机热备
临时工说:从人性的角度来分析为什么公司内MySQL 成为少数派,PolarDB 占领高处
POLARDB  到底打倒了谁  PPT 分享 (文字版)
PostgreSQL  字符集乌龙导致数据查询排序的问题,与 MySQL 稳定 "PG不稳定"
PostgreSQL  Patroni 3.0 新功能规划 2023年 纽约PG 大会 (音译)

Austindatabases 公众号,主要围绕数据库技术(PostgreSQL, MySQL, Mongodb, Redis, SqlServer,PolarDB, Oceanbase 等)和职业发展,国外数据库大会音译,国外大型IT信息类网站文章翻译,等,希望能和您共同发展。
截止今天共发布 1238篇文章


AustinDatabases
关于数据库相关的知识分享
 最新文章