-
Notifications
You must be signed in to change notification settings - Fork 0
/
socksifer-client.py
138 lines (117 loc) · 3.56 KB
/
socksifer-client.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
import base64
import json
import select
import socket
import socketio
import threading
import sys
import requests
import urllib3
# Disable SSL certificate verification for the underlying requests session
urllib3.disable_warnings()
server_id = ''
http_session = requests.Session()
http_session.verify = False
sio = socketio.Client(http_session=http_session)
socks_connections = {}
upstream_buffer = {}
def base64_to_bytes(data) -> bytes:
"""
Base64 encode a bytes object.
:param data: A base64 string.
:return: A bytes object.
:rtype: bytes
"""
return base64.b64decode(data)
def bytes_to_base64(data) -> str:
"""
Base64 encode a bytes object.
:param data: A python bytes object.
:return: A base64 encoded string
:rtype: str
"""
return base64.b64encode(data).decode('utf-8')
@sio.event
def socks(data):
global server_id
data = json.loads(data)
server_id = data['server_id']
@sio.event
def socks_upstream(data):
global socks_connections
global upstream_buffer
data = json.loads(data)
client_id = data['client_id']
upstream_buffer[client_id].append(base64_to_bytes(data['data']))
def stream(client_id):
global upstream_buffer
while True:
client = socks_connections[client_id]
r, w, e = select.select([client], [client], [])
if client in w and len(upstream_buffer[client_id]) > 0:
client.send(upstream_buffer[client_id].pop(0))
if client in r:
try:
downstream_data = client.recv(4096)
if len(downstream_data) <= 0:
break
socks_downstream_result = json.dumps({
'client_id': client_id,
'data': bytes_to_base64(downstream_data)
})
sio.emit('socks_downstream_results', socks_downstream_result)
except:
break
@sio.event
def socks_connect(data):
global socks_connections
data = json.loads(data)
atype = data['atype']
address = data['address']
port = data['port']
client_id = data['client_id']
socks_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socks_connection.settimeout(0.1)
rep = None
try:
socks_connection.connect((address, port))
rep = 0
except socket.error as e:
if e.errno == socket.errno.EACCES:
rep = 2
elif e.errno == socket.errno.ENETUNREACH:
rep = 3
elif e.errno == socket.errno.EHOSTUNREACH:
rep = 4
elif e.errno == socket.errno.ECONNREFUSED:
rep = 5
rep = rep if rep else 6
if rep != 0:
results = json.dumps({
'atype': atype,
'rep': rep,
'bind_addr': None,
'bind_port': None,
'client_id': client_id
})
else:
socks_connections[client_id] = socks_connection
upstream_buffer[client_id] = []
bind_addr = socks_connection.getsockname()[0]
bind_port = socks_connection.getsockname()[1]
results = json.dumps({
'atype': atype,
'rep': rep,
'bind_addr': bind_addr,
'bind_port': bind_port,
'client_id': client_id
})
threading.Thread(target=stream, daemon=True, args=(client_id,)).start()
sio.emit('socks_connect_results', results)
@sio.event
def ping(data):
sio.emit('pong', data)
if len(sys.argv) != 2:
print(f'Incorrect arguments provided. Please run {sys.argv[0]} http://server-url:port/')
sys.exit()
sio.connect(sys.argv[1])