1
0
mirror of synced 2024-12-18 09:15:54 +01:00
bemaniutils/bemani/utils/bemanishark.py

108 lines
3.7 KiB
Python
Raw Normal View History

from typing import Optional
import argparse
from bemani.sniff import Sniffer
from bemani.protocol import EAmuseProtocol, EAmuseException
from bemani.common import HTTP
def mainloop(
address: Optional[str] = None, port: int = 80, verbose: bool = False
) -> None:
"""
Main loop of BEMANIShark. Starts an instance of Sniffer and EAmuseProtocol and does a
lazy job of banging them together with the above HTTP.parse. Will loop trying to decode
packets forever.
Arguments:
address - A string representing an IP of interest
port - An integer representing a port of interest
"""
sniffer = Sniffer(address=address, port=port)
parser = EAmuseProtocol()
while True:
packets = sniffer.recv_stream()
inbound = HTTP.parse(packets["inbound"], request=True)
outbound = HTTP.parse(packets["outbound"], response=True)
if inbound is not None:
if inbound["data"] is None:
in_req = None
else:
try:
in_req = parser.decode(
inbound["headers"].get("x-compress"),
inbound["headers"].get("x-eamuse-info"),
inbound["data"],
)
except EAmuseException:
in_req = None
print(
f"Inbound request (from {packets['source_address']}:{packets['source_port']} to {packets['destination_address']}:{packets['destination_port']}):"
)
if verbose:
print(f"HTTP {inbound['method']} request for URI {inbound['uri']}")
print(f"Compression is {inbound['headers'].get('x-compress', 'none')}")
print(
f"Encryption key is {inbound['headers'].get('x-eamuse-info', 'none')}"
)
if in_req is None:
print("Inbound request was not parseable")
else:
print(in_req)
if outbound is not None:
if outbound["data"] is None:
out_req = None
else:
try:
out_req = parser.decode(
outbound["headers"].get("x-compress"),
outbound["headers"].get("x-eamuse-info"),
outbound["data"],
)
except EAmuseException:
out_req = None
print(
f"Outbound response (from {packets['destination_address']}:{packets['destination_port']} to {packets['source_address']}:{packets['source_port']}):"
)
if verbose:
print(f"Compression is {outbound['headers'].get('x-compress', 'none')}")
print(
f"Encryption key is {outbound['headers'].get('x-eamuse-info', 'none')}"
)
if out_req is None:
print("Outbound response was not parseable")
else:
print(out_req)
def main() -> None:
parser = argparse.ArgumentParser(
description="A utility to sniff packets and decode them as eAmusement packets. Should probably be run as root."
)
parser.add_argument(
"-p", "--port", help="Port to sniff on. Defaults to 80", type=int, default=80
)
parser.add_argument(
"-a",
"--address",
help="Address to sniff on. Defaults to all addresses",
type=str,
default=None,
)
parser.add_argument(
"-v", "--verbose", help="Show extra packet information", action="store_true"
)
args = parser.parse_args()
mainloop(address=args.address, port=args.port, verbose=args.verbose)
if __name__ == "__main__":
main()