import argparse import paramiko # 定义一个名为Client的类,用于表示SSH客户端相关操作 class Client: # 类的初始化方法,接收主机地址、用户名和密码作为参数 def __init__(self, host, user, password): self.host = host self.user = user self.password = password # 创建一个paramiko的SSHClient实例,用于后续的SSH连接操作 self.client = paramiko.SSHClient() # 设置自动添加主机密钥策略,避免出现未知主机密钥时连接失败 self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 调用连接方法,尝试建立SSH连接 self.connect() # 定义连接方法,用于建立到指定主机的SSH连接 def connect(self): try: # 使用提供的主机、用户名和密码进行SSH连接 self.client.connect(self.host, username=self.user, password=self.password) print(f"[+] Connected to {self.host}") except Exception as e: print(f"[-] Error connecting to {self.host}: {e}") # 用于在已连接的SSH会话上执行命令,并返回命令的输出结果 def send_command(self, cmd): # 在SSH会话上执行命令,获取标准输入、标准输出和标准错误输出流 stdin, stdout, stderr = self.client.exec_command(cmd) # 读取标准输出内容,并使用utf-8编码将字节数据转换为字符串 output = stdout.read().decode('utf-8') # 读取标准错误输出内容,并进行同样的编码转换 error = stderr.read().decode('utf-8') if error: print(f"[-] Error executing command on {self.host}: {error}") return output # 类方法,用于向所有已添加到botNet列表中的客户端发送相同命令,并收集结果 @classmethod def botnet_command(cls, command): results = [] # 遍历botNet列表中的每个客户端实例 for client in cls.botNet: # 在每个客户端上执行命令,并获取输出结果 output = client.send_command(command) # 将客户端的主机地址和对应的命令输出结果作为元组添加到results列表中 results.append((client.host, output)) return results # 类方法,用于向botNet列表中添加一个新的客户端实例 @classmethod def add_client(cls, host, user, password): client = cls(host, user, password) cls.botNet.append(client) # 类方法,用于关闭所有已添加到botNet列表中的客户端的SSH连接 @classmethod def close_all_connections(cls): for client in cls.botNet: client.client.close() print(f"[+] Connection to {client.host} closed") # 初始化一个空的botNet列表,用于存储所有的客户端实例 Client.botNet = [] def main(): # 创建一个命令行参数解析器对象,用于解析用户输入的命令行参数 parser = argparse.ArgumentParser(description='SSH Botnet Client') # 添加一个名为--host的命令行参数,可接收多个值,用于指定要连接的主机地址 parser.add_argument('--host', nargs='+', help='Host(s) to connect to') # 添加一个名为--user的命令行参数,可接收多个值,用于指定SSH连接的用户名 parser.add_argument('--user', nargs='+', help='Username(s) for SSH connection') # 添加一个名为--password的命令行参数,可接收多个值,用于指定SSH连接的密码 parser.add_argument('--password', nargs='+', help='Password(s) for SSH connection') args = parser.parse_args() # 检查是否缺少必要的命令行参数,如果缺少则报错 if not args.host or not args.user or not args.password: parser.error('Missing required arguments') # 检查主机地址、用户名和密码的数量是否一致,如果不一致则报错 if len(args.host)!= len(args.user) or len(args.host)!= len(args.password): parser.error('The number of hosts, users, and passwords must be the same') # 通过循环,为每个主机地址、用户名和密码的组合创建一个Client实例,并添加到botNet列表中 for host, user, password in zip(args.host, args.user, args.password): Client.add_client(host, user, password) print("Connected to all hosts. Enter 'exit' to quit.") while True: command = input("Enter command: ") if command.lower() == 'exit': break results = Client.botnet_command(command) for host, output in results: print(f"Output from {host}:") print(output) # 关闭所有已添加的客户端的SSH连接 Client.close_all_connections() if __name__ == '__main__': main()
运行方法: 第一种:终端控制:python your_script.py --host IP1 IP2 --user user1 user2 --password password1 password2
输出结果: