Files
MaorSabag c0fc8d878b Initial commit: NoNameAx public release
Position-independent C2 beacon for Adaptix Framework with:
- PIC shellcode beacon (PEB walk, FNV1a hashing)
- BeaconGate API proxy + WFSO PoC sleepmask (extensible)
- BOF execution with module stomping
- Malleable C2 profiles with runtime switching
- WinHTTP transport (proxy-aware)
- Token manipulation (steal, impersonate, create)
- TCP tunneling (SOCKS, lportfwd, rportfwd)
- SMB pivoting
- Stardust UDRL loader with module stomping
2026-06-28 09:44:19 -04:00

7.8 KiB

Token Commands

NaX supports Windows access token manipulation for impersonation, privilege escalation, and lateral movement. Eight commands cover the full token lifecycle: query identity, steal tokens from processes, impersonate, create tokens from credentials, and manage the token store.


Architecture

Token Store

The beacon maintains an in-memory linked list of stolen/created tokens (NAX_TOKEN_NODE). Each entry holds the token handle, a numeric ID, and the resolved DOMAIN\user string. The store persists across heartbeats until explicitly cleared.

Impersonation Model

When a token is activated (via token steal with auto-impersonate, token use, or token make), the beacon calls ImpersonateLoggedOnUser on its main thread. All subsequent operations (file I/O, network access, process creation) run under the impersonated identity. The Adaptix console header updates to show the impersonated user with a * prefix.

Command IDs

Each token operation has its own command ID (Adaptix pattern), not a single command with sub-command dispatch:

Command ID Description
token getuid 0x50 Current identity (process or impersonated)
token steal 0x51 Duplicate token from a running process
token use 0x52 Impersonate a stored token by ID
token list 0x53 List all tokens in the store
token rm 0x54 Remove a token from the store
token revert 0x55 Drop impersonation, revert to process token
token make 0x56 Create token from credentials (LogonUserA)
token privs 0x57 List privileges on the current token

Commands

token getuid

Return the current effective identity. If impersonating, returns the impersonated user; otherwise returns the process token user.

token getuid

Result: DOMAIN\username with an elevated flag (Yes/No).

Implementation detail: Uses OpenThreadToken(..., OpenAsSelf=TRUE) to avoid ERROR_ACCESS_DENIED when impersonating a non-admin user. Falls back to OpenProcessToken if no thread token exists.

token steal

Duplicate a token from a target process and optionally impersonate it immediately.

token steal <pid> [impersonate]
Argument Description
pid Target process ID
impersonate If present (any value), auto-impersonate the stolen token
token steal 4832
token steal 4832 true

Opens the process with PROCESS_QUERY_INFORMATION, duplicates the token with TOKEN_ALL_ACCESS, resolves the token's user/domain via GetTokenInformation, and stores it. If impersonate is set, calls ImpersonateLoggedOnUser and updates the console header.

token use

Impersonate a previously stored token by its numeric ID.

token use <token_id>
token use 1
token use 3

Looks up the token in the store, calls ImpersonateLoggedOnUser, and updates the console header with the token's DOMAIN\user.

token list

List all tokens currently in the store.

token list

Output is a table with columns: ID, Handle, User, Domain.

token rm

Remove a token from the store and close its handle.

token rm <token_id>
token rm 2

If the removed token was the currently impersonated one, impersonation is NOT automatically reverted -- use token revert separately.

token revert

Drop impersonation and revert to the process token.

token revert

Calls RevertToSelf() and clears the console header's impersonation indicator.

token make

Create a new token from plaintext credentials using LogonUserA. Supports multiple logon types for different use cases.

token make [-t <type>] <domain> <username> <password>
Argument Description
-t <type> Logon type (optional, default: new_credentials)
domain Target domain (e.g., CORP, sevenkingdoms.local, . for local)
username Account username
password Account password

Logon Types

Type Value Behavior
interactive 2 Full logon. Token SID shows the actual user. Local and network access as the target user. Requires the password to be valid.
network 3 Network logon. Token valid for network resources only.
network_cleartext 8 Like network but credentials available for delegation. Useful for Kerberos double-hop.
new_credentials 9 (Default) Network-only credentials. Token SID remains the caller's identity locally, but network access uses the supplied credentials. Does NOT validate the password locally.
token make sevenkingdoms.local cersei.lannister il0vejaime
token make -t interactive CORP admin P@ssw0rd!
token make -t network_cleartext . svc_account SecretPass

Type 9 vs Type 2: With new_credentials (default), token getuid still shows the original user because the token SID isn't changed -- only outbound network authentication uses the new credentials. Use -t interactive when you need the token to fully reflect the target identity.

token privs

List all privileges on the current effective token (thread token if impersonating, process token otherwise).

token privs

Output is a table with columns: Privilege Name, Status (Enabled/Disabled).

Uses OpenThreadToken(..., OpenAsSelf=TRUE) like token getuid for the same access-check safety.


Console Header

When impersonation is active, the Adaptix console header shows the impersonated identity with a * prefix:

*SEVENKINGDOMS\cersei.lannister

This is updated via TsAgentUpdateDataPartial with the Impersonated field. Commands that set impersonation (token steal with impersonate flag, token use, token make) set the header. token revert clears it.


Wire Format

Task (server -> beacon)

All token commands use the standard task frame: cmdId(1) | taskId(4) | args(variable).

Command Args format
token getuid (none)
token steal pid(4LE) | impersonate(1)
token use tokenId(4LE)
token list (none)
token rm tokenId(4LE)
token revert (none)
token make logonType(4LE) | domainLen(4LE) | domain | userLen(4LE) | user | passLen(4LE) | pass
token privs (none)

Result (beacon -> server)

Command Success data
token getuid userLen(4LE) | user | domainLen(4LE) | domain | elevated(1)
token steal tokenId(4LE) | userLen(4LE) | user | domainLen(4LE) | domain | impersonate(1)
token use userLen(4LE) | user | domainLen(4LE) | domain
token list count(4LE) | [tokenId(4LE) | handle(8LE) | userLen(4LE) | user | domainLen(4LE) | domain] * count
token rm (empty)
token revert (empty)
token make tokenId(4LE) | userLen(4LE) | user | domainLen(4LE) | domain
token privs count(4LE) | [nameLen(4LE) | name | status(4LE)] * count

On error (status=0x01), all token commands return the Win32 error code as errorCode(4LE) in the result data.


Files

File Role
src_beacon/include/Wire.h NAX_CMD_TOKEN_GETUID through NAX_CMD_TOKEN_PRIVS (0x50-0x57)
src_beacon/include/Nax.h Forward declarations for all 8 CmdToken* functions
src_beacon/src/Commands/Token.c Beacon-side implementations
src_beacon/src/Commands/Dispatch.c 8 separate case entries routing to each handler
src_server/agent_nonameax/pl_main.go CMD_TOKEN_* Go constants
src_server/agent_nonameax/pl_commands.go Command packing (args -> wire format)
src_server/agent_nonameax/pl_format.go Result decoders (decodeTokenGetUidResult, etc.)
src_server/agent_nonameax/pl_results.go Result processing + console header updates
src_server/agent_nonameax/ax_config.axs AxScript command registration + UI