tp5.1注入分析
背景
上次遇到的盲猜的注入,其实我之前跟过流程,但是很明显的失败了
不知道为什么在cltphp中可以爆出数据库及一些数据
- 最终结果是
cltphp在linux下无法完成注入
- 在
Windows下可以完成,因为不区分大小写
但是在之前的测试中默认的配置是不存在notlike的注入问题的
故记录:
tp5.0和tp5.1关于notlike的框架差异
cltphp和默认tp5.1的差异
分析
tp5.0和5.1差异
在tp5.0中,notlike的注入支持#和--+等符号来注释
如下

但是在tp5.1中,使用#或者--+都会出现参数绑定的问题
#绑定参数是出现错误

--+则是不匹配的问题

经过分析发现
tp5.0中在绑定参数是,bind为空,无需进行绑定

tp5.1中则是需要进行绑定

那么问题肯定就是出在对like表达式的处理上了
tp5.0对like的处理
通过parseValue对传入的参数值进行处理,此时的item值依然为111'

跟进方法
可以发现,不存在:绑定符号,进入qoute方法进行处理

进入此方法后,只是通过PDO参数的类型进行了转义,并未进行bind之类的操作

所以返回的值直接为转义后的值,无需进行参数绑定

下面就是直接将logic拼接,所以在query方法中bind参数为空

tp5.1对like的处理
tp5.1就很简单了,定义了parseLike方法,方法中进行了参数绑定的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| protected function parseLike(Query $query, $key, $exp, $value, $field, $bindType, $logic) { if (is_array($value)) { foreach ($value as $item) { $name = $query->bind($item, $bindType); $array[] = $key . ' ' . $exp . ' :' . $name; }
$whereStr = '(' . implode(' ' . strtoupper($logic) . ' ', $array) . ')'; } else { $whereStr = $key . ' ' . $exp . ' ' . $value; }
return $whereStr; }
|
tp5.1和cltphp配置差异
默认情况下,如下代码,未进行警告或者error
1 2 3 4 5
| <?php $a = array(0=>"a"); list($b,$c) = $a; print_r($b); print_r($c);
|
但是在默认的tp框架中会爆下标1不存在

原因:目标cms的配置文件中关闭了错误

end
结语:
tp5.1中Request类去掉了表达式的过滤
tp5.1中exists表达式的写法问题,可能导致注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| protected function parseWhereItem($logic, $field, $op, $condition, $param = []) { if (is_array($op)) { array_unshift($param, $field); $where = $param; } elseif ($field && is_null($condition)) { if (in_array(strtoupper($op), ['NULL', 'NOTNULL', 'NOT NULL'], true)) { $where = [$field, $op, '']; } elseif (in_array($op, ['=', 'eq', 'EQ', null], true)) { $where = [$field, 'NULL', '']; } elseif (in_array($op, ['<>', 'neq', 'NEQ'], true)) { $where = [$field, 'NOTNULL', '']; } else { $where = [$field, '=', $op]; } } elseif (in_array(strtoupper($op), ['EXISTS', 'NOT EXISTS', 'NOTEXISTS'], true)) { $where = [$field, $op, is_string($condition) ? $this->raw($condition) : $condition]; } else { $where = $field ? [$field, $op, $condition, isset($param[2]) ? $param[2] : null] : null; }
return $where; }
|