好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

MYSQL PDO宽字符SQL注入深入分析 - 网站安全 - 自学

首先查看以下代码

 

$pdo->query('SET NAMES GBK'); 

$var = chr(0xbf) . chr(0x27) . " OR 1=1 /*"; 

$query = "SELECT * FROM test WHERE name = ? LIMIT 1"; 

$stmt = $pdo->prepare($query); 

$stmt->execute(array($var)); 

 

1.设置字符集

SET names x等同于以下内容:

SET character_set_client = x 

SET character_set_results = x 

SET character_set_connection = x 

 

2.设置payload www.2cto.com

 

3.深入分析

mysql的prepare其实是本地 PHP 客户端模拟的,并没有根据你 mysql 的设置做字符集的调整。应该交与mysql server端做prepare,同时得调用mysql_set_character_set去操作,server才会按照字符集去做转义。

php本地模拟的prepare底层就是mysql_real_escape_string,所以必须得用mysql_set_character_set去设置mysql->charset,否则就存在字符集问题。

 

也就是说在php本地调用pdo prepare中的mysql_real_escape_string来操作query,使用的是本地单字节字符集,即编码为\xbf\x5c\x27,并带入到mysql中查询,由于使用set names设置了连接字符集,mysql使用内部操作字符集gbk来进行操作,即执行

"SELECT * FROM test WHERE name = 'xxx' or 1=1 /* LIMIT 1";从而注入成功

 

解决方案:使用mysql_set_character_set函数来设置字符集。​

查看更多关于MYSQL PDO宽字符SQL注入深入分析 - 网站安全 - 自学的详细内容...

  阅读:47次