PHP 之防sql注入示例

一、效果图

1、存在sql注入

image

2、消除sql注入

image

二、简单示例

1、创建表

image

2、提交界面设计

image

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
</head>
<body>
    <form action="?" method="POST">
        <input type="text" name="username" placeholder="请输入用户名"><br>
        <input type="password" name="password" placeholder="请输入密码"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

3、编写可注入的php代码

if($_POST) {
    extract($_REQUEST);
    $conn = mysqli_init();
    mysqli_real_connect($conn, '127.0.0.1', 'test', '123456'); //连接数据库
    mysqli_select_db($conn, 'test'); //选择数据库
    if(!$username || !$password) {
        die('error');
    }
    $sql = insertSql('test', [
        'username' => $username,
        'password' => $password
    ]);
    $res = mysqli_query($conn, $sql);
    mysqli_close($conn);
    if($res) {
        die('ok');
    }
    die('err');
}

 4、使用sqlmap测试

python sqlmap.py --url="http://localhost/test/test2.php" --dbs --data="username=yy&password=123" --method="post" --flush-session  --dbms=mysql --level=5 --risk=3 --random-agent --tamper=space2comment

三、解决sql注入

<?php
    if($_POST) {
        //处理sql注入
        $_REQUEST = strip_sql($_REQUEST);
        extract($_REQUEST);
        $conn = mysqli_init();
        mysqli_real_connect($conn, '127.0.0.1', 'test', '123456'); //连接数据库
        mysqli_select_db($conn, 'test'); //选择数据库
        if(!$username || !$password) {
            die('error');
        }
        $sql = insertSql('test', [
            'username' => $username,
            'password' => $password
        ]);
        $res = mysqli_query($conn, $sql);
        mysqli_close($conn);
        if($res) {
            die('ok');
        }
        die('err');
    }
    /**
     * 拼接sql语句
     * @param $table
     * @param $array
     * @return string
     */
    function insertSql($table, $array)
    {
        $sqlk = '';
        $sqlv = '';
        foreach ($array as $k => $v) {
            $sqlk .= ',`' . $k.'`';
            $sqlv .= ',"'.$v.'"';
        }
        $sqlk = substr($sqlk, 1);
        $sqlv = substr($sqlv, 1);
        $sql = "insert into $table ($sqlk) values ($sqlv)";
        return $sql;
    }

    function strip_sql($string, $type = 1) {
        if(is_array($string)) {
            return array_map('strip_sql', $string);
        } else {
            if($type) {
                $string = preg_replace("/\/\*([\s\S]*?)\*\//", "", $string);
                $string = preg_replace("/0x([a-fA-d0-9]{2,})/", '0&#120;\\1', $string);
                $string = preg_replace("/0X([a-fA-d0-9]{2,})/", '0&#88;\\1', $string);
                $string = preg_replace_callback("/(select|update|replace|delete|drop)([\s\S]*?)(from)/i", 'strip_wd', $string);
                $string = preg_replace_callback("/(load_file|substring|substr|reverse|trim|space|left|right|mid|lpad|concat|concat_ws|make_set|ascii|bin|oct|hex|ord|char|conv)([^a-z]?)\(/i", 'strip_wd', $string);
                $string = preg_replace_callback("/(union|where|having|outfile|dumpfile)/i", 'strip_wd', $string);
                return $string;
            } else {
                return str_replace(array('&#95;','&#100;','&#101;','&#103;','&#105;','&#109;','&#110;','&#112;','&#114;','&#115;','&#116;','&#118;','&#120;','&#69;','&#82;','&#84;','&#88;'), array('_','d','e','g','i','m','n','p','r','s','t','v','x','E','R','T','X'), $string);
            }
        }
    }
    
    function strip_wd($m) {
        if(is_array($m) && isset($m[1])) {
            $wd = substr($m[1], 0, -1).'&#'.ord(substr($m[1], -1)).';';
            if(isset($m[3])) return $wd.$m[2].$m[3];
            if(isset($m[2])) return $wd.$m[2].'(';
            return $wd;
        }
        return '';
    }
?>

 

posted @ 2025-07-25 14:20  样子2018  阅读(12)  评论(0)    收藏  举报