文章目录
- 背景
- 示例
- 代码
- 代码解释
- 导入模块
- SSH服务器的地址和端口
- 用户名和密码列表
- 生成所有可能的用户名和密码组合
- 尝试连接到SSH服务器并验证用户名和密码
- 遍历并测试每一对凭证
背景
我们华为摄像头linux终端的密码忘了,还不太好初始化,手动一个个测试太麻烦,所以实现了个python代码,用来自动测试用户密码是否能登录。
示例
代码
import paramiko
import time
'''
这个脚本会对每个组合尝试两次连接(这通过 retries=2 参数控制)。
如果遇到认证错误,它将立即中断当前组合的尝试并继续到下一个组合,因为再次尝试相同的错误密码没有实际意义。
对于其他类型的连接失败(如网络问题),如果第一次失败,它将等待一秒钟后再尝试一次。
'''
# SSH 服务器的地址和端口
ssh_host = '192.168.1.81'
ssh_port = 22
# 用户名列表
usernames = ['root',
'admin',
'ApiAdmin']
# 密码列表
passwords = ['123',
'HuaWei123',
'ChangeMe123',
'abc12345',
'aa123456',
'admin']
# 生成所有可能的用户名和密码组合
credentials = [(user, pwd) for user in usernames for pwd in passwords]
# 尝试连接到 SSH 服务器并验证用户名和密码
def try_login(host, port, username, password, retries=3):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for attempt in range(1, retries + 1):
try:
print(
f"尝试连接: {host}:{port} 用户名 '{username}' 和密码 '{password}' (尝试次数: {attempt})")
client.connect(host, port=port, username=username,
password=password, timeout=10)
# 如果连接成功,返回 True
print(
f"成功连接到 {host}:{port} - 用户名 '{username}' 和密码 '{password}' 是有效的!")
return True
except paramiko.AuthenticationException:
# 如果认证失败(即密码错误),直接返回 False
print(f"认证失败: {host}:{port} - 用户名 '{username}' 和密码 '{password}'")
return False
except paramiko.SSHException as e:
# 如果连接失败(非认证失败),打印错误并重试
print(f"连接失败: {host}:{port} - 重试中... (错误: {e})")
time.sleep(1) # 稍微等待一下,避免立即重连
finally:
client.close()
print(
f"最终失败: {host}:{port} - 用户名 '{username}' 和密码 '{password}' 在多次尝试后仍无法连接。")
return False
# 遍历并测试每一对凭证
for username, password in credentials:
print('========开始尝试新的凭证组合========')
try_login(ssh_host, ssh_port, username, password)
# 注意,这里的重试可能不是必要的,因为 try_login 已经包括了重试逻辑
try_login(ssh_host, ssh_port, username, password)
print('========结束当前凭证组合的尝试========')
代码解释
这段代码的目的是通过SSH协议尝试连接到指定的服务器,使用提供的用户名和密码组合列表进行身份验证。它适用于需要验证多个凭据对有效性的场景,比如在你有一个用户名和密码列表,需要检查哪些能够成功登录到SSH服务器。下面我将逐部分解释代码的功能:
导入模块
import paramiko
import time
paramiko
:这是一个Python实现的SSHv2协议库,用于创建SSH连接,执行远程命令,传输文件等。time
:用于实现等待(延迟)的功能,特别是在重连尝试中。
SSH服务器的地址和端口
ssh_host = '192.168.2.112'
ssh_port = 22
这里定义了SSH服务器的IP地址和端口号。'192.168.2.112'
是SSH服务器的IP地址,22
是SSH协议的默认端口号。
用户名和密码列表
# 用户名列表
usernames = ['root',
'admin',
'ApiAdmin']
# 密码列表
passwords = ['123',
'HuaWei123',
'ChangeMe123',
'abc12345',
'aa123456',
'admin']
这两个列表分别包含了要尝试的用户名和密码。代码将遍历这些列表,为每个用户名尝试所有密码。
生成所有可能的用户名和密码组合
credentials = [(user, pwd) for user in usernames for pwd in passwords]
使用列表推导式生成用户名和密码的所有可能组合,结果是一个包含元组的列表,每个元组包含一对用户名和密码。
尝试连接到SSH服务器并验证用户名和密码
def try_login(host, port, username, password, retries=3):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for attempt in range(1, retries + 1):
try:
print(f"尝试连接: 用户名 '{username}' 和密码 '{password}' (尝试次数: {attempt})")
client.connect(host, port=port, username=username,
password=password, timeout=10)
# 如果连接成功,返回 True
print(f"成功: 用户名 '{username}' 和密码 '{password}' 是有效的!")
return True
except paramiko.AuthenticationException:
# 如果认证失败(即密码错误),直接返回 False
print(f"认证失败: 用户名 '{username}' 和密码 '{password}'")
return False
except paramiko.SSHException as e:
# 如果连接失败(非认证失败),打印错误并重试
print(f"连接失败,重试中... (错误: {e})")
time.sleep(1) # 稍微等待一下,避免立即重连
finally:
client.close()
print(f"最终失败: 用户名 '{username}' 和密码 '{password}' 在多次尝试后仍无法连接。")
return False
这个函数尝试使用提供的用户名和密码通过SSH连接到服务器。如果连接成功,它会打印一条成功消息并返回True
。连接尝试默认最多重试3次(通过retries
参数控制)。
-
设置SSH客户端:首先,创建一个
paramiko.SSHClient
实例,并设置一个策略来自动接受未知的SSH密钥(对于自动化任务通常是可接受的)。 -
尝试连接:使用
client.connect()
方法尝试连接到服务器。如果连接成功,打印成功消息并返回True
。 -
处理异常:
AuthenticationException
:如果遇到认证失败(密码错误),打印一条消息并返回False
。SSHException
:如果因其他原因连接失败(如网络问题),打印错误消息并等待1秒后重试,直到达到重试次数限制。
-
关闭连接:无论成功与否,最后都关闭SSH连接。
遍历并测试每一对凭证
for username, password in credentials:
print('========start========')
try_login(ssh_host, ssh_port, username, password)
try_login(ssh_host, ssh_port, username, password)
print('========end========')
这部分代码遍历之前生成的用户名和密码组合,对每一对凭证尝试连接两次。每次尝试之前和之后都有打印消息,以标示尝试的开始和结束。
注意,此代码实际上会对每个凭证组合尝试四次连接(每个组合两次尝试,循环两遍),这可能不是预期的行为(主要是因为手动登录的时候,错误三次将会提示重新尝试,担心这个,所以每个组合尝试登录两次)。如果目的是对每个组合仅尝试两次,应将内部的两次try_login
调用合并为一次,并确保try_login
函数内部逻辑正确处理重试。
成功测试出服务器密码: