diff --git a/src/gallia/commands/scan/uds/sa_dump_seeds.py b/src/gallia/commands/scan/uds/sa_dump_seeds.py index 95bf4c975..453cfbd1e 100644 --- a/src/gallia/commands/scan/uds/sa_dump_seeds.py +++ b/src/gallia/commands/scan/uds/sa_dump_seeds.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 +import asyncio import binascii import sys import time @@ -84,6 +85,12 @@ def configure_parser(self) -> None: default=b"", help="Append an optional data record to each seed request", ) + self.parser.add_argument( + "--sleep", + type=float, + metavar="FLOAT", + help="Attempt to fool brute force protection by sleeping for N seconds between seed requests.", + ) async def request_seed(self, level: int, data: bytes) -> bytes | None: resp = await self.ecu.security_access_request_seed( @@ -168,6 +175,8 @@ async def main(self, args: Namespace) -> None: # Errors are already logged in .request_seed() continue + logger.info(f"Received seed of length {len(seed)}") + await file.write(seed) if last_seed == seed: logger.warning("Received the same seed as before") @@ -209,6 +218,10 @@ async def main(self, args: Namespace) -> None: # Re-enter session. Checking/logging will be done at the beginning of next iteration await self.ecu.set_session(session) + if args.sleep is not None: + logger.info(f"Sleeping for {args.sleep} seconds between seed requests…") + await asyncio.sleep(args.sleep) + await file.close() self.log_size(seeds_file, time.time() - start_time) await self.ecu.leave_session(session, sleep=args.power_cycle_sleep)