ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL注入实例( PHP + mysql )

2020-09-27 19:00:33  阅读:250  来源: 互联网

标签:pdo return GET mysql sql PDO SQL PHP strlen


SQL注入的产生一般是由:开发人员在编写过程中未对用户输入参数做处理,直接拼接SQL,导致数据库被篡改。

下面的Demo演示的是“恶意用户利用漏洞删除mysql数据”

<?php
//原有的sql模块,不安全的,抛弃
function sql($sql){
  /*
  * 这是一个为了使用方便而编写的sql方法。
  * 所有select开头的sql返回查询结果,
  * 所有非select开头的sql返回受影响的行数。
  */    

    $ip="***";
    $port=3306;
    $username="***";
    $password="***";
    $database="***";
    $return = 0;
    //创建PDO对象
    $dsn = "mysql:host=$ip;dbname=$database;port=$port;charset=utf8";
    if(preg_match("/^[iIuUdDsS][nNpPeE][sSdDlL][eEaA][rRtTcC][tTeE]/is",$sql)){
        try{
                        $options = array(
                          PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //默认是PDO::ERRMODE_SILENT, 0, (忽略错误模式)
                          PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认是PDO::FETCH_BOTH, 4
                        );
                        $pdo = new PDO($dsn, $username, $password, $options);
                        if (preg_match("/^[sS]/is",$sql)) {
                          //使用query
                          $stmt = $pdo->query($sql); //返回一个PDOStatement对象
                          $return = $stmt->fetchAll(); //获取所有
                          //$return = $stmt->rowCount(); //记录数
                        }else{
                          $return = $pdo->exec($sql); //返回受影响的行数
                          //$return = $pdo->lastInsertId();//返回修改的ID
                        }
                        $pdo = null;
                }catch(Exception $e){
                    $return = $e->getMessage();
                }
    }
    return $return;
}



/*
* Sql注入Demo,这是存在风险的实力:
*/
$k  = $_GET['k'];
$v  = $_GET['v'];
$i  = file_get_contents('php://input');
if( strlen($k)>0 && ((strlen($v)>0 && count($_GET)==2)||( strlen($i)>0 && count($_GET)==1) )){ 
    $v = strlen($v) > 0 ? $v : $i;
    echo sql("insert into kv(k,v)values('$k','$v');"); //没有使用预编译
    exit();
}

?>

 

 恶意用户访问:

1 curl "***.com/1.php?k=sql注入" -d "test');delete from kv;"

结果:kv表数据被全部删除!

MySQL [***_db]> select * from kv;
Empty set (0.04 sec)

MySQL [***_db]> 

 

解决方法:通过PHP prepare预编译sql

代码如下:

<?php

//进行预编译的sql方法
function ssql($sql,$arr=[],$json=false){
        $ip="***";
        $port=3306;
        $username="***";
        $password="***";
        $database="***";
        $dsn = "mysql:host=$ip;dbname=$database;port=$port;charset=utf8";
        $return = 0;

        if(preg_match("/^[iIuUdDsS][nNpPeE][sSdDlL][eEaA][rRtTcC][tTeE]/is",$sql)){
                try{
                        $options = array(
                                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //默认是PDO::ERRMODE_SILENT, 0, (忽略错误模式)
                                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认是PDO::FETCH_BOTH, 4
                        );
                        $pdo = new PDO($dsn, $username, $password, $options);//创建PDO对象
                        $stmt = $pdo->prepare($sql);//2)使用prepare预处理
                        $precute = $stmt->execute($arr);  //执行一条预处理语句 .成功时返回 TRUE, 失败时返回 FALSE 
                        if($precute){
                                if( preg_match("/^[sS]/is",$sql) ) {
                                        $sqlData = $stmt->fetchAll();
                                }else{
                                        $sqlData = $stmt->rowCount(); //成功数
                                }
                                if($json){
                                        $return = json_encode($sqlData,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);//JSON_PRETTY_PRINT|
                                }
                        }
                        $pdo = null;
                }catch(Exception $e){
                }
        }
    return $return;
}



/*
* 这是被测代码,使用预编译的sql方法
*/
$k  = $_GET['k'];
$v  = $_GET['v'];
$i  = file_get_contents('php://input');
if( strlen($k)>0 && ((strlen($v)>0 && count($_GET)==2)||( strlen($i)>0 && count($_GET)==1) )){ 
    $v = strlen($v) > 0 ? $v : $i;
    echo ssql("insert into kv(k,v)values(?,?);",[$k,$v]);
    exit();
}
?>

 

 恶意用户访问:

1 curl "***.com/1.php?k=sql注入" -d "test');delete from kv;"

结果:直接存入data,没有数据被删除。

MySQL [***_db]> select * from kv;
+----+------+-----------+------------------------+------+
| i | s | k | v | n |
+----+------+-----------+------------------------+------+
| 89 | NULL | sql注入 | test');delete from kv; | NULL |
+----+------+-----------+------------------------+------+
1 row in set (0.04 sec)

MySQL [***_db]>

 

标签:pdo,return,GET,mysql,sql,PDO,SQL,PHP,strlen
来源: https://www.cnblogs.com/LiTry/p/13741253.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有