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
输出结果: