一个由Mysql特性引起的php验证漏洞

某php+mysql系统,mysql数据库中有个user表,其中有个code字段,类型是int(11),这个字段是保存一个随机数,用来找回密码的时候做验证,默认值是0。 
  找回密码时候的步骤是,首先填写自己邮箱,接收重置密码的邮件,点击链接,访问如下代码: 
if (!empty($_GET[‘email‘]) && !empty($_GET[‘code‘])) 

    if (!$db->count(‘user‘,"email=‘{$_GET[‘email‘]}‘ AND code=‘{$_GET[‘code‘]}‘")) 
        die(‘error‘); 
    $_SESSION[‘email‘] = $_GET[‘email‘]; 
    ... 
}

  在数据库中查找email=$_GET[‘email‘]并且code=$_GET[‘code‘]的行数,如果行数为0则die出去,否则设置$_SESSION[‘email‘] = $_GET[‘email‘] ,最后就以$_SESSION[‘email‘]内存储的邮箱重置密码。 
  看似似乎没问题,只有当email为你的email,并且你知道他的随机code的时候,才能不die,才能获得$_SESSION[‘email‘]。 
但关键问题就是:code的默认值是0,也就是说所有用户只要没有重置过密码,他的code就是0,所以等于说我知道了所有用户的code,那我不就可以重置所有用户的密码了吗? 
  不不,等下,我们看到这行代码:

if (!empty($_GET[‘email‘]) && !empty($_GET[‘code‘]))

  必须要!empty($_GET[‘code‘])的时候,才可能进入这个if语句。熟悉php的人都知道,empty(0)是返回真的。所以说,如果$_GET[‘code‘]=0的话,根本进不来这个if语句。 那怎么办?

  这又涉及到mysql一个tip,很容易犯错的点——code这个字段的类型是整型int(11),而在mysql里面,当字段类型为整型、where语句中的值不为整型的时候,会被转换成整型才放入查询。也就是说,如果where code=‘xxx‘中xxx不为整型的话,则会先将xxx转换成整数,才放入查询。 
  也就是说,如果我们传入的字符串为0aaa,则会转换成0,再执行。

select count(*) from `user` where `id`=‘0‘;

select count(*) from `user` where `id`=‘0a‘;

  以上得到的结果都是1。

  所以通过这个tip,就可以绕过if (!empty($_GET[‘email‘]) && !empty($_GET[‘code‘])),只要我们传入的$_GET[‘code‘]=0xxx,就可以进入if语句,并且让select count(*)语句返回1,最后找回任意用户密码,不需要爆破。

时间: 2024-07-28 21:12:01

一个由Mysql特性引起的php验证漏洞的相关文章

[转]Infobright是一个与MySQL集成的开源数据仓库

[文章作者:张宴 本文版本:v1.1 最后修改:2010.05.18 转载请注明原文链接:http://blog.zyan.cc/infobright/] Infobright是一个与MySQL集成的开源数据仓库(Data Warehouse)软件,可作为MySQL的一个存储引擎来使用,SELECT查询与普通MySQL无区别. 一.Infobright的基本特征: 优点: 查询性能高:百万.千万.亿级记录数条件下,同等的SELECT查询语句,速度比MyISAM.InnoDB等普通的MySQL存储

PHP框架Swoole的一个定时器Timer特性

在各种业务型系统中,往往需要服务器在后台扫描相关数据,触发相应的统计.通知等操作. 比如对于一个项目管理系统,需要每天的特定时间内,统计每项任务的执行.到期情况.整个项目的进度等等,根据统计情况,做相应通知处理: 这样一个场景,如何编程实现? 用一般的编程方式,是无法实现自动触发与统计的.当然,简单的思路,是利于系统的cron job机制.但这种方式,对于配置及可靠性方面,需要比较多的人为操作因素. Swoole是一个使用c开发的php扩展,通过php就可以实现高性能web服务器,同时,还内置了

【原创】贡献一个项目中用到的js身份证验证-超级准!!!

前言 首先贡献一个大神的链接:js验证身份证超准 代码 function checkIdcard(idcard) { var Errors = new Array( "验证通过!", "身份证号码位数不对!", "身份证号码出生日期超出范围或含有非法字符!", "身份证号码校验错误!", "身份证地区非法!" ); var area = { 11: "北京", 12: "天津&

改进身份验证漏洞扫描的五个步骤

你无法保护你不知道的东西.虽然这并不是IT安全领域的咒语,但当你从"可信"用户的角度寻找安全漏洞,或者换句话说,通过身份验证执行漏洞扫描时,这个原则确实是真的. 通过配置漏洞扫描仪来登录到你正在测试的主机,你会看到这个故事的其余部分--即为了节省时间或金钱,或者因为复杂性而经常被忽略的安全方面.事实的真相是,尽管执行身份验证扫描确实需要更多的时间,但从发现的漏洞(以及最终缓解的风险)来看,这种漏洞扫描比通过非身份验证扫描的效果好十倍. 安全团队可以遵循下面五种方法来更有效地准备和执行身

MySQL服务端读取客户端的漏洞

一个adminer如下 看到这个页面尝试弱口令登陆无果,想起了前段时间做的MySQL服务端读取客户端的漏洞poc: https://github.com/allyshka/Rogue-MySql-Server 在服务端监听后,使用adminer连接服务端 起初读/etc/passwd ,报错显示为opendir的关系,于是读取web文件, 于是读取 /data01/htdocs/m.php文件成功读取由于已经发现有config.php,于是读取config.php 发现mysql配置文件,得到m

从偶然的机会发现一个mysql特性到wooyun waf绕过题

MayIKissYou | 2015-06-19 12:00 最近在测试的时候,偶然的机会发现了一个mysql的特性, 为啥是偶然的机会呢..... 一次测试的过程中我在mysql的console下做了如下的操作: 看出些什么了么? 我当时发现报错的时候例如-+{等符号 报错的时候提示的是''(双引号里没东西),但是如select后面添加1 a等内容的时候报的是 selecta,select1等等. 想到共性了么,-+{等等内容是能够直接添加到select后面的,知其那那个sql总结的帖子里有,

ASP.NET MVC 使用Remote特性实现远程属性验证

RemoteAttribute是asp.net mvc 的一个验证特性,它位于System.Web.Mvc命名空间 下面通过例子来说明 很多系统中都有会员这个功能,会员在前台注册时,用户名不能与现有的用户名重复,还要求输入手机号码去注册,同时手机号码也需要验证是否重复,下面是实体类 /// <summary> /// 会员 /// </summary> public class Member { public int Id { get; set; } [Required(Error

Innodb_buffer_pool_pages_dirty [一个故事@MySQL DBA]MYSQL

http://www.orczhou.com/index.php/2010/12/more-about-mysql-innodb-shutdown/http://www.orczhou.com/index.php/2014/03/some-tricky-about-mysqladmin-extended-status/https://dbarobin.com/2015/08/29/mysql-optimization-under-ssd/https://www.percona.com/blog/

.NET技术-1.0.使用反射、特性简化代码(验证Model类)

使用反射.特性简化代码 参考项目:利用反射验证Model类/AssemblyVerification 假设现在有一个学生类(Student) /// <summary> /// 学生类 /// </summary> public class Student { /// <summary> /// 名字 /// </summary> private string name; public string Name { get { return name; } s