| 作者:冰的原点 说明:文章已发表于黑客手册07年11期,转载请注明出处!
自己刚刚学ASP,哎,没有人教,好不爽呀!这不,自己看了几本书后,而且非安全上每期都有分析ASP的文章,代码都看得‘懂’了,于是心痒了,马上跑到百度大叔那里去!下了个浪人文章系统V2.3!慢慢看了起来!
由于没有经验,因此就看先黑箱测试!本地打开一看,呵呵,界面还不错嘛!如图1.

随便点个文章看看,咦,竟然是这种形式的:read.asp?id=120,那还等什么,直接在后面加一个 and 1=1试试,如图2.

哇,直接跳到官方网站去了!怎么回事?看来有东西在监视url传来的数据。这回没辙了,只有硬着头皮去看代码了。于是来到这里,关键代码如下:
<!--#include file="Inc/Config.asp" --> <% dim sql dim rs dim SortName,SortID,AsSortName,AsSortID if Request.QueryString("ID")="" then response.wrITe "没有选择相关文章" response.end end if
set rs=server.createobject("adodb.recordset") sql="update "&GuTablePrefix&"_Article set ArticleReadNum=ArticleReadNum+1 where ArticleID="&Request.QueryString("ID") rs.open sql,conn,1,3 sql="select SortID,AsSortID,ArticleTitle,ArticleWriter,ArticleWrITerContact,ArticleFrom,ArticleFromURL,ArticleContent,ArticleCommend,ArticleShow,ArticleReadNum,ArticleDate from "&GuTablePrefix&"_Article where ArticleID="&Request.QueryString("ID") rs.open sql,conn,1,1 if rs.eof and rs.bof then response.wrITe "没有找到相关文章" response.end else ArticleTitle=rs("ArticleTITle") LKeys=rs("ArticleTITle") SortID=rs("SortID") AsSortID=rs("AsSortID") ArticleWriter=rs("ArticleWrITer") ArticleWriterContact=rs("ArticleWrITerContact") ArticleFrom=rs("ArticleFrom") ArticleFromURL=rs("ArticleFromURL") ArticleCommend=rs("ArticleCommend") ArticleReadNum=rs("ArticleReadNum") ArticleDate=rs("ArticleDate") ArticleContent=rs("ArticleContent")
set rsC=server.createobject("adodb.recordset") sql="select SortName from "&GuTablePrefix&"_Sort where SortID="&SortID rsC.open sql,conn,1,1 SortName=rsC("SortName") rsC.close set rsS=server.createobject("adodb.recordset") sql="select AsSortName from "&GuTablePrefix&"_AsSort where AsSortID="&AsSortID rsS.open sql,conn,1,1 AsSortName=rsS("AsSortName") rsS.close end if rs.close %> |
很明显,这里只判断id是不是为空就直接进入数据更新,按理由我们是有机可乘的,唯一有问题的就是那个包含文件了(这里要谢谢神无月同学了,开始我还以为这个文件里面不会有问题,没想到问题就出在这个文件里)。于是我们来到这里:
<!-- #include file="conn.asp" --> <!-- #include file="Function.asp" --> <% dim WebName,WebURL,WebMKeyWords,WebMDescription dim GuTablePrefix,LRECNUserNameD,LRECNUserGradeD dim SM_SServer,SM_SUsername,SM_SPassword,RM_Subject,RM_SendEmail,RM_SendName,RM_Body dim RArticleDate,RArticleUserName,RArticleAddIP,RArticleReadNum dim MessageQQ,SearchIP,ReadExplain WebName="浪人文章" WebURL="http://www.lre.cn/article/" WWebMKeyWords="浪人文章" WebMDescription="浪人文章" GuTablePrefix="LRE_CN" LRECNUserNameD=session("LRECNUserNameSe") LRECNUserGradeD=session("LRECNUGUserGrade") SM_SServer="mail.lre.cn" SM_SUsername="article@lre.cn" SM_SPassword="sendmail" RM_Subject="" RM_SendEmail="" RM_SendName="" RM_Body="1" ArticleWrITer="未知" ArticleWrITerC ArticleFrom="网络" ArticleFromURL="" RArticleDate="0" RArticleUserName="0" RArticleAddIP="0" RArticleReadNum="0" MessageQQ="http://wpa.QQ.com/msgrd?V=1&SITe=WWW&Menu=yes&Uin=" SearchIP="http://www.ip.cn/ip.php?q=" ReadExplain="" ’Username:peonun ’DateTime:2006-9-14 00:00:20 %> <!-- #include file="../SQL.asp" --> |
了,当时我看的时候,只看了这个文件的头部分,没有往下看,这就是作者的细心的地方,把这一句文件在文件最后了,才导致我出现这样低级的错误。于是继续跟踪,来看这个文件到底是怎么监视的,关键代码如下:
<% Dim Fy_Url,Fy_a,Fy_x,Fy_Cs(),Fy_Cl,Fy_Ts,Fy_Zx
Fy_Cl=2 ’处理方式:1=提示信息,2=转向页面,3=先提示再转向指定页面 Fy_Zx=""&WebURL&"" ’出错时转向的页面,现在设置的是提取网站网址
On Error Resume Next Fy_Url=Request.ServerVariables("QUERY_STRING") ’原点解释(下同):取得传递过来的url Fy_a=split(Fy_Url,"&") ’用splIT以&进行分割,并把分割取得的字符存在fy_a里 redim Fy_Cs(ubound(Fy_a)) ’重新定义fy_a的上界 On Error Resume Next ’容错语句 for Fy_x=0 to ubound(Fy_a) Fy_Cs(Fy_x) = left(Fy_a(Fy_x),instr(Fy_a(Fy_x),"=")-1) ’定义fy_cs(fy_x) Next For Fy_x=0 to ubound(Fy_Cs) If Fy_Cs(Fy_x)"" Then If Instr(LCase(Request(Fy_Cs(Fy_x))),"’")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"and")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"=")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"(")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),")")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),">")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"select")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"update")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"chr")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"delete%20from")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),";")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"insert")0 or Instr(LCase(Request(Fy_Cs(Fy_x))),"mid")0 Or Instr(LCase(Request(Fy_Cs(Fy_x))),"master.")0 Then ’这一句最关键了,这里首先用fy_cs函数对传来的url进行处理,然后把字符串强制转化成小写,然后用instr函数判断传递过来的字符中是否含有’,and, =等字符,如果有的话,用select case语句来处理 Select Case Fy_Cl Case "1" Response.WrITe "" Case "2" Response.WrITe "" Case "3" Response.WrITe "" End Select Response.End End If End If Next %> | 上面fy_cl定义的初始值是2,因此很明显就跳到官方网去了。这里就找出原因了!而且我看了下,几乎所有的文件都包含了config.asp这个文件,既然这样,看来注入是没戏了!不甘心,于是继续看,或许还有其它的洞。当我看到upfile.asp时,于是兴趣又来了,关键代码如下:
<html> <head> <title>上传文件</tITle> <meta http-equiv="Content-Type" c> <!--#include FILE="Inc/Style.asp"--> <Script Language="VBScript"> <!-- Sub SelAddress() document.form.filepath.value=document.form.DownAddress.value End Sub //--> </Script> | 哈哈,还有这样的漏洞,赶快直接在地址栏中输入http://127.0.0.1/22/upfile.asp,如图3.

还等什么,直接传马呀。没想到出现的却是这个结果,如图4.

难道是免费版的就这样对待么?哎,连上传文件都没有写好。真是!再转一圈!咦,有留言耶!说不定可以跨站哦! 试试,如图5.

点确定,咦,怎么没对话框呢?只有这一句返回信息:用户留言已提交完成..多谢!难道是给管理员看的!于是赶快跑到后台看看去!查看“用户留言管理”,哈哈,出现了,漏洞产生了。如图6.

这里为什么成功,是因为上面的那个处理文件并没有对我们提交的内容进行处理(只对url进行了处理),所以才产生了漏洞。只找了个这样的洞心里不爽,于是跑到官网去瞧下,看它的上传页面写好了没,打开一看,哇,还在(心里想,这下你完了),如图7.

还等什么,直接传马,没想到返回信息是这样的,如图8.

看来管理员也不是吃醋的呀!于是就放弃了。
第一次写asp分析的文章,还没有经验,不足之处再所难免!有什么问题可以到论坛来和我讨论,我的ID是冰的原点!
|