如何在以下PHP mysql_ *代码上执行SQL注入?
我有一个现有的应用程序,曾经使用不推荐的
mysql_ *函数来执行数据库查询.我已经将大多数数据库访问(以及所有具有用户输入的内容)更改为PDO,因此我相信我对注入攻击相对安全.但是,我想知道如何对前面的代码执行注入攻击,以便我可以证明在需要时它是多么不安全.
我有一个格式的链接: http://localhost/api/view.php?id= 然后将未经过清理的内容传递到下面的select函数中: $db->select('invitations','Replied,Response,Registered',null,"Id = '".$id."'"); $res = $db->getResult(); 然后我做一个var_dump()来查看结果. 我尝试过类似的东西: > http://localhost/api/view.php?id =< id>‘ 但似乎这些类型的查询不会成功.理想情况下,我希望能够做一些严厉的事情.我希望得到像’); DROP TABLE用户; –,但我似乎无法做出任何类型的事情. 这是完整的选择功能: public function select($table,$rows = '*',$join = null,$where = null,$order = null,$limit = null){ // Create query from the variables passed to the function $q = 'SELECT '.$rows.' FROM '.$table; if($join != null){ $q .= ' JOIN '.$join; } if($where != null){ if (is_array($where)) { $filter = $where; $where = " 0 = 0 "; $qs = ""; for ($i=0;$i<count($filter);$i++){ switch($filter[$i]['data']['type']){ case 'string' : $qs .= " AND ".$filter[$i]['field']." LIKE '%".$filter[$i]['data']['value']."%'"; Break; case 'list' : if (strstr($filter[$i]['data']['value'],',')){ $fi = explode(',$filter[$i]['data']['value']); for ($q=0;$q<count($fi);$q++){ $fi[$q] = "'".$fi[$q]."'"; } $filter[$i]['data']['value'] = implode(',$fi); $qs .= " AND ".$filter[$i]['field']." IN (".$filter[$i]['data']['value'].")"; }else{ $qs .= " AND ".$filter[$i]['field']." = '".$filter[$i]['data']['value']."'"; } Break; case 'boolean' : $qs .= " AND ".$filter[$i]['field']." = ".($filter[$i]['data']['value']); Break; case 'numeric' : switch ($filter[$i]['data']['comparison']) { case 'eq' : $qs .= " AND ".$filter[$i]['field']." = ".$filter[$i]['data']['value']; Break; case 'lt' : $qs .= " AND ".$filter[$i]['field']." < ".$filter[$i]['data']['value']; Break; case 'gt' : $qs .= " AND ".$filter[$i]['field']." > ".$filter[$i]['data']['value']; Break; } Break; case 'date' : switch ($filter[$i]['data']['comparison']) { case 'eq' : $qs .= " AND ".$filter[$i]['field']." = '".date('Y-m-d',strtotime($filter[$i]['data']['value']))."'"; Break; case 'lt' : $qs .= " AND ".$filter[$i]['field']." < '".date('Y-m-d',strtotime($filter[$i]['data']['value']))."'"; Break; case 'gt' : $qs .= " AND ".$filter[$i]['field']." > '".date('Y-m-d',strtotime($filter[$i]['data']['value']))."'"; Break; } Break; } } $where .= $qs; } $q .= ' WHERE '.$where; } if($order != null){ $q .= ' ORDER BY '.$order; } if($limit != null){ $q .= ' LIMIT '.$limit; } // Check to see if the table exists if($this->tableExists($table)){ // The table exists,run the query $query = @mysql_query($q); if($query){ // If the query returns >= 1 assign the number of rows to numResults $this->numResults = mysql_num_rows($query); // Loop through the query results by the number of rows returned for($i = 0; $i < $this->numResults; $i++){ $r = mysql_fetch_array($query); $key = array_keys($r); for($x = 0; $x < count($key); $x++){ // Sanitizes keys so only alphavalues are allowed if(!is_int($key[$x])){ if(mysql_num_rows($query) > 1){ $this->result[$i][$key[$x]] = $r[$key[$x]]; }else if(mysql_num_rows($query) < 1){ $this->result = null; }else{ $this->result[$key[$x]] = $r[$key[$x]]; } } } } return true; // Query was successful }else{ array_push($this->result,mysql_error()); return false; // No rows where returned } }else{ return false; // Table does not exist } } 我怎样才能执行SQL注入? 编辑: 使用$_GET [‘id’]通过浏览器接收该值.事实上,第二个值不是在SQL查询中使用,而是在switch语句中使用.所以,完整的请求看起来像这样: http://localhost/api/view.php?rsvp=<status>&id=<id> 这可能有所帮助. 编辑2: 可能重要的是要提到有问题的ID实际上是GUID,而不是数值.到目前为止,我使用正确的ID在评论中运行了所有查询.以下是一些结果: > http://localhost/api/view.php?id = 62FD23D8-B6C0-03F1-D45A-C9AC33C91774′; drop table users; – => array(1){[0] => string(166)“您的SQL语法中有错误;请查看与您的MySQL服务器版本对应的手册,以便在’drop table users附近使用正确的语法; – ”在第1行”} 以下这些行是使用$id的全部代码: // ... if(isset($_GET['id'])) { $id = $_GET['id']; $db->select('invitations',"Id = '".$id."'"); $res = $db->getResult(); // ... } 解决方法
仅仅是一些特定输入导致MySQL语法错误的事实证明用户输入对SQL语法有一些意想不到的影响,这意味着可以进行SQL注入.
但是这种SQL注入的利用是另一个章节. MySQL,或者更确切地说是PHP’s MySQL extension,默认情况下不支持使用
因此,删除表的经典示例将无效,您从注入点开始是limited to the capabilities of the current statement和allowed syntax elements. 在您的具体示例中,SELECT限制您 >从MySQL用户可以访问的数据库中读取任意数据 对于读取任意数据,UNION将是最佳选择,因为结果似乎反映回用户.您必须确保生成的SQL是有效的,这意味着您的UNION必须有三列(即,现有SELECT中的Replied,Response和Registered): ' UNION SELECT '1','2','3 结果语句如下所示: SELECT Replied,Registered FROM invitations WHERE Id = '' UNION SELECT '1','3' 您现在可以用自己的表达式(包括LOAD_FILE)或子查询替换另外选择的值. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |