
Async BOF to automatically extract or renew Kerberos TGTs on a target system.
This repository contains two Async Beacon Object Files (BOF). The first, tgt-monitor, monitors the system for Kerberos logon events and wakes up the agent whenever a new Kerberos TGT is captured. Similar to Rubeus' monitor command, this BOF is running indefinitely and periodically checks the LSA ticket cache on the system. When a new TGT is detected, it prints the ticket metadata and outputs a base64-encoded kirbi blob that can be used for lateral movement via pass-the-ticket attacks. The second, tgt-renew, automatically renews TGTs on the system if their remaining lifetime is below a specified threshold (e.g. 15 minutes).
[!Important] The BOFs in this repository require asynchronous object file loading capabilities. Such functionality is provided by the Conquest framework.
Both BOFs require to be run from a NT AUTHORITY\SYSTEM context. The privileges are checked following the same logic.
SeImpersonatePrivilege). The BOF terminates if this also does not yield SYSTEM level access.The steps below are repeated in a loop until the BOF is cancelled via the stop event. A user-defined interval sets the delay between polls.
--user argument was provided, only sessions matching that username are considered.BeaconWakeup() call to force the agent to check in and return the output.
--user argument was provided, only sessions matching that username are considered.RenewUntil time, it is flagged as expired and re-authentication is required.BeaconWakeup() call.
The ticket renewal process involves the following steps:
This repository features a Conquest Module that implements the following two commands.
The tgt-monitor BOF alerts when new TGTs are captured and returns them as a Base64-encoded blob. The following arguments need to be passed to the object file:
| Name | Type | Description |
|---|---|---|
interval | int | Timeout between checks in seconds. |
targetUsers | string | Case-insensitive comma-separated list of target usernames. When this field is set, only TGTs for the specified users are retrieved. Otherwise, TGTs are collected for all users. Note that computer accounts need to end with $. |
Usage: tgt-monitor [--interval interval] [--user user]
Example: tgt-monitor --interval 5 --user DC01$
Optional arguments:
--interval interval INT Polling interval in seconds (default: 60).
--user user STRING Comma-separated list of target usernames (default: all users).

The encoded ticket can be used directly with Rubeus.exe ptt /ticket:<base64> or impacket-ticketConverter for further lateral movement, as shown in the screenshot below. In Conquest, it is possible to use the ptt command to directly inject the ticket into the current logon session to impersonate the target user.

The tgt-renew BOF automatically renews tickets that expire soon until they can no-longer be renewed. The following arguments need to be passed to the object file:
| Name | Type | Description |
|---|---|---|
interval | int | Timeout between checks in seconds. |
threshold | int | Renewal threshold in minutes. The ticket is renewed when the time to EndTime is lower than this threshold. |
targetUsers | string | Case-insensitive comma-separated list of target usernames. When this field is set, only TGTs for the specified users are renewed. Otherwise, TGTs are renewed for all users. Note that computer accounts need to end with $. |
targetLuids | string | Case-insensitive comma-separated list of target LUIDs. When this field is set, only TGTs for the specified LUIDs are renewed. |
Usage: tgt-renew [--interval seconds] [--threshold minutes] [--user user] [--luid luid]
Example: tgt-renew --luid 0x3e4 --interval 300 --threshold 30
Optional arguments:
--interval seconds INT Polling interval in seconds (default: 60).
--threshold minutes INT Ticket renewal threshold in minutes (default: 15).
--user user STRING Comma-separated list of target usernames (default: all users).
--luid luid STRING Comma-separated list of target LUIDs (default: all LUIDs).
The --user and --luid flags are mutually exclusive.

git clone https://github.com/jakobfriedl/tgt-monitor-bof
cd tgt-monitor-bof
make
From there, use Conquest's Script Manager to load the dist/tgt-monitor.py module.
This implementation of this Beacon Object File is based on the following projects: