从三月开始,安华金和安全实验室会陆续推出系列文章,专门以oracle数据库为研究对象,展开安全隐患的分析研究,为大家带来安全防范建议,帮助大家做好数据库安全防护。本期推出oracle 12c 安全隐患系列(一),如果您或您的团队正在使用oracle12c,或打算使用oracle12c,请一定按照本文思路对用户的inherit privileges权限进行合理分配,杜绝安全隐患。
在12.1之后的oracle版本中引入了一个和安全相关的权限—inherit privileges。这个权限可以赋予用户或角色。喜的是,oracle引入这个权限的目标是解决调用者权限可能造成的安全隐患。然而悲的是,在12.1的默认配置下,inherit privileges并不会起到提高安全性的作用。只有用户重新配置inherit privileges才能真正达到oracle设计inherit privileges提高安全性目的。
要弄清楚如何正确配置inherit privileges,首先要搞清楚三个问题:1.调用者方式的安全隐患。2. inherit privileges是如何工作的?3. inherit privileges应该如何配置?
oracle函数、存储过程的创建不同于其他数据库,可以采取两种截然不同的方式建立。一种是定义者权限(definer’s right),一种是调用者权限(invoker’s right)。调用者权限创建的函数或存储过程,在创建过程中不会判断创建者是否拥有对存储过程或函数中调用的表、视图和对象的执行权限。简单地说,就是调用者方式允许低权限用户在函数或存储过程中使用超越自身的权限。允许超越自身权限带来了便利,也同时给数据库带来非法提权、非法操作、非法获取敏感信息等一系列安全隐患。
为了讲清楚隐患,这里举一个例子:有一个低权限用户hacker_user,他只有创建存储过程和会话权限。
hacker_user使用调用者权限创建了函数 add_number。并把add_number的执行权限赋予全体,让所有用户都可以通过hacker_user. add_number的方式调用该函数。
至此无论是有dba权限的dba_user还是只有会话权限的normal_user都可以使用hacker_user. add_number完成运算任务。
当hacker_user. add_number得到其他用户充分信任后,hacker_user动了提升自己权限的心思。于是hacker_user首先使用调用者方式创建一个用于提权的存储过程(change_me_dba)。由于使用的是调用者方式,即使“grant dba to hacker_user这种高危语句被嵌入其中,存储过程也能顺利创建。
接着hacker_user再偷偷对add_number进行修改,在add_number中调用change_me_dba.
hacker_user整个布局完成后,就静静等着其他用户像以往一样调用hacker_user. add_number。这种攻击的方式不仅难以防护,还难以被察觉。低权限用户使用hacker_user. add_number,依然会正常运算,同时也不会出现任何报错信息。例如用normal_user调用hacker_user. add_number 正确运算,且无报错,如果不去检查hacker_user. add_number的源码会很难发现,实际上hacker_user在私下已经偷偷对hacker_user. add_number动了手脚。
由于无异常、不报错,被hacker_user修改后的add_number能安全地潜伏在数据库中。等到类似dba_user这样的dba用户调用hacker_user. add_number后,它会神不知鬼不觉地进行提权。
同样地,即便是有dba权限的dba_user调用也不会有任何异常。除非查询dba_role_privs,才会抓到hacker_user的“狐狸尾巴”。
但分析如何提权,必须对所有hacker_user中的内容进行分析,因为发现问题的时候hacker_user很可能早就把add_number改了回去,把change_me_dba做了删除,做到毁尸灭迹,以防止安全人员找到提权手法后,进行针对性封堵。
oracle12.1为了解决上述问题,引入了inherit privileges和inherit any privileges 这两组权限,用以限制用户访问其他用户,使用调用者权限创建的函数或存储过程。在12.1上正确配置权限后用dba_user调用add_number,不仅不会执行,且会出现ora-06598错误,用以防止低权限用户借用高权限进行非法操作。
inherit privileges通过grant和revoke进行赋权或取消赋权。invoking_user(dba_user)只把自己的inherit privileges赋予自己信任的procedure_owner(hacker_user)中,防止调用不安全的存储过程或函数。
grant inherit privileges on user invoking_user to procedure_owner;
revoke inherit privileges on user invoking_user from procedure_owner;
引入inherit privileges原本可以很好地解决低权限用户利用调用者方式,骗取高权限的问题。但oracle12.1默认对inherit privileges权限的赋予存在一定的问题。12.1在创建新用户或升级到12.1后对老用户都自动做了grant inherit privileges on user username to public 的操作,使得inherit privileges的限制直接作废。默认状态下hacker_user依然可以用上述手段完成提权操作。
好的解决方法也需要合理的配置。如果配置不当,安全将成为一句空话。inherit privileges权限的办法是好的,但不科学的默认配置毁了这一切。
默认任何用户都把inherit privileges赋予public的行为,很大程度是从兼容性的角度考虑的。虽然达到了兼容的目的,但却破坏了安全的效果,而且很可能给后来者留下错误使用inherit privileges的范例。总结下来,inherit privileges合理配置应该遵循两点:1.用户只给可信且必要的存储过程和函数的用户赋予inherit privileges;2.dba用户不要给任何用户inherit privileges 权限,防止出现低权限用户被破解后利用调用者权限窃取dba权限,实施非法行为。
针对上述两个要点,我们首先检查当前数据库dba用户有system、sys和dba_user.
下一步再检查这些dba用户是否已经给其他用户inherit privileges,如果存在请进行回收,否则可能造成安全隐患。
dba_user用户inherit privileges权限赋予public,回收该权限。否则,还可能出现dba用户误使用有风险的函数或存储过程的现象。
对每一个dba使用类似检查,修改dba默认的赋权对象,再按照实际需求把用户的inherit privileges权限赋予必要用户。如此,既不影响用户使用,又在一定程度上避免安全隐患。
当然如果您不愿意手动进行上述检查和部署,可以通过安华金和的漏扫产品dbscan,进行针对性的专项检查,并根据您的配置方案进行权限的自动部署。
inherit privileges的出现说明oracle对于安全问题已经越来越重视。但百密终有一疏,在默认情况下,新功能inherit privileges形同虚设,并不能起到加强数据库安全的效果。如果您或您的团队正在使用oracle12c,或打算使用oracle12c,请一定按照本文思路对用户的inherit privileges权限进行合理分配,杜绝安全隐患。
试用申请