paramiko 源码修改

  paramiko主要用来实现ssh客户端、服务端链接,上一节我们说到了堡垒机,堡垒机内有一个需求是“用户行为审计”,在这里我们就可以通过修改paramiko内文件的源码来实现相关要求。

paramiko 源码包安装测试
  • 下载地址https://github.com/ 下载源码包paramiko
  • 解压源码包 paramiko-master.zip
  • 使用目录:paramiko-master\paramiko-master\demos
  • python3启动:python paramiko-master\paramiko-master\demos\demos.py

:paramiko demos.py启动 不支持python3 ,由于python3默认是bays类型,需要修改源码。

\demos\interactive.py",
line , in writeall
sys.stdout.write(data)
TypeError: write() argument must be str, not bytes
修改源代码(demos.py 添加 python3 支持)
:interactive.py文件内(77~85 行)
def writeall(sock):
while True:
data = sock.recv(256)
if not data:
sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
sys.stdout.flush()
break
    # 修改为编译为UTF-8
sys.stdout.write(data.decode())
sys.stdout.flush()
C:\Users\Administrator\demos>python3 demo.py
Hostname: 192.168.1.100
*** Unable to open host keys file
*** WARNING: Unknown host key!
Username [Administrator]: root
Auth by (p)assword, (r)sa key, or (d)ss key? [p] p
Password for root@192.168.1.100:
*** Here we go! Line-buffered terminal emulation. Press F6 or ^Z to send EOF. Last login: Mon Jan 22 11:24:35 2018 from 192.168.1.150 [root@localhost ~]#
注:登陆成功

测试使用

修改源码(实现抓取用户操作指令)

注:paramiko-master\paramiko-master\demos\demos.py 文件源码、简要说明
import base64
from binascii import hexlify
import getpass
import os
import select
import socket
import sys
import time
import traceback
from paramiko.py3compat import input import paramiko
try:
import interactive
except ImportError:
from . import interactive def agent_auth(transport, username):
"""
Attempt to authenticate to the given transport using any of the private
keys available from an SSH agent.
""" agent = paramiko.Agent()
agent_keys = agent.get_keys()
if len(agent_keys) == 0:
return for key in agent_keys:
# 尝试将本地key验证,验证不了就用密码
print('Trying ssh-agent key %s' % hexlify(key.get_fingerprint()))
try:
transport.auth_publickey(username, key)
print('... success!')
return
except paramiko.SSHException:
print('... nope.') def manual_auth(username, hostname):
default_auth = 'p'
auth = input('Auth by (p)assword, (r)sa key, or (d)ss key? [%s] ' % default_auth)
if len(auth) == 0:
auth = default_auth # r非对称秘钥
if auth == 'r':
default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
path = input('RSA key [%s]: ' % default_path)
if len(path) == 0:
path = default_path
try:
key = paramiko.RSAKey.from_private_key_file(path)
except paramiko.PasswordRequiredException:
password = getpass.getpass('RSA key password: ')
key = paramiko.RSAKey.from_private_key_file(path, password)
t.auth_publickey(username, key)
# 使用DSA 秘钥
elif auth == 'd':
default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_dsa')
path = input('DSS key [%s]: ' % default_path)
if len(path) == 0:
path = default_path
try:
key = paramiko.DSSKey.from_private_key_file(path)
except paramiko.PasswordRequiredException:
password = getpass.getpass('DSS key password: ')
key = paramiko.DSSKey.from_private_key_file(path, password)
t.auth_publickey(username, key)
else:
pw = getpass.getpass('Password for %s@%s: ' % (username, hostname))
t.auth_password(username, pw) # setup logging
paramiko.util.log_to_file('demo.log') username = ''
if len(sys.argv) > 1:
hostname = sys.argv[1]
if hostname.find('@') >= 0:
username, hostname = hostname.split('@')
else:
# 输入IP
hostname = input('Hostname: ')
if len(hostname) == 0:
# 不输入打印错误
print('*** Hostname required.')
sys.exit(1)
# 端口号22
port = 22
if hostname.find(':') >= 0:
hostname, portstr = hostname.split(':')
port = int(portstr) # now connect
try:
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 链接IP端口号
sock.connect((hostname, port))
except Exception as e:
# 登陆错误就报错
print('*** Connect failed: ' + str(e))
# 打印错误行
traceback.print_exc()
sys.exit(1) try:
# ssh实例化传入socket
t = paramiko.Transport(sock)
try:
t.start_client()
except paramiko.SSHException:
print('*** SSH negotiation failed.')
sys.exit(1) try:
keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
except IOError:
try:
# 生成rsa 防止证书校验
keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
except IOError:
print('*** Unable to open host keys file')
keys = {} # check server's host key -- this is important.
key = t.get_remote_server_key()
if hostname not in keys:
print('*** WARNING: Unknown host key!')
elif key.get_name() not in keys[hostname]:
print('*** WARNING: Unknown host key!')
elif keys[hostname][key.get_name()] != key:
print('*** WARNING: Host key has changed!!!')
sys.exit(1)
else:
print('*** Host key OK.') # get username
if username == '':
# getuser取出当前用户名
default_username = getpass.getuser()
username = input('Username [%s]: ' % default_username)
if len(username) == 0:
username = default_username agent_auth(t, username)
# key验证 没通过继续往下走
if not t.is_authenticated():
manual_auth(username, hostname)
if not t.is_authenticated():
print('*** Authentication failed. :(')
# 认证成功就关闭
t.close()
sys.exit(1) # ssh_session交互
chan = t.open_session()
# get终端 vt100 终端模式
chan.get_pty()
chan.invoke_shell()
print('*** Here we go!\n') # 交互
# chan是双方打开的一个通道
# 调用interactive文件
interactive.interactive_shell(chan)
chan.close()
t.close() # 表村错误数据关闭链接
except Exception as e:
print('*** Caught exception: ' + str(e.__class__) + ': ' + str(e))
traceback.print_exc()
try:
t.close()
except:
pass
sys.exit(1)

