前言
最近翻出了一个多年前写的 Web 老项目,需要再次启用该项目做一些事情。项目顺利启动了,却在登录页面前卡住了——管理员密码早忘得一干二净。
没有找回密码功能,数据库里的密码又是哈希存储的,暴力破解不现实。正巧的是之前群里有相关讨论的记录
“你就不能安装一下,在设置管理员密码的时候把数据库的盐和哈希复制出来,然后塞到替换掉现在的数据库哈希和盐,不就换成自己的密码了。”
附上截图:
于是就有了这次“偷梁换柱”式密码重置的实战记录。
思路分析
大多数 Web 应用的密码存储逻辑是这样的:
- 用户注册/设置密码时,系统生成一个随机盐值(Salt)
- 将 密码明文 + 盐值 进行哈希运算,得到密码哈希(Hash)
- 把 盐值 和 哈希值 一起存入数据库
- 登录验证时,用同样的算法对输入密码和数据库中取出的盐值进行哈希,对比结果即可。
核心思路:
既然无法从哈希反推出明文,那就反过来——用一套我已知明文的“盐+哈希”凭证,直接覆盖掉数据库中旧的凭证。这样我就能用自己设定的密码登录了。
具体操作步骤
第一步:搭建一套全新的临时环境
在本地重新安装一份完全相同版本的项目源码,走一遍全新安装流程。在设置管理员密码这一步,我输入了一个绝对不会忘记的密码,比如 123456。
用小皮这种快速部署一个
第二步:获取新密码的盐和哈希
安装完成后,立即进入数据库,查看用户表(通常是 users 或 admin 表),找到刚创建的管理员记录:
SELECT username, password_hash, salt FROM users WHERE username = 'admin';记下这条记录中的 password_hash 和 salt 值,这就是我们已知明文密码对应的凭证对。
当然也可以直接导出为sql文件去里面查找就行
第三步:替换旧项目的数据库凭证
连接到旧项目的数据库,执行更新操作:
UPDATE users
SET password_hash = '新获取的哈希值',
salt = '新获取的盐值'
WHERE username = 'admin';
注意: 表名、字段名需根据实际项目调整。第四步:验证登录
用 123456 这个密码登录旧项目,成功进入后台!
整个操作耗时不超过 5 分钟,困扰已久的密码问题就这样被“狸猫换太子”给解决了。
这个方案为什么能成功?
密码算法一致:新旧项目使用完全相同的哈希算法和盐值处理逻辑
凭证对完全匹配:新生成的盐和哈希,与密码明文是配套的,验证必然通过
数据库直接读写权限:有权限直接操作数据库,才能完成替换
本质上,就是把“新用户注册时该发生的事情”,手动在数据库里模拟了一遍。
总结
这次“硬改”密码的经历,其实暴露了同时也是利用了几个事实:
- 懂原理才知道怎么绕路——密码存储和验证的机制,既是保护,也可以被合法利用来恢复访问
- 源码面前没有秘密——能看代码就有无数种方法让自己重获权限
- 直接操作数据库是最高权限——数据库层一旦可写,应用层的一切限制都不存在
最后还得感谢那句灵感来源的话,有时候解决问题的关键不是硬碰硬地破解,而是换个角度“偷梁换柱”。这也算是开发者对自己项目拥有“超级权限”的一种体现吧。
评论0
暂时没有评论