-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
executable file
·137 lines (116 loc) · 4.53 KB
/
server.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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import http.server
import socketserver
import socket
import fcntl
import struct
import os
import magic
import pathlib
import sys
TOOLCHAIN_PATH = pathlib.Path(__file__).parent.absolute()
def get_local_interface_ip(ifname: str = 'tun0') -> str:
SIOCGIFADDR = 0x8915
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
netip = fcntl.ioctl(sock.fileno(), SIOCGIFADDR, struct.pack('256s', ifname[:15].encode('utf-8')))
return socket.inet_ntoa(netip[20:24])
class HTTPHandler(http.server.BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def send_error(self, code: int, message: str | None = None, explain: str | None = None) -> None:
#return super().send_error(code, message, explain)
client_ip, client_port = self.client_address
try:
user_agent = self.headers.get('User-Agent')
except:
user_agent = '-'
try:
print(f'[!] {client_ip}:{client_port:5d} | {user_agent} | {self.command} {self.path}')
except:
print(f'[!] {client_ip}:{client_port:5d} | {user_agent} | {message}')
self.send_response_only(405)
self.send_header('Content-Length', 0)
self.send_header('Connection', 'close')
self.end_headers()
def handle_file(self, path: str) -> bytes:
with open(path, 'rb') as fd:
return fd.read()
def do_POST(self):
content = b''
path = self.path[1:]
client_ip, client_port = self.client_address
user_agent = self.headers.get('User-Agent')
body = self.rfile.read1().decode('utf-8')
print(f'[+] {client_ip}:{client_port:5d} | {user_agent} | {self.command} {self.path} | {body}')
mime = magic.Magic(mime = True)
self.send_response_only(200)
self.send_header('Content-Type', mime.from_buffer(content))
self.send_header('Content-Length', len(content))
self.send_header('Connection', 'close')
self.end_headers()
try:
self.wfile.write(content)
except ConnectionResetError:
print('[!] < Connection reset error')
def do_GET(self):
content = b''
path = self.path[1:]
client_ip, client_port = self.client_address
user_agent = self.headers.get('User-Agent')
print(f'[+] {client_ip}:{client_port:5d} | {user_agent} | {self.command} {self.path}')
if path.startswith('bc'):
try:
port = int(path[len('bc?'):])
except ValueError:
port = 31337
cpath = pathlib.PurePath(TOOLCHAIN_PATH, 'bc.py')
with open(cpath, 'r') as fd:
content = fd.read().replace('__PORT__', str(port)).replace('__HOST__', get_local_interface_ip())
content = content.encode('utf-8')
print(f'[*] Served backconnect script for port {port}')
if path.startswith('static/'):
name = pathlib.PurePath(path).name
cpath = pathlib.PurePath(TOOLCHAIN_PATH, 'static', name)
try:
content = self.handle_file(cpath)
except Exception as e:
print(f'[!] {e!s}')
if path.startswith('current/'):
cwd = pathlib.PurePath(os.getcwd())
cpath = pathlib.PurePath(*pathlib.PurePath(path).parts[1:])
cpath = pathlib.PurePath(os.path.normpath(cwd.joinpath(cpath)))
if cpath.is_relative_to(cwd):
try:
content = self.handle_file(cpath)
except Exception as e:
print(f'[!] {e!s}')
mime = magic.Magic(mime = True)
self.send_response_only(200)
self.send_header('Content-Type', mime.from_buffer(content))
self.send_header('Content-Length', len(content))
self.send_header('Connection', 'close')
self.end_headers()
try:
self.wfile.write(content)
except ConnectionResetError:
print('[!] < Connection reset error')
class HTTPServer(socketserver.ThreadingTCPServer):
allow_reuse_address = True
def main():
iface = os.getenv('IFACE', 'tun0')
try:
bind = get_local_interface_ip(iface)
except OSError:
print(f'[!] {iface} down?')
return
port = 8000
if len(sys.argv) > 1:
port = int(sys.argv[1])
print(f'[*] Handling on {bind}:{port}')
httpd = HTTPServer((bind, port), HTTPHandler)
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
main()