记一次不存在的注入之再看tp路由问题

背景

一套cms基于tp6

发现api接口中存在一个类似于注入的地方

1
2
3
4
5
6
7
8
9
10
public function lst(Request $request, $cid)
{
list($page, $limit) = UtilService::getMore([
['page',1],
['limit',10],
],$request, true);
$list = Article::cidByArticleList($cid,$page,$limit,"id,title,image_input,visit,from_unixtime(add_time,'%Y-%m-%d %H:%i') as add_time,synopsis,url") ?? [];
if(is_object($list)) $list = $list->toArray();
return app('json')->successful($list);
}

cidByArticleList方法为

1
2
3
4
5
6
7
8
9
10
11
12
public static function cidByArticleList($cid, $page, $limit, $field = 'id,title,image_input,visit,add_time,synopsis,url')
{
$model = new self();
// if ($cid) $model->where("`cid` LIKE '$cid,%' OR `cid` LIKE '%,$cid,%' OR `cid` LIKE '%,$cid' OR `cid`=$cid ");
if ((int)$cid) $model = $model->where("CONCAT(',',cid,',') LIKE '%,$cid,%'");
$model = $model->field($field);
$model = $model->where('status', 1);
$model = $model->where('hide', 0);
$model = $model->order('sort DESC,add_time DESC');
if ($page) $model = $model->page($page, $limit);
return $model->select();
}

很奇葩的判断方式

  • (int)$cid并不会改变后面拼接的cid的值

但是怎么都访问不到,访问如下

1612495440727

猜测应该是定义了路由

调用堆栈

  • index.php入口
  • http.phprun方法->runWithRequest方法->dispatchToRoute方法
  • route.phpdispatch方法
  • 加载定义的路由

1612495727398

  • 此时重新调用http.phploadRoutes方法,包含定义的路由文件

1612495800652

剩下的就是对路由进行检查的部分,直接定位路由文件

可以看到存在很多的未授权接口,刚才以为有漏洞的接口也在这里

但是调用这个接口后依然不能注入,就很懵逼

1612495934918

正常访问时下面这个样子

1612496287599

但是只要添加特殊符号,就直接404,查找根源

跟踪流程直接到相应的路由检查的地方

1612496061731

在匹配完成之后发现这个路由存在一个正则

1612496170252

就是cid参数值只能是字母数字下划线,不确定这是tp原生的还是cms重新定义的,继续查找根源

跟进buildRuleRegex方法

1612496549951

继续跟进buildNameRegex方法

之前的articlelist由于不存在<,所以直接return

1612496650122

但是cid变量传递进来的是<cid>

发现,刚才分析的正则表达式是config传递过来的

1612496747611

跟进config方法

1612496805872

发现这是thinkphp自带的过滤机制

1612496837962

遂得出一个结论,在使用自定义路由的时候

get方式的路由,无法注入,这相当于又多了一层安全保障吧