CTFshow-sql注入---弱类型转换

  //拼接sql语句查找指定ID用户
  $sql = "select pass from ctfshow_user where username = {$username}";
      
//返回逻辑


  //用户名检测
  if(preg_match('/and|or|select|from|where|union|join|sleep|benchmark|,|\(|\)|\'|\"/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==intval($password)){
      $ret['msg']='登陆成功';
      array_push($ret['data'], array('flag'=>$flag));
    }

payload:username=0&pass=0

为什么?

pass是密码比较为弱类型,字符串会转换为0
username为什么等于0?(问得好,我也不知道,等我我问问我女朋友,emmm算了我好像没有)
百度大法启动!!!(具体可看mysql隐式转换)

MySql隐式转换 以下规则描述比较操作的转换方式:

如果一个或两个参数都为空,则比较结果为空,但空安全<=>相等比较运算符除外。对于空值<=>空值,结果为真。不需要转换。

如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。

如果两个参数都是整数,则将它们作为整数进行比较。

如果不与数字进行比较,十六进制值将被视为二进制字符串。

如果其中一个参数是timestamp或datetime列,而另一个参数是常量,则在执行比较之前,该常量将转换为timestamp。这样做是为了更好地支持ODBC。注意,这不是为in()中的参数所做的!为了安全起见,在进行比较时始终使用完整的日期时间、日期或时间字符串。例如,要在与日期或时间值之间使用时获得最佳结果,请使用cast()将值显式转换为所需的数据类型。

如果其中一个参数是十进制值,则比较取决于另一个参数。如果另一个参数是十进制或整数值,则将这些参数作为十进制值进行比较;如果另一个参数是浮点值,则将这些参数作为浮点值进行比较。

在所有其他情况下,参数都是作为浮点数(实数)进行比较的。

看完上面的,你是不是什么都没看懂,以后可分为三种情况,这种情况属于第三种,作为浮点数进行比较 把字符串和0都转为浮点数,字符串会转换失败(并不是所有字符串都会转成0 eg:1huahua转换浮点数为1.00),变成0,结果就成了0=0。 就会列出0=0的数据。
ojbk就到这里。

你可能感兴趣的:(CTF)