Python编写SSH暴力破解脚本获密码后无法保留远程SSH Shell求助
解决SSH登录脚本无法保留交互式Shell的问题
嘿,这个问题我之前折腾过好一阵!你的脚本能成功验证密码,说明登录握手没问题,但没法保留Shell的核心原因是:你只完成了SSH的身份验证,却没有启动交互式会话并把本地终端的输入输出和远程Shell绑定起来。下面给你两种常用的解决方案:
方案一:用Paramiko库(纯Python实现)
如果你用的是Paramiko(最流行的Python SSH库),别只停留在connect()那一步,登录成功后要调用invoke_shell()启动交互式Shell,然后实时处理输入输出:
import paramiko import sys import select def ssh_interactive_login(host, username, password): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # 完成身份验证 ssh.connect(host, username=username, password=password, timeout=5) print(f"✅ 登录成功!密码:{password}") # 启动交互式Shell shell = ssh.invoke_shell() # 设置终端尺寸,避免远程命令输出排版错乱 shell.send("stty rows 40 columns 120\n") # 实时交互循环:同时监听远程输出和本地输入 while True: # 检查远程Shell是否有输出 if shell.recv_ready(): output = shell.recv(1024).decode() sys.stdout.write(output) sys.stdout.flush() # 检查本地是否有输入(非阻塞) if sys.stdin in select.select([sys.stdin], [], [], 0)[0]: user_input = sys.stdin.readline() shell.send(user_input) ssh.close() except paramiko.AuthenticationException: print(f"❌ 密码错误:{password}") except Exception as e: print(f"⚠️ 连接异常:{str(e)}") # 替换成你的目标IP、用户名和找到的密码 ssh_interactive_login("192.168.1.100", "root", "your_found_password")
为什么之前的方法没用?
- 只移除
sys.exit(0)但没处理IO:远程Shell的输出会堆积在缓冲区,本地输入也传不到远程,程序会卡住不动; - 用
exec_command():这是执行一次性命令的接口,不是交互式Shell,执行完命令会话就结束了。
方案二:用Subprocess调用系统SSH命令(依赖系统工具)
如果你更倾向于用系统原生的ssh命令,需要配合sshpass(用来传递密码,避免手动输入),并绑定终端IO:
import subprocess import threading def ssh_with_system_cmd(host, username, password): # 先确保已安装sshpass(Ubuntu/Debian:sudo apt install sshpass;CentOS:yum install sshpass) cmd = [ "sshpass", "-p", password, "ssh", "-o", "StrictHostKeyChecking=no", # 跳过主机密钥验证(测试场景用) f"{username}@{host}" ] # 启动SSH进程,绑定输入输出 proc = subprocess.Popen( cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True ) # 单独开线程读取远程输出,避免阻塞 def print_output(): for line in iter(proc.stdout.readline, ''): print(line, end='') threading.Thread(target=print_output, daemon=True).start() # 处理本地输入,发送给远程Shell while proc.poll() is None: try: user_input = input() proc.stdin.write(user_input + '\n') proc.stdin.flush() except EOFError: break # 调用示例 ssh_with_system_cmd("192.168.1.100", "root", "your_found_password")
注意事项
sshpass会把密码暴露在进程列表里,只适合测试环境;- 生产环境建议用密钥登录,避免明文密码传递。
核心思路就是:登录成功后,一定要建立双向的IO通道,让本地的键盘输入能传到远程,远程的命令输出能显示在本地终端,这样Shell才能持续保持交互状态。
内容的提问来源于stack exchange,提问作者user3479956
相关产品推荐
相关产品推荐

