Island adjusted to differentiate parsing data incoming from linux and windows bootloaders

This commit is contained in:
VakarisZ 2020-02-24 17:17:34 +02:00
parent c2b125012f
commit 056c260c12
4 changed files with 24 additions and 7 deletions

View File

@ -115,8 +115,12 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
def do_POST(self): def do_POST(self):
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
post_data = self.rfile.read(content_length).decode() # <--- Gets the data itself post_data = self.rfile.read(content_length).decode() # <--- Gets the data itself
try:
r = requests.post(url=self.path, data=post_data) r = requests.post(url=self.path, data=post_data)
if (r.status_code != 200): except requests.exceptions.ConnectionError as e:
LOG.error("Couldn't forward request to the island: {}".format(e))
return self.send_response(404)
if r.status_code != 200:
# somehow forward post request to the next proxy # somehow forward post request to the next proxy
r = requests.post(url=self.path, data=post_data, proxy=self.path) r = requests.post(url=self.path, data=post_data, proxy=self.path)
if (r.status_code != 200): if (r.status_code != 200):

View File

@ -87,7 +87,7 @@ def init_app_url_rules(app):
def init_api_resources(api): def init_api_resources(api):
api.add_resource(Root, '/api') api.add_resource(Root, '/api')
api.add_resource(Monkey, '/api/monkey', '/api/monkey/', '/api/monkey/<string:guid>') api.add_resource(Monkey, '/api/monkey', '/api/monkey/', '/api/monkey/<string:guid>')
api.add_resource(Bootloader, '/api/bootloader') api.add_resource(Bootloader, '/api/bootloader/<string:os>')
api.add_resource(LocalRun, '/api/local-monkey', '/api/local-monkey/') api.add_resource(LocalRun, '/api/local-monkey', '/api/local-monkey/')
api.add_resource(ClientRun, '/api/client-monkey', '/api/client-monkey/') api.add_resource(ClientRun, '/api/client-monkey', '/api/client-monkey/')
api.add_resource(Telemetry, '/api/telemetry', '/api/telemetry/', '/api/telemetry/<string:monkey_guid>') api.add_resource(Telemetry, '/api/telemetry', '/api/telemetry/', '/api/telemetry/<string:monkey_guid>')

View File

@ -1,4 +1,5 @@
from http.server import HTTPServer, BaseHTTPRequestHandler from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
from urllib import parse from urllib import parse
import urllib3 import urllib3
@ -9,7 +10,7 @@ import pymongo
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class BootloaderHttpServer(HTTPServer): class BootloaderHttpServer(ThreadingMixIn, HTTPServer):
def __init__(self, mongo_url): def __init__(self, mongo_url):
self.mongo_client = pymongo.MongoClient(mongo_url) self.mongo_client = pymongo.MongoClient(mongo_url)
@ -26,6 +27,7 @@ class BootloaderHTTPRequestHandler(BaseHTTPRequestHandler):
if not conf: if not conf:
conf = self.server.mongo_client['monkeyisland']['config'].find_one({'name': 'initial'}) conf = self.server.mongo_client['monkeyisland']['config'].find_one({'name': 'initial'})
island_server_path = BootloaderHTTPRequestHandler.get_bootloader_resource_path_from_config(conf) island_server_path = BootloaderHTTPRequestHandler.get_bootloader_resource_path_from_config(conf)
island_server_path = parse.urljoin(island_server_path, self.path)
r = requests.post(url=island_server_path, data=post_data, verify=False) r = requests.post(url=island_server_path, data=post_data, verify=False)
if r.status_code != 200: if r.status_code != 200:

View File

@ -10,18 +10,29 @@ from monkey_island.cc.services.bootloader import BootloaderService
class Bootloader(flask_restful.Resource): class Bootloader(flask_restful.Resource):
# Used by monkey. can't secure. # Used by monkey. can't secure.
def post(self, **kw): def post(self, os):
data = Bootloader.parse_bootloader_request(request.data) if os == 'linux':
data = Bootloader.parse_bootloader_request_linux(request.data)
elif os == 'windows':
data = Bootloader.parse_bootloader_request_windows(request.data)
else:
return make_response({"status": "OS_NOT_FOUND"}, 404)
resp = BootloaderService.parse_bootloader_data(data) resp = BootloaderService.parse_bootloader_data(data)
if resp: if resp:
return make_response({"status": "RUN"}, 200) return make_response({"status": "RUN"}, 200)
else: else:
return make_response({"status": "ABORT"}, 200) return make_response({"status": "ABORT"}, 200)
@staticmethod @staticmethod
def parse_bootloader_request(request_data: bytes) -> Dict[str, str]: def parse_bootloader_request_linux(request_data: bytes) -> Dict[str, str]:
parsed_data = json.loads(request_data.decode().replace("\n", "") parsed_data = json.loads(request_data.decode().replace("\n", "")
.replace("NAME=\"", "") .replace("NAME=\"", "")
.replace("\"\"", "\"") .replace("\"\"", "\"")
.replace("\":\",", "\":\"\",")) .replace("\":\",", "\":\"\","))
return parsed_data return parsed_data
@staticmethod
def parse_bootloader_request_windows(request_data: bytes) -> Dict[str, str]:
return json.loads(request_data.decode("utf-16", "ignore"))