作为一个oracle运维人员,我们日常需要排查,看系统中的用户是否都是我们正在使用的用户,以防止有人恶意建立用户,从而使得业务数据的系统。 我们一般都是通过查询dba_users来查看当前系统中的用户。

如:select username from dba_users;

其实这种并不能完全显示我们系统中存在的用户,我来做如下演示:

    SQL> select username from dba_users;

    USERNAME
    ------------------------------
    SYS
    SYSTEM
    SCOTT
    OUTLN
    MGMT_VIEW
    MDSYS
    ORDSYS
    CTXSYS
    ANONYMOUS
    EXFSYS
    DMSYS

    USERNAME
    ------------------------------
    DBSNMP
    WMSYS
    SYSMAN
    XDB
    ORDPLUGINS
    SI_INFORMTN_SCHEMA
    OLAPSYS
    MDDATA
    DIP
    TSMSYS

    21 rows selected.

    SQL> conn xlh/oracle
    Connected.

    SQL> show user
    USER is "XLH"

从这个演示过程中,我们不难发现,我们在DBA_USERS中检查是没有发现XLH这个用户的,而我们却用这个账户登录成功。

这个用户我们就称之为匿藏用户。

在这里我给大家提供一种检测隐藏用户的方法:

    SQL> select USER# AS USERID,NAME,TYPE# AS TYPE FROM SYS.USER$ WHERE TYPE#=1 AND (NAME NOT IN (SELECT USERNAME AS NAME FROM ALL_USERS) OR NAME NOT IN (SELECT USERNAME AS NAME FROM DBA_USERS) );

    USERID NAME                                 TYPE
    ---------- ------------------------------ ----------
    55 XLH                                     1

这里查询出来的即为匿藏用户,那我们就需要分析一下为什么会出现这种情况,首先我们取出DBA_USERS的定义:

    SQL> select dbms_metadata.get_ddl('VIEW','DBA_USERS','SYS') FROM dual;

    DBMS_METADATA.GET_DDL('VIEW','DBA_USERS','SYS')
    --------------------------------------------------------------------------------

    CREATE OR REPLACE FORCE VIEW "SYS"."DBA_USERS" ("USERNAME", "USER_ID", "PASSWO

    RD", "ACCOUNT_STATUS", "LOCK_DATE", "EXPIRY_DATE", "DEFAULT_TABLESPACE", "TEMPOR

    ARY_TABLESPACE", "CREATED", "PROFILE", "INITIAL_RSRC_CONSUMER_GROUP", "EXTERNAL_

    NAME") AS
    select u.name, u.user#, u.password,
    。。。

    。。。
    and u.type# = 1
    and u.resource$ = pr.profile#
    and dp.profile# = 0

    DBMS_METADATA.GET_DDL('VIEW','DBA_USERS','SYS')
    --------------------------------------------------------------------------------
    and dp.type#=1
    and dp.resource#=1
    and pr.type# = 1
    and pr.resource# = 1
    and u.name !='XLH'

注意看高亮部门,系统视图呗篡改,有木有?

这种情况下,我们需要将篡改的视图改回去,即可正常使用DBA_USERS来查询出所有的用户。