ThinkPHPSQL注入
前段时间先知上的一篇文章
成因:传入参数未进行过滤
thinkphp的MVC架构中,Controller函数的变量也作为GET/POST传参的方式,如 http://serverName/index.php/Home/Blog/archive/year/2013/month/11 我们即可访问到 public function archive($year=’2013’,$month=’01’)。而这个URL同样可以写为http://serverName/index.php?c=Blog&a=archive&year=2013&month=11,那么同样可以写为http://serverName/index.php?c=Blog&a=archive&year=2013&month[0]=exp&month[1]=sqli。这样传递的参数是不会经过I函数的,所以I函数里的过滤也没有效果。
跟踪下TP的处理流程吧~
TP3.2:
自己写一个文件
(模型类命名为除去表前缀的数据表名称,采用驼峰法命名,并且首字母大写,然后加上模型层的名称(默认定义是Model) 例: UserModel.class.php)
1 | public function login(){ |
首先跟踪Where
1 | …… |
简单的将where放入options[where]里
再来看看find
跟踪到
1 | $resultSet = $this->db->select($options); |
继续跟踪select
1 | public function select($options=array()) { |
跟进buildSelectSql
1 | $sql = $this->parseSql($this->selectSql,$options); |
跟进parseSql
1 | public function parseSql($sql,$options=array()){ |
因为我们是where,所以跟进parseWhere
1 | $whereStr .= $this->parseWhereItem($this->parseKey($key),$val); |
继续跟进parseWhereItem
1 | elseif('bind' == $exp ){ // 使用表达式 |
传入的数组第一位是exp或者bind的时候都可直接将数组第二位带入SQL语句,先来看下exp的
这里数组第二位未传参,可传任意参数
bind的时候会带上: 需要满足其他条件才能造成注入
1 | public function login(){ |
传入参数
1 | id[]=bind&id[]=0'&username=1234 |
即可