Java tunnel Oracle-OS

See How to Java, How to mine listener's log, Mining the alert.log
I have sysdba privilege on database but I can't kill sessions from OS because I don't have the oracle password...
That's quite boring...

 

Quick Java tunnel - no terminal reading

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "os/quickOracleTunnel" as
package os.quickOracleTunnel;
public class OST {
  public static void execute(String line) throws Exception {
    Runtime runtime = Runtime.getRuntime();
    //Process p = runtime.exec(new String[] {"cmd.exe", "/C", "del c:\\temp\\sqlnet.log"});
    Process p = runtime.exec(new String[] {"/bin/sh", "-c", line});
  }
}

create or replace procedure sh(line in varchar2) as LANGUAGE JAVA NAME 'os.quickOracleTunnel.OST.execute(java.lang.String)';

begin
  sh('kill -9 23770');
end;

 

Advanced Java tunnel - output(and errors) returned

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "pattern/myBlockingQueueAnyVersion/MyBlockingQueue" as
package pattern.myBlockingQueueAnyVersion;

public class MyBlockingQueue {

private int notifyCount = 0;
private int expectCount;
private Object lock = new Object();

class NotEnoughNotifications extends Exception {
public NotEnoughNotifications(String msg) {
super(msg);
}
}

public MyBlockingQueue(int expectCount) {
this.expectCount = expectCount;
}

public void threadIsDone() {
notifyCount++;
synchronized(lock) {
lock.notify();
}
}

 /** When using the timeout you probably don't care any more of the thread 
* after timeout, so remember to .setDaemon(true) on your thread*/
public void waitForThreadsDone(long timeout) throws Exception {
long callTime = System.currentTimeMillis();
long elapsedTime = 0;
while(((elapsedTime = (System.currentTimeMillis() - callTime))<timeout) &&
(notifyCount<expectCount)) {
long timeToWait = timeout-elapsedTime;
if(timeToWait>0) {
synchronized(lock) {
lock.wait(timeToWait);
}
}
}
if(notifyCount < expectCount) throw new NotEnoughNotifications(
"Timeout. Not enough finish notification received. Expected " + 
expectCount + ", received " + notifyCount + ", " + elapsedTime + 
" millis. elapsed, timeout was after " + timeout + " millis.");
else if (notifyCount > expectCount) throw new Exception("Too many finish " +
"notification received. Expected " + expectCount + ", received "
+ notifyCount);
}

public void waitForThreadDone() throws Exception {
boolean completionOk = false;
while(! completionOk) {
completionOk = true;
try {
waitForThreadsDone(Long.MAX_VALUE);
} catch(NotEnoughNotifications e) {
completionOk = false;
}
}
}

public static void main(String[] args) throws Exception {
args.getClass();
MyBlockingQueue lock = new MyBlockingQueue(1);
class MyThread extends Thread {
MyBlockingQueue lock;
public MyThread(MyBlockingQueue lock) {
this.lock = lock;
}
public void run() {
System.out.println("Thread done");
lock.threadIsDone();
}
};
MyThread t = new MyThread(lock);
t.start();
Thread.sleep(2000);
lock.waitForThreadDone();
}
}

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "os/oracleTunnel/advanced/StreamReader" as
package os.oracleTunnel.advanced;

import java.io.IOException;
import java.io.InputStream;

import pattern.myBlockingQueueAnyVersion.MyBlockingQueue;

public class StreamReader extends Thread {

  private InputStream inputStream;
  private String result = "";
  private MyBlockingQueue q;

  StreamReader(MyBlockingQueue q, InputStream inputStream) {
    this.inputStream = inputStream;
    this.q = q;
  }
  
  public void run() {
    try {
      byte[] buff = new byte[1000];
      int read = 0;
      while((read=inputStream.read(buff))!=-1) {
        result = result + new String(buff, 0, read);
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally { 
      q.threadIsDone();
    }
  }

  public String getResult() {
    return result;
  }
}

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "os/oracleTunnel/advanced/AST" as
package os.oracleTunnel.advanced;

import pattern.myBlockingQueueAnyVersion.MyBlockingQueue;

public class AST {

  public static class ECommandException extends Exception {
    public ECommandException(String msg) {
      super(msg);
    }
  }

  public static String execute(String command, long timeout) throws Exception {
    Runtime runtime = Runtime.getRuntime();
    Process process;
    //int exitValue = -1;
    process = runtime.exec(command);
    MyBlockingQueue q = new MyBlockingQueue(2);
    StreamReader errorReader = new StreamReader(q, process.getErrorStream());
    StreamReader outputReader = new StreamReader(q, process.getInputStream());
    errorReader.start();
    outputReader.start();
    /* Do not wait for process, any error is raisen from error output. 
     * Any command waiting for user input will hang forever */
    //exitValue = process.waitFor();
    q.waitForThreadsDone(timeout);
    if(errorReader.getResult().length() > 0)
      throw new ECommandException(errorReader.getResult());
    return outputReader.getResult();
  }
  
  public static void main(String[] args) throws Exception {
    args.getClass();
    System.out.println(AST.execute("cmd.exe /C dir", 10000));
  }
} 

Pl/Sql declaration

create or replace FUNCTION shAdv(Command IN STRING, timeout in number) RETURN varchar2 IS LANGUAGE JAVA NAME 'os.oracleTunnel.advanced.AST.execute(java.lang.String, long) return java.lang.String';

begin
  dbms_output.put_line(shAdv('df -k', 10000));
end;

For more complex commands you may create a file on the OS using WriteToFile.java.sql and then execute the file
Remember a chmode +x filename