什么是撞库?
撞库是一种网络攻击手段,攻击者通过收集已泄露的用户名和密码信息,尝试在其他网站或服务上登录,以获取用户的账户权限。由于许多用户在不同网站上使用相同的密码,这使得撞库攻击变得尤为有效。
一些常见的撞库方法
-
使用密码字典撞多个账号:
- 攻击者创建一个包含可能密码的列表(密码字典),然后使用这个列表对大量账号进行尝试登录。
- 如果用户在不同网站上使用相同的密码,攻击者就有可能成功登录。
-
使用少数密码尝试撞多个账号:
- 攻击者可能只使用几个常见的密码(如“123456”、“password”等)去尝试登录大量账号。
- 这种方法依赖于大量用户使用简单或常见密码的事实。
-
使用泄露的凭证信息:
- 如果攻击者能够从其他网站或数据泄露事件中获得用户的凭证信息,他们会使用这些凭证在其他网站上尝试登录。
-
自动化脚本和工具:
- 攻击者使用自动化脚本和工具来执行撞库攻击,这些工具可以快速地对大量账号进行登录尝试。
-
利用API漏洞:
- 如果网站的API存在安全漏洞,攻击者可能会利用这些漏洞来执行撞库攻击,通过API提交登录请求。
-
使用代理IP和VPN:
- 为了规避IP被封禁的风险,攻击者可能会使用代理IP或VPN来隐藏自己的真实IP地址。
-
利用验证码绕过机制:
- 有些攻击者会尝试绕过或自动化解决验证码,以继续进行撞库攻击。
-
利用社工库:
- 社工库是黑客用来记录攻击手段和方法的数据库,其中可能包含大量用户信息,攻击者利用这些信息进行撞库。
-
彩虹表和时间-记忆-数据权衡攻击:
- 彩虹表是一种预先计算好的密码哈希值表,可以快速匹配密码哈希,而时间-记忆-数据权衡攻击则是在彩虹表的基础上进一步优化存储和查询效率。
应对撞库的加盐方法
为了应对撞库攻击,我们可以采用"加盐"(Salting)的方法。加盐是一种密码存储技术,通过在密码上添加随机数据,使得即使两个用户使用相同的密码,存储的密码哈希值也不同。
加盐的步骤
- 生成盐:为每个用户生成一个唯一的随机盐值。
- 密码与盐的组合:将用户的密码与盐值进行组合。
- 哈希处理:对组合后的字符串进行哈希处理,生成密码哈希值。
- 存储:将盐值和哈希值一起存储在数据库中。
Python实现加盐
来,给个登录程序,展示如何实现加盐过程(其中还使用getpass来隐藏密码):
import os
import hashlib
import getpass
# 全局变量,存储盐值
SALT = os.urandom(16) # 生成一个16字节的随机盐值
def hash_password(password, salt):
"""使用盐值对密码进行哈希处理"""
password_salt = password.encode('utf-8') + salt
hash_obj = hashlib.sha256(password_salt)
hashed_password = hash_obj.hexdigest()
return hashed_password, salt
def save_user_data(username, hashed_password, salt):
"""将用户名、哈希密码和盐值保存到文件"""
with open('user_data.txt', 'a') as file:
file.write(f"{username},{hashed_password},{salt.hex()}\n")
def register():
"""注册用户功能"""
username = input("请输入用户名: ")
password = getpass.getpass("请输入密码: ") # 使用getpass隐藏密码输入
hashed_password, salt = hash_password(password, SALT)
save_user_data(username, hashed_password, salt)
print("注册成功!")
def login():
"""用户登录验证功能"""
username = input("请输入用户名: ")
password = getpass.getpass("请输入密码: ")
user_found = False
try:
with open('user_data.txt', 'r') as file:
for line in file:
stored_username, stored_hash, stored_salt = line.strip().split(',')
if stored_username == username:
hashed_password, _ = hash_password(password, bytes.fromhex(stored_salt))
if hashed_password == stored_hash:
print("登录成功")
user_found = True
break
except FileNotFoundError:
print("用户数据文件不存在")
if not user_found:
print("用户名或密码错误")
def main():
"""主函数,提供用户选择注册或登录"""
while True:
print("\n请选择操作:")
print("1. 注册")
print("2. 登录")
print("3. 退出")
choice = input("请输入选项(1-3): ")
if choice == '1':
register()
elif choice == '2':
login()
elif choice == '3':
print("退出程序。")
break
else:
print("无效的输入,请重新选择。")
if __name__ == "__main__":
main()