文件源码

注:paramiko-master\paramiko-master\demos\interactive.py 文件源码修改,实现用户审计

import socket
import sys
from paramiko.py3compat import u # windows does not have termios...
try:
# 不出错代表这是一个linux系统
import termios
import tty
has_termios = True
except ImportError:
has_termios = False def interactive_shell(chan):
if has_termios:
# linux链接
posix_shell(chan)
else:
windows_shell(chan) # chan是传入的通道
def posix_shell(chan):
import select oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0) #-----------------1.源码修改---------------------# # 创建列表用来存放客户端输入命令
cmd = []
#----------------------------------------------# while True:
# stdin标准输入,stdout标准输出,标准错误
r, w, e = select.select([chan, sys.stdin], [], []) # 如果chan在r里面就代表有数据过来了
if chan in r:
try:
# 数据过来就收数据
x = u(chan.recv(1024))
# 如果数据等于0,代表断开链接
if len(x) == 0:
sys.stdout.write('\r\n*** EOF\r\n')
break
# 发送数据
sys.stdout.write(x)
# 刷新数据
sys.stdout.flush()
except socket.timeout:
pass
# 没进行一次动作就select就执行返回一次
if sys.stdin in r:
x = sys.stdin.read(1)
if len(x) == 0:
break
#-----------------2.源码修改---------------------# # 判断用户是否使用回车键
if x == "\r":
# 将列表字符拼接
cmd_str="".join(cmd)
# 获取出用户执行命令
print("-->",cmd_str)
# 清空列表
cmd = []
else:
# 没有回车就将字符添加列表内
cmd.append(x)
#----------------------------------------------#
chan.send(x) finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) # thanks to Mike Looijmans for this code
def windows_shell(chan):
import threading sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n") def writeall(sock):
while True:
data = sock.recv(256)
if not data:
sys.stdout.write('\r\n*** EOF ***\r\n\r\n')
sys.stdout.flush()
break
sys.stdout.write(data.decode())
sys.stdout.flush() writer = threading.Thread(target=writeall, args=(chan,))
writer.start() try:
while True:
d = sys.stdin.read(1)
if not d:
break
chan.send(d)
except EOFError:
# user hit ^Z or F6
pass

