Files
volatility3/development/banner_server.py
2024-12-17 22:55:39 +01:00

95 lines
2.9 KiB
Python

import argparse
import base64
import json
import logging
import os
import pathlib
import urllib
from volatility3.cli import PrintedProgress
from volatility3.framework import contexts, constants
from volatility3.framework.automagic import linux, mac
vollog = logging.getLogger(__name__)
class BannerCacheGenerator:
def __init__(self, path: str, url_prefix: str):
self._path = path
self._url_prefix = url_prefix
def convert_url(self, url):
parsed = urllib.parse.urlparse(url)
relpath = os.path.relpath(parsed.path, os.path.abspath(self._path))
return urllib.parse.urljoin(self._url_prefix, relpath)
def run(self):
context = contexts.Context()
json_output = {"version": 1}
path = self._path
filename = "*"
for banner_cache in [linux.LinuxBannerCache, mac.MacBannerCache]:
sub_path = banner_cache.os
potentials = []
for extension in constants.ISF_EXTENSIONS:
# Hopefully these will not be large lists, otherwise this might be slow
try:
for found in (
pathlib.Path(path)
.joinpath(sub_path)
.resolve()
.rglob(filename + extension)
):
potentials.append(found.as_uri())
except FileNotFoundError:
# If there's no linux symbols, don't cry about it
pass
new_banners = banner_cache.read_new_banners(
context,
"BannerServer",
potentials,
banner_cache.symbol_name,
banner_cache.os,
progress_callback=PrintedProgress(),
)
result_banners = {}
for new_banner in new_banners:
# Only accept file schemes
value = [
self.convert_url(url)
for url in new_banners[new_banner]
if urllib.parse.urlparse(url).scheme == "file"
]
if value and new_banner:
# Convert files into URLs
result_banners[str(base64.b64encode(new_banner), "latin-1")] = value
json_output[banner_cache.os] = result_banners
output_path = os.path.join(self._path, "banners.json")
with open(output_path, "w") as fp:
vollog.warning(f"Banners file written to {output_path}")
json.dump(json_output, fp)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--path", default=os.path.dirname(__file__))
parser.add_argument(
"--urlprefix",
help="Web prefix that will eventually serve the ISF files",
default="http://localhost/symbols",
)
args = parser.parse_args()
bcg = BannerCacheGenerator(args.path, args.urlprefix)
bcg.run()