当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0136776

漏洞标题:tipask前台无条件sql注入(条件限制gpc)

相关厂商:tipask

漏洞作者: hkAssassin

提交时间:2015-08-25 12:14

修复时间:2015-10-09 12:16

公开时间:2015-10-09 12:16

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:未联系到厂商或者厂商积极忽略

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-08-25: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-10-09: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

这cms很无语,而且国内很大公司好像还都在用。注入的问题特多。

详细说明:

/model/base.class.php 文件为初始化时加载的一个文件。里面全是初始化函数。
146 行function init_user() 函数直接是初始化用户信息的。代码如下:
function init_user() {
@$sid = tcookie('sid'); //接受sid参数
@$auth = tcookie('auth');
$user = array();
@list($uid, $password) = empty($auth) ? array(0, 0) : taddslashes(explode("\t", authcode($auth, 'DECODE')), 1);
if (!$sid) {
$sid = substr(md5(time() . $this->ip . random(6)), 16, 16);
tcookie('sid', $sid, 31536000);
}
$this->load('user');
//var_dump($_ENV['user']);die;
if ($uid && $password) {
$user = $_ENV['user']->get_by_uid($uid, 0);
($password != $user['password']) && $user = array();
}
if (!$user) {
$user['uid'] = 0;
$user['groupid'] = 6;
}
$_ENV['user']->refresh_session_time($sid, $user['uid']); //后面我们跟进这个函数看一下
$user['sid'] = $sid;
$user['ip'] = $this->ip;
$user['uid'] && $user['loginuser'] = $user['username'];
$user['uid'] && $user['avatar'] = get_avatar_dir($user['uid']);
$this->user = array_merge($user, $this->usergroup[$user['groupid']]);
//var_dump($this->user);die;
}
上面代码的问题出在sid参数上。这个参数通过tookie函数接受进来的。我们跟进看一下。此函数在/lib/global.func.php 文件中。函数代码如下:
function tcookie($var, $value = 0, $life = 0) {
global $setting;
$cookiepre = $setting['cookie_pre'] ? $setting['cookie_pre'] : 't_';//注意前缀,方便我们在前端找对应的参数
if (0 === $value) {
$ret = isset($_COOKIE[$cookiepre . $var]) ? $_COOKIE[$cookiepre . $var] : '';
checkattack($var, 'cookie');
return $ret;
} else {
$domain = $setting['cookie_domain'] ? $setting['cookie_domain'] : '';
checkattack($var, 'cookie'); //用来过滤
setcookie($cookiepre . $var, $value, $life ? time() + $life : 0, '/', $domain, $_SERVER['SERVER_PORT'] == 443 ? 1 : 0);
}
}
以上代码的核心部分是checkattack函数。是用来做过滤的。我们看下这个函数,此函数在globa.func.php文件中,代码如下:
function checkattack($reqarr, $reqtype = 'post') {
$filtertable = array(
'get' => '\'|(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)',
'post' => '\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)',
'cookie' => '\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)'
);
foreach ($reqarr as $reqkey => $reqvalue) {
if (preg_match("/" . $filtertable[$reqtype] . "/is", $reqvalue) == 1 && !in_array($reqkey, array('content'))) {
print('Illegal operation!');
exit(-1);
}
}
}
看到哪个foreach 我就郁闷了。他只过滤数组的情况,一般的情况不做正则匹配的过滤。上面的分析已经说的很明白了。
我们来看看前端的sid参数在哪里。当用户访问这个系统的首页的时候其实已经初始化了这个参数,参数为cookie字段的:tp_sid。
上面的sid参数最终进入了 refresh_session_time函数。这个函数在/model/user.class.php文件中,代码如下:
function refresh_session_time($sid, $uid) {
$lastrefresh = intval(tcookie("lastrefresh"));
//var_dump($lastrefresh);die;
if (!$lastrefresh) {
//echo 11111;die;
if ($uid) {
$this->db->query("UPDATE " . DB_TABLEPRE . "session SET `time` = {$this->base->time} WHERE sid='$sid'");
} else {
$session = $this->db->fetch_first("SELECT * FROM " . DB_TABLEPRE . "session WHERE sid='$sid'");
if ($session) {
$this->db->query("UPDATE " . DB_TABLEPRE . "session SET `time` = {$this->base->time} WHERE sid='$sid'");
} else {
$this->db->query("INSERT INTO " . DB_TABLEPRE . "session (sid,`ip`,`time`) VALUES ('$sid','{$this->base->ip}',{$this->base->time})");
}
}
tcookie("lastrefresh", '1', 60);
}
}
从上面的代码可以看出,只要$lastrefresh这个参数的值为0就可以进入数据库操作。而$lastrefresh这个参数也是cookie字段中的一个参数:tp_lastrefresh=0;
所以最终的攻击流程为。访问首页抓包在tp_sid参数处注入同时设置tp_lastrefresh=0;通过测试发现不会受到任何拦截。可以看下面的漏洞证明

漏洞证明:

下面的图为我在本地搭建的从tipask官网下载的最新版做的测试。utf8和gbk都测了,漏洞复现以utf8为例

1.png


下面的图为数据的监控日志

2.png


下面的图为我在他们官网做的测试。直接sleep(10)。官网挂了

3.jpg


下面的图为我自己写的一个脚本盲注数据库名,当然也可以读admin的密码

4.png

修复方案:

ps:你猜

版权声明:转载请注明来源 hkAssassin@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝


漏洞评价:

评论

  1. 2015-11-02 15:47 | BeenQuiver ( 普通白帽子 | Rank:101 漏洞数:26 | 专注而高效,坚持好的习惯千万不要放弃)

    开发者的脑子抽了。