Linux 您所在的位置:网站首页 passwd-stdin Linux

Linux

2023-05-25 14:14| 来源: 网络整理| 查看: 265

目录ParamikoSSH第一版第二版最终版SFTP第一版第二版

Paramiko

Paramiko官网

image-20230321084638027

image-20230321084921247

从官方的介绍当中我们起码得知以下几个信息:

此模块用于python3.6以上,目前python3.11左右,完全满足; 此模块用于实现sshv2协议的客户端和服务端; 核心类有五种,我们常用的是Client和SFTP两个类 SSH

接下来,我们通过paramiko实现通过sshv2连接服务器,并执行ip addr show然后从结果当中把IP地址通过python字符串切割的方式获取到。

实验环境:

服务端:192.168.80.130:kali linux 客户端:windows pycharm # 服务端基本配置 ┌──(root㉿kali)-[~/Desktop] └─# systemctl enable --now ssh root㉿kali)-[~/Desktop] └─# ss -tnlp | grep 22 LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1938,fd=3)) LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1938,fd=4)) ┌──(root㉿kali)-[~/Desktop] └─# grep -i "permitrootlogin" /etc/ssh/sshd_config PermitRootLogin yes ┌──(root㉿kali)-[~/Desktop] └─# systemctl restart ssh ┌──(root㉿kali)-[~/Desktop] └─# passwd New password: cba-123 Retype new password: cba-123 passwd: password updated successfully ┌──(root㉿kali)-[~/Desktop] └─# ip addr show eth0 | sed -n 3p | awk -F" " '{print $2}' | awk -F"/" '{print $1}' 192.168.3.19 ┌──(root㉿kali)-[~/Desktop] └─# hostname -I 192.168.3.19

在使用paramiko的过程当中我们可以选择通过shell命令进行切割字符串,也可以通过python进行切割,由于shelle命令只能在LINUX上执行,如果我们操作是网络设备那shell的命令不再好用了,所以我们打算使用python关于字符串的切割逻辑。

第一版

要求1:要求向linux发送一个df命令,并取回df的其结果。

要求2:要求向linux发送四个命令,并取会其结果

# 要求1 import paramiko,time port_number = 22 username = "root" password = "cba-123" ip= "192.168.80.130" # 调用paramiko的sshclient类进行实例化 ssh = paramiko.SSHClient() # 斩断ssh进程与文件系统之间的联系 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 这一步如果抓包去看的话,其实就是sshv2的连接过程 # tcp三次握手、协商版本、交换密钥……、完事后直接四次挥手并不保持连接直接挥手 ssh.connect( port=port_number, username=username, password=password, hostname=ip ) # 向ssh发送一个df命令,然后通过标准的输入、输出和错误接收 # 打印标准输出 stdin, stdout, stderr = ssh.exec_command("df") out = stdout.read() print(out.decode()) # 如果不带close最后的中断直接是reset,而使用了close之后最后中断就是平滑的三次握手 ssh.close() "C:\Program Files\Python311\python.exe" G:\python2\第十章\test.py Filesystem 1K-blocks Used Available Use% Mounted on udev 1955888 0 1955888 0% /dev tmpfs 398824 1380 397444 1% /run /dev/sda1 101639152 12773768 83656196 14% / tmpfs 1994112 0 1994112 0% /dev/shm tmpfs 5120 0 5120 0% /run/lock tmpfs 398820 88 398732 1% /run/user/0 # 要求2的完成可以采取一个非常取巧的办法,把四个命令写到一块即可,如下所示: stdin, stdout, stderr = ssh.exec_command("hostname;df;ps aux|grep ssh;cat /etc/issue") 第二版

要求把上述代码写成函数,并连续执行四个命令,如下所示:

import paramiko, time port_number = 22 username = "root" password = "cba-123" ip = "192.168.3.19" def ssh(cmd): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( port=port_number, username=username, password=password, hostname=ip ) stdin, stdout, stderr = ssh.exec_command(cmd) out = stdout.read() print(out.decode()) ssh.close() ssh("df | head -1") ssh("hostname") ssh("cat /etc/issue") ssh("cat /etc/passwd | head -1")

其实像上图这么做是一个循环的过程,是完全的单线程操作,每一个命令都需要完成ssh的过程然后执行命令最后断开连接,这个过程要重复四次,这是特别浪费资源的,但我们在这里不去讨论多线程之类的,也不去关注性能,反正这么就完成任务;

其实代码还可以更简单一点,那就是把命令写在列表,然后循环列表,执行函数;

cmds = ["df|head -1","hostname","whoami","echo $PATH"] for cmd in cmds: ssh(cmd)

上述代码还有改进的地方,那就是在标准输入和输出那个地方,咱们可以使用三元运算:

stdin, stdout, stderr = ssh.exec_command(cmd) res,err = stdout.read(),stderr.read() result = res if res else err print(result.decode()) ssh.close() 最终版 import paramiko, time port_number = 22 username = "root" password = "cba-123" ip = "192.168.3.19" def ssh(cmd): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( port=port_number, username=username, password=password, hostname=ip ) stdin, stdout, stderr = ssh.exec_command(cmd) res,err = stdout.read(),stderr.read() result = res if res else err print(result.decode()) ssh.close() cmds = ["df|head -1","hostname","whoami","ecdho $PATH"] for cmd in cmds: ssh(cmd) "C:\Program Files\Python311\python.exe" G:\python2\第十章\test.py Filesystem 1K-blocks Used Available Use% Mounted on kali root zsh:1: command not found: ecdho SFTP

SFTP是在ssh建立连接的基础上,所以上述代码建立连接的部分,可以直接直接抄下来

第一版

将服务器的/etc/passwd文件下载到本地,命名为backup_hostname

# 将服务器的/etc/passwd文件下载到本地,命名为backup_hostname import paramiko, time port_number = 22 username = "root" password = "cba-123" ip = "192.168.3.19" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( port=port_number, username=username, password=password, hostname=ip ) # 在ssh的基础上附加或打开sftp sftp = ssh.open_sftp() sftp.get("/etc/hostname","backup_hostname") ssh.close() 第二版

将服务器的/etc下的passwd文件、fstab文件、issue文件全都下载下来;

# 下载 import os.path import paramiko def sftp_get(file_path): port_number = 22 username = "root" password = "cba-123" ip = "192.168.3.19" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( port=port_number, username=username, password=password, hostname=ip ) # 在ssh的基础上附加或打开sftp sftp = ssh.open_sftp() file_in = file_path file_out = os.path.basename(file_in) sftp.get(file_in, file_out) ssh.close() files = ["/etc/passwd","/etc/issue","/etc/hostname"] for file in files: sftp_get(file)

image-20230321125143881

多次执行会直接进行覆盖的。

这里面涉及到一个新的知识点,那就是取文件的基名,要通过os模块,非常容易理解。

# 上传 import os.path import paramiko def sftp_put(put_file): port_number = 22 username = "root" password = "cba-123" ip = "192.168.3.19" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( port=port_number, username=username, password=password, hostname=ip ) # 在ssh的基础上附加或打开sftp sftp = ssh.open_sftp() file_in = put_file file_out = f'/tmp/{file_in}.back' sftp.put(file_in,file_out) ssh.close() files = ["passwd","issue","hostname"] for file in files: sftp_put(file)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有