Python paramiko 修改源码实现用户命令抓取的更多相关文章

  1. Hadoop 修改源码以及将修改后的源码应用到部署好的Hadoop中

    我的Hadoop版本是hadoop-2.7.3, 我们可以去hadoop官网下载源码hadoop-2.7.3-src,以及编译好的工程文件hadoop-2.7.3, 后者可以直接部署. 前者hadoo ...

  2. Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

    摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...

  3. openfire源码解读--用户登录

    根据xmpp协议 客户端发送: <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>XXXXXXXXXXXXX ...

  4. zookeeper-如何修改源码-《每日五分钟搞定大数据》

    本篇文章仅仅是起一个抛砖迎玉的作用,举一个如何修改源码的例子.文章的灵感来自 ZOOKEEPER-2784. 提一个问题先 之前的文章讲过zxid的设计,我们先复习下: zxid有64位,分成两部分: ...

  5. solr-用mmseg4j配置同义词索引和检索(IKanlyzer需要修改源码适应solr接口才能使用同义词功能)

    概念说明:同义词大体的意思是指,当用户输入一个词时,solr会把相关有相同意思的近义词的或同义词的term的语段内容从索引中取出,展示给用户,提高交互的友好性(当然这些同义词的定义是要在配置文件中事先 ...

  6. openvswitch2.11.0修改源码后重新编译(2)

    一:前提 已经正常安装了SDN环境(mininet和openswitch2.11.0和Ryu) 使用前面教程安装环境SDN实验---使用git安装Mininet (一)测试ovs是否正常使用 1.ry ...

  7. v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...

  8. Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

    Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...

  9. Windows7 64位环境6sv2.1大气传输模型修改源码添加国产高分卫星GF-1 GF-2光谱响应支持

    下面开始添加国产卫星光谱响应的支持: 以下主要参考文章“6S大气传输模型修改源码添加.自定义卫星光谱响应(以HJ-1B CCD为例)”网址:http://blog.csdn.net/sam92/art ...

随机推荐

  1. linux signal

    1) SIGHUP 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联. 登录Linux时,系统会分配给 ...

  2. Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求

    Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求   Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 java ...

  3. Logistic 最大熵 朴素贝叶斯 HMM MEMM CRF 几个模型的总结

    朴素贝叶斯(NB) , 最大熵(MaxEnt) (逻辑回归, LR), 因马尔科夫模型(HMM),  最大熵马尔科夫模型(MEMM), 条件随机场(CRF) 这几个模型之间有千丝万缕的联系,本文首先会 ...

  4. java生成excel,word文件

    第一部分: 在网站开发中,用户可能需要打印word或者excel表,这种需求是非常多的. java语言生成excel表格和python的方式有点像,使用Apache POI的组件,一通全通.开发过程通 ...

  5. artTemplate的使用案列

    (2) https://github.com/aui/art-template/wiki/syntax:simple

  6. Ant 批量执行jmeter 脚本

    一.环境准备: 1.Jdk1.6或以上:http://www.oracle.com/technetwork/java/javase/downloads/index.html 命令行输入:java -v ...

  7. windows 安装 Apache、php、mysql及其配置(转载)

    此文包括的注意内容:软件版本及下载地址Apache2.4的配置和安装php7.0的配置mysql5.5的安装常见问题及解决方法1.软件版本Windows server 2008 r2+ 64位Apac ...

  8. 11 vs2015 连接oracle 11g 数据库及相关问题

    1.下载Oracle Developer Tools for Visual Studio 2015 ,网址如下. http://www.oracle.com/technetwork/topics/do ...

  9. selenium+python爬虫环境搭建

    前言: 准备使用selenium爬取网站数据,先搭建selenium+python爬虫环境搭建 系统环境: 64位win10系统,同时装python2.7和python3.6两个版本,IDE为pych ...

  10. 201621123049《java程序设计》第四周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 继承 类型转换 覆盖 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 2. 书面作业 1. ...