重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛
标题:
Oracle 11g 用户密码抓取sql语句原理
[打印本页]
作者:
mahan
时间:
5 天前
标题:
Oracle 11g 用户密码抓取sql语句原理
select 'create user ' || username || ' identified by values' || '''' ||
b.password || '''' || ' default tablespace ' || default_tablespace ||
' temporary tablespace ' || temporary_tablespace || ';'
from dba_users a, sys.user$ b
where username = 'USERNAME'
and a.username = b.name;
SQL 语句是 Oracle 数据库管理员(DBA)在做数据库迁移或克隆环境时非常经典的一个“偷梁换柱”脚本。
它之所以能够“抓取”到用户的密码,核心原因在于它绕过了常规的安全视图,直接读取了数据库最底层的系统数据字典表,并利用了 Oracle 特殊的哈希导入语法。
以下是具体的原理解析:
1. 直击底层核心表:sys.user$
在这个查询中,起决定性作用的是 sys.user$ b 这一部分。
常规视图的限制: 在早期的 Oracle 版本中,管理员可以通过 dba_users 视图直接看到用户的密码哈希值。但出于安全考虑,Oracle 后来(10g 之后)将 dba_users 视图中的密码列隐藏或置空了。
基表的特权: sys.user$ 是 Oracle 数据库最底层的系统基表之一,存放着数据库用户的核心元数据。无论视图怎么隐藏,数据库在验证登录时总需要比对密码,因此密码的密文(哈希值)依然存储在这个基表里。查询中的 b.password 就是直接从底层基表里把这个加密后的哈希字符串提取了出来。
权限要求: 只有拥有极高权限(如 SYSDBA 或 SELECT ANY DICTIONARY)的用户,才能查询 sys.user$ 这个表。
2. 巧妙利用 IDENTIFIED BY VALUES 语法
抓取出密码的密文后,这个脚本通过字符串拼接 (||),动态生成了一句 CREATE USER 的 DDL 语句。其中的关键在于 IDENTIFIED BY VALUES:
通常我们创建用户使用的是 IDENTIFIED BY '明文密码',Oracle 接收到明文后,会在内部对其进行哈希加密,然后把哈希值存入底层表。
当使用 IDENTIFIED BY VALUES '哈希字符串' 时,相当于告诉 Oracle:“不要对后面这段字符串进行加密了,它本身已经是密文,请直接把它原样写入底层表。”
结果: 这样生成的新用户,其底层存储的密码密文与原用户完全一模一样。因此,当用户尝试登录新环境时,依然可以使用他们原来的“明文密码”成功登录,而 DBA 在整个过程中根本不需要知道真正的明文密码是什么。
现实情况与版本限制提示
虽然这个脚本逻辑非常清晰,但在现代实际应用中需要注意 Oracle 版本的演进:
Oracle 10g 及以前: 该语句完美适用,密码哈希确实存在 sys.user$.password 中(通常是 DES 加密)。
Oracle 11g: 密码加密算法升级为更安全的 SHA-1。在这个版本中,旧的 password 列可能为空,新的密码哈希被移动到了 sys.user$.spare4 列中。如果是在 11g 中使用,脚本里的 b.password 通常需要修改为 b.spare4。
Oracle 12c 及以上版本: 引入了 SHA-512 加密,且安全机制进一步严格,底层存储结构变得更复杂。在较新的版本中,官方推荐直接使用系统自带的包来获取包含密码哈希的完整建表语句,而不是手动拼表:
SQL
SELECT DBMS_METADATA.GET_DDL('USER', 'USERNAME') FROM DUAL;
欢迎光临 重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛 (http://bbs.cqsztech.com/)
Powered by Discuz! X3.2