PHP测试代码:
// 面向对象写法
$id=addslashes($_GET[‘id’]); //获取id并转义预定义字符
// /$id=$_GET[‘id’];
$mysqli=new mysqli(‘localhost’,’root’,’root’,’test’); //连接数据库 指定数据库
if ($mysqli->connect_errno) { //判断错误信息
die(‘Connect Eroor:’).$mysqli->connect_error(); //断开连接 返回错误
}else {
if ($id) {
$sql=”SELECT * FROM mysqli_test WHERE id=’$id'”; //查询语句
echo $sql;
$mysqli->query(‘set names gbk’);
$result=$mysqli->query($sql); //执行一个查询
//var_dump($result);
$date=$result->fetch_assoc(); //获得一个结果集
//var_dump($date);
echo “
username:”.$date[‘username’]; //打印输出
echo “
password:”.$date[‘password’];
}else {
echo “Error:ID NULL”;
}
}
?>
// 面向过程写法
// $con=mysql_connect(‘localhost’,’root’,’root’) or die(‘Connect Error:’.mysql_error()); //连接数据库
// mysql_select_db(‘test’,$con);//设置数据库
// $id=addslashes($_GET[‘id’]);
// $sql=”SELECT * FROM mysqli_test WHERE id=’$id'”;
// echo $sql;
// $result=mysql_query($sql);
// $date=mysql_fetch_assoc($result);
// echo “
username:”.$date[‘username’];
// echo “
password:”.$date[‘password’];
// //var_dump($date);
?>
当PHP开启magic_quotes_gpc (魔术引号),或者使用addslashes、mysql_real_escape_string等函数进行过滤时,如果查询语句中存在单引号,我们尝试闭合单引号就会被过滤掉,如图,通过添加\(转义符)将单引号转义
这种形式下,如果数据库使用的是GB2312、GBK、GB18030等宽字节的编码时,就会造成宽字节注入
当我们输入%df’时经过addslashes转义变成 %dF%5C%27 在通过GBK编码后变成 運’
在这里我们发现他多出来了一个单引号正好闭合了我们查询语句中的单引号
构造语句:http://127.0.0.1/sqltest.php?id=1%df’and 1=2 union select 1,user(),database() — a(这里要注意 在mysql注释符后边要加一个空格符,由于浏览器在会删去url末尾中的空格符 所以我们在后边加一个字符串 中间加个空格)
修复:
mysql_real_escape_string转义
参数化查询(预编译)
pdo查询