0X01 SSH的建立
我想,第一步先实现简单的ssh通信再说,类似其他那种高端的C&C将逐步研究
对于ssh,python有个module叫paramiko,对没错看起来像日语单词
The introductions of some modules are as follow:
1、SSHClient类
SHClient类是SSH服务会话的高级表示,封装了传输、通道以及SFTPClient的校验、建立方法,通常用于执行命令。
1)connect方法
connect(self,hostname,port=22,username=None,password=None,pkey=None,key_filename=None,timeout=None,allow_agent=True,look_for_keys=True,compress=False)
参数说明:
hostname:连接目标的主机地址
port:连接目录的端口,默认为22
username:用户名
password:密码
pkey:私钥方式用户验证
key_filename:私钥文件名
timeout:连接超时时间
allow_agent:是否允许使用ssh代理
look_for_keys:是否允许搜索私钥文件
compress:打开时是否压缩
2)exec_command方法
exec_command(self,command,bufsize=-1)
参数说明:
command:执行的的指令
bufsize:文件缓冲区大小,-1不限制
3)load_system_host_keys方法
load_system_host_keys(self,filename=None)
参数说明:
filename:指定远程主机的公钥文件,默认为.ssh目录下的known_hosts文件
4)set_missing_host_key_policy方法
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
参数说明:
AutoAddPolicy:自动添加主机名及密钥到本地并保存,不依赖load_system_host_keys()配置,即如果known_hosts里没有远程主机的公钥时,默认连接会提示yes/no,自动yes
RejectPolicy:自动拒绝未知主机名和密钥,依赖load_system_host_keys()
WarnningPlicy:功能与AutoAddPolicy相同,但是未知主机会提示yes/no
2、SFTPClient类
根据SSH传输协议的sftp会话,实现远程文件上传、下载等操作。
1)from_transport方法
classmethod from_transport(cls,t)
参数说明:
t:一个已通过验证的传输对象
示例:
>>> import paramiko >>> a = paramiko.Transport((“127.0.0.1″,2222)) >>> a.connect(username=”root”, password=’123456′) >>> sftp = paramiko.SFTPClient.from_transport(a)
2)put方法
put(self,localpath,remotepath,callback=None,confirm=True)
参数说明:
localpath:上传源文件的本地路径
remotepath:目标路径
callback:获取接收与总传输字节数
confirm:上传完毕后是否调用stat()方法,以便确认文件大小
示例:
>>> localpath=’ftp-test.log’ >>> remotepath=’/data/ftp-test.log’ >>> sftp.put(localpath,remotepath)
3)get方法
get(self, remotepath, localpath, callback=None)
参数说明:
remotepath:需要下载的远程文件
localpath:本地存储路径
callback:同put方法
4)其他方法
mkdir:用于创建目录
remove:删除目录
rename:重命名
stat:获取文件信息
listdir:获取目录列表
了解完模块,我们先尝试实现一下连接ss
h
import paramiko
import datetime import os hostname = "47.10.84." port=22 username = "root" password = "" ssh = paramiko.SSHClient() #创建一个ssh连接 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #目的是接受不在本地已知主机文件下的主机。missing host key很明显可以看出是指在丢失主机密钥的情况下做出什么动作,AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。
ssh.connect(hostname=hostname,port=22,username=username,password=password) stdin,stdout,stderr = ssh.exec_command('ls') #传送指令 res,err = stdout.read(),stderr.read() result = res if res else err print(result) ssh.close()
很不幸的是,这种方式只能分次传送指令,下面我介绍一下另一种方式——transport
transport = paramiko.Transport(('z',22)) transport.connect(username=username, password=password) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df -h') stdin1, stdout1, stderr1 = ssh.exec_command('ls') print(stdout.read().decode('utf-8')) print(stdout1.read().decode('utf-8')) transport.close()
这个亚子就很舒服了
那我们开始尝试上传文件
import paramiko import datetime import os import paramiko def sftp_upload_file(server_path, local_path): try: t = paramiko.Transport((hostname, 22)) t.connect(username=username, password=password) #创建一个transport连接 sftp = paramiko.SFTPClient.from_transport(t) #在transport基础上打开SFTP连接 sftp.put(local_path, server_path,confirm=True) ssh = paramiko.SSHClient() ssh._transport = t stdin, stdout, stderr = ssh.exec_command("ls ") #上传完成后显示命令 print(stdout.read().decode('utf-8')) t.close() except : print("error") if __name__ == '__main__': sftp_upload_file("/xxx.py", "D:\\bug.py")
but...不具备实用性,于是我加入了点目录遍历:
def sftp_upload_file(server_path,host_file_path): try: t = paramiko.Transport((hostname, 22)) t.connect(username=username, password=password) local_path = "" sftp = paramiko.SFTPClient.from_transport(t) for root, dir, files in os.walk(host_file_path): for i in files: local_path = host_file_path+"\\"+i print(local_path) server_path1 = server_path + "/"+i print(server_path) sftp.put(local_path, server_path1,confirm=True) ssh = paramiko.SSHClient() ssh._transport = t stdin, stdout, stderr = ssh.exec_command("ls -a ") print(stdout.read().decode('utf-8')) t.close() except : print("error")
结果如下:
哎嗨图没了,算了懒得上传了,未完待续,随心更新