【漏洞-Oracle】未设置口令复杂度校验、密码有效期

1.场景描述

三方漏洞扫描:

2.详细描述

安全问题:Oracle未设置系统的口令复杂度校验、密码有效期。

危害分析结果:存在使用口令被恶意用户猜测获得,合法用户身份被仿冒,导致系统被非授权访问的可能性。

**整改建议:**建议根据需要对系统用户口令设置复杂度限制,口令的复杂度(8位以上、至少字母、数字、符号等混合组成)并更换周期进行合理设置(90天以内),不允许新设定的口令与前次旧口令相同。

涉及对象: Oracle。

3.方案分析

查询后得知:可通过配置密码复杂度策略 解决。

Oracle数据库通过Profile来管理密码策略。默认情况下,数据库中有一个默认Profile:DEFAULT。我们可以修改这个默认的Profile ,或者创建一个新的Profile并将其应用到需要的用户中。
在profile中可配置,通过LIMIT子句可设置多个密码策略,如密码有效期、密码错误n次后锁定用户、密码错误后锁定的天数、密码是否可和之前一样、密码可一样几次、密码到期后可使用的天数、密码复杂度等。其中,密码复杂度验证可以用默认函数,可以根据需要自定义一个密码验证函数。

为了不影响原有用户,本文创建一个新Profile 进行测试。 步骤:

1)创建一个新profile:taiy_secure_profile,指定各种策略。

创建一个新密码验证函数:taiy_verify_function(8位以上,含字母、数字、符号等)。

2)将这个配置文件分配给特定的数据库用户,使得该用户的密码将受到这些策略的约束。

4.问题处理

4.1查询

sql 复制代码
[oracle@neptune ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Thu Dec 19 22:13:13 2024
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.


Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SYS@orcl> alter session set container=orclpdb1;

Session altered.

1)查看oracle 用户密码管理策略

select DISTINCT PROFILE from dba_users ;

sql 复制代码
SYS@orcl> select DISTINCT PROFILE from dba_users t ;

PROFILE
---------
DEFAULT

SYS@orcl>

结果截图: 策略都为DEFAULT

2)查看默认密码策略里的配置

sql 复制代码
命令:
SELECT * FROM dba_profiles WHERE resource_type='PASSWORD' ;

结果截图:

3) 查看密码复杂度校验

SELECT PROFILE,LIMIT FROM dba_profiles T WHERE resource_type='PASSWORD' AND T.resource_name='PASSWORD_VERIFY_FUNCTION'

order by 1,2

结果截图:

说明:Limit 列的值为null 表示未启用密码验证函发功能;

如果返回值为函数名称,如:VERIFY_FUNCTION 则表示启用验证函数功能。

4.2 创建新 密码验证函数:taiy_verify_function

密码复杂度要求:如8位以上,必须包含字母、数字、符号。

sql 复制代码
CREATE OR REPLACE FUNCTION taiy_verify_function (
    username IN VARCHAR2,
    password IN VARCHAR2,
    old_password IN VARCHAR2
) RETURN BOOLEAN IS
    l_min_length CONSTANT NUMBER := 8;
    l_has_upper BOOLEAN := FALSE;
    l_has_lower BOOLEAN := FALSE;
    l_has_zm   BOOLEAN := FALSE;
    l_has_digit BOOLEAN := FALSE;
    l_has_special BOOLEAN := FALSE;
    l_char CHAR(1);
BEGIN
    -- 检查密码长度
    IF LENGTH(password) <= l_min_length THEN
        RAISE_APPLICATION_ERROR(-20001, 'Password is too short');
    END IF;

    -- 遍历密码字符,检查是否包含大写字母、小写字母、数字和特殊字符
   /* FOR i IN 1 .. LENGTH(password) LOOP
        l_char := SUBSTR(password, i, 1);

        IF REGEXP_LIKE(l_char, '[A-Z]') THEN
            l_has_upper := TRUE;
        ELSIF REGEXP_LIKE(l_char, '[a-z]') THEN
            l_has_lower := TRUE;
        ELSIF REGEXP_LIKE(l_char, '[0-9]') THEN
            l_has_digit := TRUE;
        ELSIF REGEXP_LIKE(l_char, '[^a-zA-Z0-9]') THEN
            l_has_special := TRUE;
        END IF;
    END LOOP;*/
    
    IF REGEXP_LIKE(password, '[A-Z]') THEN
        l_has_upper := TRUE;
    END IF;
    IF REGEXP_LIKE(password, '[a-z]') THEN
        l_has_lower := TRUE;
    END IF;
    
    IF l_has_upper OR l_has_lower THEN
        l_has_zm := TRUE;
    END IF;

    IF REGEXP_LIKE(password, '[0-9]') THEN
        l_has_digit := TRUE;
    END IF;
    IF REGEXP_LIKE(password, '[^a-zA-Z0-9]') THEN
        l_has_special := TRUE;
    END IF;

    -- 检查是否满足所有复杂度要求
    IF NOT l_has_zm OR NOT l_has_digit OR NOT l_has_special THEN
        RAISE_APPLICATION_ERROR(-20002, 'Password does not meet complexity requirements');
    END IF;

    -- 其他检查(例如,密码不能与用户名、服务器名等相同)
    -- ...

    RETURN TRUE;
EXCEPTION
    WHEN OTHERS THEN
        RETURN FALSE;
END;
/

GRANT EXECUTE ON taiy_verify_function TO PUBLIC container=current;


create or replace function my_password_test
 ( username varchar2,
   password varchar2,
   old_password varchar2)
 return boolean IS
   differ integer;
begin
   if not ora_complexity_check(password, chars => 8, upper => 1, lower => 1,
                           digit => 1, special => 1) then 
      return(false);
   end if;
 
   -- Check if the password differs from the previous password by at least
   -- 6 characters
   if old_password is not null then 
      differ := ora_string_distance(old_password, password);
      if differ < 3 then
         raise_application_error(-20033, 'The new password should differ '
					|| 'from the previous password by '
					|| 'at least 4 characters.');
      end if;
   end if;
 
   return(true);
end;
/

GRANT EXECUTE ON my_password_test TO PUBLIC container=current;

查找资料:ORACLE的默认密码复杂度函数位置:$ORACLE_HOME/rdbms/admin下utlpwdmg.sql脚本中,有兴趣的可以看下。因此可将此函数写入该sql中,或者在任何位置执行sql创建函数即可。本文在该位置创建sql文件:taiy_verify_function.sql,赋予权限,执行。

@?/rdbms/admin/feng_verify_function.sql

/home/u01/app/oracle/product/19.3.0/dbhome_1/rdbms/admin/

-- 执行utlpwdmg.sql脚本

--"?"是一个占位符,代表Oracle的环境变量,代表Oracle的home目录。

--@ 是调用脚本标识,@后面直接写脚本的完整路径及...

执行结果:

4.3 创建新 profile: taiy_secure_profile,指定各种策略

含义:

FAILED_LOGIN_ATTEMPTS 10 --密码错误尝试次数,超过后被锁定

PASSWORD_LIFE_TIME 90 --密码有效期90天

PASSWORD_REUSE_TIME UNLIMITED --指定了口令不能重用前的天数:30天内不能重复使用旧密码

PASSWORD_REUSE_MAX UNLIMITED --重复使用旧密码的最大次数:如3

PASSWORD_LOCK_TIME 1 --登录尝试失败达到指定次数,用户锁定天数

PASSWORD_GRACE_TIME 7 /*--表示密码到期后可以延续使用的天数,

并且可延续时间内登录会有相应口令即将过期的提示。*/

PASSWORD_VERIFY_FUNCTION taiy_verify_function;

执行:

sql 复制代码
CREATE  PROFILE taiy_secure_profile LIMIT
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LIFE_TIME 90
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX  UNLIMITED
PASSWORD_LOCK_TIME  1
PASSWORD_GRACE_TIME 7
PASSWORD_VERIFY_FUNCTION taiy_verify_function;

4.4 将配置文件分配给特定用户,使其密码将受策略约束

执行:-- 将该配置文件分配给用户

sql 复制代码
ALTER USER NH_AML PROFILE taiy_secure_profile;

执行后,查看结果:

4.5 验证结果

oracle@neptune admin\]$ pwd /home/u01/app/oracle/product/19.3.0/dbhome_1/rdbms/admin ![](https://i-blog.csdnimg.cn/direct/fc3cc7ccfe07439b83bc4db2590c1cbe.png) 提示: ![](https://i-blog.csdnimg.cn/direct/2eb7390cda3b4763aa8f6cc1ee1f092d.png) ![](https://i-blog.csdnimg.cn/direct/33c4c81423a7415faafa0af7f057f578.png) 试了10次密码 失败后,再次登录正确密码,提示锁定 ![](https://i-blog.csdnimg.cn/direct/0ede799e1c83411284db4ef1cc4ce6c0.png) ![](https://i-blog.csdnimg.cn/direct/9f43e36b324844128f37346c384411ef.png) ## 5.知识总结 > CREATE PROFILE taiy_secure_profile LIMIT > > FAILED_LOGIN_ATTEMPTS 10 --密码错误尝试次数,超过后被锁定 > > PASSWORD_LIFE_TIME 90 --密码有效期90天 > > PASSWORD_REUSE_TIME UNLIMITED --指定了口令不能重用前的天数: > > 如:30天内不能重复使用旧密码 > > PASSWORD_REUSE_MAX UNLIMITED --重复使用旧密码的最大次数:如3 > > PASSWORD_LOCK_TIME 1 --登录尝试失败达到指定次数,用户锁定天数 > > PASSWORD_GRACE_TIME 7 /\*--表示密码到期后可以延续使用的天数, > > 并且可延续时间内登录会有相应口令即将过期的提示。\*/ > > PASSWORD_VERIFY_FUNCTION taiy_verify_function;

相关推荐
影子24014 小时前
Navicat导出mysql数据库表结构说明到excel、word,单表导出方式记录
数据库·mysql·excel
java_heartLake4 小时前
PostgreSQL15深度解析(从15.0-15.12)
数据库·postgresql
nuc-1276 小时前
sqli-labs学习记录8
数据库·学习·sqli-labs
余华余华7 小时前
计算机等级考试数据库三级(笔记3)
服务器·数据库·oracle
南風_入弦8 小时前
Oracle logminer详解
数据库·oracle·恢复
小安同学iter9 小时前
SpringBoot (二) 日志系统
数据库·spring boot·后端
Chandler249 小时前
Redis:事务
数据库·redis·缓存
是阿建吖!10 小时前
【MySQL】事务
数据库·mysql
Asuka0711 小时前
MySQL数据库和表的操作
数据库·mysql
天上掉下来个程小白11 小时前
Redis-04.Redis常用命令-字符串常用命令
java·数据库·redis·springboot·苍穹外卖