Python:webshell 跳板机审计服务器
1.修改paramiko源码包实现
https://github.com/paramiko/paramiko/tree/1.10.1 下载源码包
unzip paramiko-1.10.1.zip
paramiko-1.10.1/demos/demo.py 模拟用户登录,在demo.py中会调用interactive.py
paramiko-1.10.1/demos/interactive.py 会把用户执行的命令以及服务器返回的结果打印出来
修改interactive.py,可以把用户名、执行的命令、时间、主机ip记录到日志中
demo.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | import base64 from binascii import hexlify import getpass import os import select import socket import sys import threading import time import traceback import paramiko import interactive #define host print ( "\033[34;1mWelcome zhengshun's Fort Machine\nThere have those machines:\033[0m" ) dictroy = { "vc-app01" : "192.168.101.131" , "vc-app02" : "192.168.101.130" , "vc-app03" : "192.168.101.132" } while 1 : try : print ('') for k,v in dictroy.items(): print k,v print ('') hostname = raw_input ( 'please input IP:' ) if hostname = = '': continue elif hostname = = 'exit' : break elif hostname = = 'quit' : break 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: 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 = 'p' if len (auth) = = 0 : auth = default_auth if auth = = 'r' : default_path = os.path.join(os.environ[ 'HOME' ], '.ssh' , 'id_rsa' ) path = raw_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) elif auth = = 'd' : default_path = os.path.join(os.environ[ 'HOME' ], '.ssh' , 'id_dsa' ) path = raw_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 = '123456' t.auth_password(username, pw) # setup logging paramiko.util.log_to_file( 'demo.log' ) username = 'root' if len (hostname) = = 0 : print '*** Hostname required.' sys.exit( 1 ) port = 22 if hostname.find( ':' ) > = 0 : hostname, portstr = hostname.split( ':' ) port = int (portstr) # now connect try : sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((hostname, port)) except : print ( '\033[31;1minvalid value\033[0m' ) continue #except Exception, e: # print '*** Connect failed: ' + str(e) # traceback.print_exc() # sys.exit(1) try : 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 : 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 not keys.has_key(hostname): print '*** WARNING: Unknown host key!' elif not keys[hostname].has_key(key.get_name()): 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 = = '': default_username = getpass.getuser() username = raw_input ( 'Username [%s]: ' % default_username) if len (username) = = 0 : username = default_username agent_auth(t, username) if not t.is_authenticated(): manual_auth(username, hostname) if not t.is_authenticated(): print '*** Authentication failed. :(' t.close() sys.exit( 1 ) chan = t.open_session() chan.get_pty() chan.invoke_shell() print '*** Here we go!' print interactive.interactive_shell(chan) chan.close() t.close() except Exception, e: print '*** Caught exception: ' + str (e.__class__) + ': ' + str (e) traceback.print_exc() try : t.close() except : pass sys.exit( 1 ) except : continue |
2.创建跳板机用户,并设置用户登陆的环境变量
注意事项:用户登录跳板机后不能跳过demo.py程序,如果退出demo.py程序则注销跳板机的登陆,只能选择要登陆的主机ip,选择后直接登陆,如果用户在输入错误时,要循环从头开始
adduser audit
vim /home/audit/.bash_profile 在环境变量中加入执行python demo.py文件,执行后logout
3.使用shellinabox实现webssh
https://code.google.com/archive/p/shellinabox/downloads 下载shellinabox-2.14.tar.gz
tar zxf shellinabox-2.14.tar.gz
cd shellinabox-2.14
./configure --prefix=/usr/local/webshell && make && make install
bash /usr/local/webshell/bin/shellinaboxd & 后台运行,shellinabox默认端口是4200
访问https://ip:4200就可以登陆跳板机
展示:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 上周热点回顾(1.20-1.26)