HackPluto's Blog

自己动手写工具(2)--TCP代理

字数统计: 941阅读时长: 4 min
2019/05/10 Share

##TCP代理的简介
这次的博客给大家再介绍一个TCP代理的小工具,TCP代理是什么呢,就是处在应用层上位于真正的服务器和客户端之间用TCP的方式将流量从一个机子转到另一个机子,可以起到监控流量,修改数据包的功能。
代理服务器还有一个重要的作用就是隐藏背后的真正服务器,使服务器免受攻击。假如代理服务器挂了,后面的服务器仍然可以正常运行,而且如果背后的服务器还拥有多台代理服务器就会使自己更加安全。

##实现的原理
1.代理先开启一个TCP服务
2.客户端先去连接代理
3.代理在与客户端取得连接后立即与远程的服务端建立TCP链接
4.无论是客户端还是服务端发送数据都是先发送到代理然后代理再决定对数据做不做修改,然后转发给接收方
5.当客户端与服务端都发出结束连接的信号时断开所有连接释放所有资源

##代码实现
定义全局变量,其中flag变量是为了记录套接字的状态

1
2
3
4
5
6
7
local_host = ""
local_port = 0
remote_host = ""
remote_port = 0
receive_first = True
flag1 = False
flag2 = False

定义主函数
使用sys.argv从命令行获取参数,如果输入格式不对则输出正确格式的范例,然后给每一个参数赋值,调用生成TCP服务的函数server_loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def Main():
global local_host
global local_port
global remote_host
global remote_port
global receive_first
if len(sys.argv[1:] != 5):
print("Use python3 proxy.py local_host local_port remote_host remote_port receive_first")
print("Example:python3 proxy.py 127.0.0.1 8899 12.34.34.1 8888 True")
else:
local_host = sys.argv[1]
local_port = sys.argv[2]
remote_host = sys.argv[3]
remote_port = sys.argv[4]
receive_first = sys.argv[5]
if "True" in receive_first:
receive_first = True
else:
receive_first = False
server_loop()

server_loop
开启TCP服务,绑定在local_host,local_port,然后建立对等连接套接字接受来自客户端的连接,同时连接远程的服务端并且开启多线程,调用执行转发数据的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def server_loop():
try:
server = socket.socket()
server.bind((local_host,local_port))
server.listen(10)
print("[*]listen on %s:%d" % (local_host,local_port))
except :
print("Failed to listen on %s:%d" % (local_host,local_port))

while True:
client_socket, addr = server.accept()
print("[*]Connect from %s:%d" % (addr[0],addr[1]))
try:
server_socket = socket.socket()
server_socket.connect((remote_host,remote_port))
print("[*]Connect to %s:%d" % (remote_host,remote_port))
except :
print("Failed to connect to %s:%d" % (remote_host,remote_port))
print("----------------------------")
client_thread = threading.Thread(target=proxy_handler,args=(client_socket,server_socket))
client_thread.start()

proxy_handler
接受来自双方的数字,打印出数据询问是否修改,若不修改直接发送,发送为两个被调函数send_client,send_server,向客户端发送与向服务端发送

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def proxy_handler(client_socket,server_socket):
global receive_first
while True:
if receive_first:
send_client(server_socket,client_socket)
receive_first = False
else:
while True:
send_server(client_socket,server_socket)
send_client(server_socket,client_socket)
if flag1 == True and flag2 == True:
break
if flag1 == True and flag2 == True:
break

send_client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def send_client(server_socket,client_socket):
global flag1
server_data = ""
server_data = receive_from(server_socket)
print(server_data)
a = input("[*]if modify the data;[y/n]")
if a == 'y':
server_data = input()
else:
pass
if len(server_data):
print("[<==]sending %d bytes to %s" % (len(server_data),local_host))
client_socket.send(server_data.encode())
if server_data == 'over':
server_socket.close()
flag1 = True

send_server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def send_server(client_socket,server_socket):
global flag2
client_data = ""
client_data = receive_from(client_socket)
print(client_data)
a = input("[*]if modify the data;[y/n]")
if a == 'y':
server_data = input()
else:
pass
if len(client_data):
print("[==>]sending %d bytes to %s" % (len(client_data),remote_host))
server_socket.send(client_data.encode())
if client_data == 'over':
client_socket.close()
flag2 = True

receive_from
接受数据,这里设置了超时时间达到非阻塞的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
def receive_from(conn_socket):
conn_socket.settimeout(3)
data = ""
try:
while True:
buffer = conn_socket.recv(4096).decode()
if buffer:
data += buffer
else:
break
except:
pass
return data

客户端代码

1
2
3
4
5
6
7
8
9
10
11
12
import socket
client = socket.socket()
client.connect(('127.0.0.1',8899))
while True:
data = client.recv(4096).decode()
if data and data != 'over':
print(data)
client.send(b'hello world')
if data == 'over':
client.send(b'over')
break
client.close()

服务端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import socket

server = socket.socket()
server.bind(('',8899))
server.listen(10)
client, addr = server.accept()
client.send(b'hello world')
while True:
data = client.recv(4096).decode()
if data and data != 'over':
print(data)
client.send(b'over')
if data == 'over':
break

client.close()

CATALOG