zoukankan      html  css  js  c++  java
  • 网页闯关游戏(riddle webgame)--SQL注入的潘多拉魔盒

    前言:
      之前编写了一个网页闯关游戏(类似Riddle Game), 除了希望大家能够体验一下我的游戏外. 也愿意分享编写这个网页游戏过程中, 学到的一些知识.
      web开发初学者往往会忽视一些常见的漏洞, 比如SQL注入攻击, XSS攻击. 本文将简述SQL注入攻击的原理, 并分享下关卡设计, 其在打开潘多拉魔盒的情况下, 又能很好地限制危害.

    效果展示:
      先打下广告: 网页闯关游戏入口(请狠狠地点击我, ^_^).
      本文的想法实施于第十一关--健忘的教授.
      
      很直接的呈现一个登陆对话框, 考验玩家能否借助非常规的方式来绕开登陆验证.

    SQL注入攻击:
      虽然SQL注入攻击已是老生常谈, 不过还是得唠叨几句"科普"一下, ^_^.
      应用程序再获取到用户提交的数据后, 有些会进行SQL语句的拼接并执行. 倘若用户提交的数据中包含SQL执行命令, 同时程序并没有对数据进行过滤和安全验证. 这样就有可能绕过验证并获取数据, 甚至注入恶意代码, 导致数据被篡改, 丢失.
      • 以用户登录为例
      服务的用户数据模型如下:

    table tb_user (
      username varchar(32),
      password varchar(32)
    );

      服务的登陆验证SQL如下:

    SELECT * FROM tb_user WHERE username = '?' AND password = '?';

      登陆的输入框入图所示:
      
      其对应的form表单为:

    <form method="post">
      用户名: <input name="username" />
      密码: <input name="password" type="password"/>
    </form>

      hacker只要在form表单中, 巧妙设计字段内容, 注入sql执行命令, 以绕过数据验证.
      比如username字段, 填写为: ' or 1 = 1 #.
      这样服务器端, 最终拼接的SQL为:

    SELECT * FROM tb_user WHERE username = '' or 1 = 1 #' AND password= '?'

      由于字符'#'在SQL规范中, 表示注释, '#'字符后直到行尾的所有字符都将被忽略掉.
      因此最终的SQL等价于如下:

    SELECT * FROM tb_user WHERE username = '' or 1 = 1

      用户数据将被返回, 如果尝试登录的是管理员后台, 那hacker将轻松获取到管理员的权限, 这非常的可怕.
      魔高一丈道高一尺, 既然知道SQL注入的攻击原理是什么? 那么防范措施就有针对性了, 千万不要相信用户提交的数据, 做好过滤和验证.

    关卡设计:
      本关就是来考察玩家对SQL注入的认知功底. 因此模拟构建了一个登陆窗口, 接受开放式的答案.
      如何对答案进行验证呢? 1). 模拟SQL的执行解析. 2). 直接跑真实的SQL.
      对于方案一, 工作量大, 多个SQL命令需要支持, 有可能覆盖不全所有的解, 有点得不偿失.
      对于方案二, 容易实现, 但是给系统带来了潜在风险, 比如注入drop tables等危险的命令.
      权衡比较, 还是采用第二种方案, 至于风险控制亦可控.
      服务程序是采用Java来编写的, 若要放开SQL注入漏洞限定, 那就不能使用mybatis/hibernate这些ORM框架, 因为这些框架已经帮我们做了escape数据的工作.
      让我们回到石器时代, 直接裸用jdbc来实现, 代码如下:

    /**
    *
    * 构造经典的SQL注入攻击
    * @param username 用户输入的用户名
    * @param password 用户输入的密码
    * @return
    */
    public boolean verifySQLInject(String username, String password) {
    
      Connection connection = null;
    
      try {
        // *) 动态载入Mysql Driver驱动类
        Class.forName("com.mysql.jdbc.Driver");
    
        // *) 获取 DB Connection
        connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
    
        Statement stmt = connection.createStatement();
    
        String sql = String.format(
                  "SELECT * " +
                  "FROM tb_virtual_user " +
                  "WHERE username = '%s' AND password = '%s'",
                  username, password
          );
        ResultSet rs = stmt.executeQuery(sql);
        if ( rs.next() ) {
          stmt.close();
    
          // *) 登陆成功
          return true;
        }
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (SQLException e) {
        e.printStackTrace();
      } finally {
        if ( connection != null ) {
          try {
            connection.close();
          } catch (SQLException e) {
            // e.printStackTrace();
          }
        }
      }
      return false;
    
    }

      注: 该代码确切地执行了用户登录的SQL语句, 常规登录和非法sql注入构造都将返回失败.
      同时正如前文所提到的, 为了验证SQL注入攻击, 从而放弃数据验证和过滤. 万一有人不是用于解题, 而是专门搞破坏怎么办? 犹如自己给自己埋了个炸弹, 你永远不知道它什么时候爆炸.
      事实上, 这是多虑的. 我们可以创建两个mysql账号, 一个专门用于sql注入验证(只授予select权限), 而剩下则用于其他的业务数据. 这样就轻松做到隔离, 且十分安全.

    GRANT USAGE ON *.* TO 'game1001'@'localhost' IDENTIFIED BY PASSWORD '*25A2CD7698FEED80089150F089755D752423A821';
    GRANT SELECT ON `db_gameweb`.`tb_virtual_user` TO 'game1001'@'localhost';

      比如创建账号game1001, 它只被授予对tb_virtual_user表的只读权限.
      这样服务就能允许sql注入存在, 但这些sql注入不具攻击性.

    后记:
      其实对该题, 我还是很满意的. 我一直希望能构建类似的题, 寓教于乐. 就当自己一个以后奋斗的方向吧! 与君共勉.

    公众号&游戏站点:
      个人微信公众号: 木目的H5游戏世界
      
      个人游戏作品集站点(尚在建设中...): www.mmxfgame.com,  也可直接ip访问http://120.26.221.54/.

  • 相关阅读:
    利用Python来远程控制肉鸡自由操作,下一个黑客大佬就是你
    利用Python来远程控制肉鸡自由操作,下一个黑客大佬就是你
    职场效率及注意点,数据领域职业选择有哪些
    职场效率及注意点,数据领域职业选择有哪些
    大数据的挑战:数据质量和历史偏见
    IP地址格式转换(htonl、ntohl;inet_addr、inet_ntoa)
    ubuntu 查看软件安装目录以及安装版本
    C++11 POD类型
    C++11 static_assert
    localtime 和 localtime_r
  • 原文地址:https://www.cnblogs.com/mumuxinfei/p/5203763.html
Copyright © 2011-2022 走看看