Get our latest research in your inbox

New threat intelligence, detection engineering, and red team write-ups, delivered when we publish.

Browsing Outlook As You: Inside an Unreported ARToken / EvilTokens Phishing Tenant

July 23, 2026Crimson7 Threat Intelligence
threat intelligencephishing-as-a-serviceEvilTokensARTokenMicrosoft 365Entra IDdevice-code phishingtoken theftBECanti-detect browser

Author: Crimson7 Threat Intelligence Date: July 23, 2026 Version: 1.0 Classification: TLP Threat Type: Phishing-as-a-Service / Token Theft Severity: High


Disclaimer and scope. This research is based on static analysis of a captured client-side build of the adversary panel, passive open-source intelligence, and observed host and service fingerprint data. A named individual surfaced during the investigation. Because public vendor reporting attributes no named developer and our own link is an unproven lead, we withhold that person's identity and personal contact details from this public post. No victim data is published, and media that could contain third-party data is handled accordingly.


TL;DR

  • We captured and reverse-engineered the client build of ARToken, an operator panel for a Microsoft 365 / Entra ID token-theft operation. It phishes Microsoft's device-code authentication flow, steals access and refresh tokens and Primary Refresh Tokens (PRTs), and drives the victim tenant from a dashboard with 80+ API endpoints.
  • Cisco Talos ties the ARToken panel to the EvilTokens phishing-as-a-service ecosystem. The specific tenant we analysed (outllerbuilt.com) is not in Talos's published IOCs, so it is a previously-unreported deployment.
  • The kit bundles a companion anti-detect browser ("ARTBrowser", built on Camoufox) so operators can replay stolen sessions offline while impersonating the victim's device fingerprint and geography. That defeats impossible-travel and device-based Conditional Access.
  • The operation is tuned for Business Email Compromise (BEC) and invoice fraud against accounts-payable teams. Full IOCs, detections, and an endpoint catalog are at the end of this post.

1. How it started

Most phishing kits want your password. This one wants your password does not care about your password at all. It wants the token you receive after you authenticate, and it ships with a custom browser so the operator can log in as you, offline, later.

The investigation began with a set of files captured under the hostname bookmark.outllerbuilt.com. The entry point was a 1.2 KB React shell:

<!doctype html>
<html lang="en">
  <head>
    <title>ARToken Panel</title>
    <script src="/tinymce/tinymce.min.js"></script>
    <script type="module" crossorigin src="/assets/index-iu05ZuMD.js"></script>
    <link rel="stylesheet" crossorigin href="/assets/index-CjxfdApj.css">
  </head>
  <body><div id="root"></div></body>
</html>

A single-page application with a bundled rich-text editor and a title that gives the game away. Rendered, it is a dark-themed operator login:

ARToken panel login, the rendered SPA served at bookmark.outllerbuilt.com

The "ART" mark and the orange-to-red gradient are the panel's brand, embedded as an inline SVG favicon in the HTML. Nothing here looks like a credential-harvesting page, because it is not one. It is the operator console for a token-theft operation.


2. Reading the panel: what the bundle confessed

The application is a Vite/React SPA plus a self-hosted TinyMCE 8.3.2 editor (the phishing-template composer). All logic lives in one 1.76 MB minified file that talks to a REST backend at base path /api. We did not need to fully de-minify it. The endpoint names and in-app help strings describe the tool on their own.

2.1 Captured artifacts

SHA-256                                                           File
e4579adf4815b7d0a52aa488e5adee2174f41f2de36147955493c74e8332e7c5  login.bin              (SPA entry HTML)
d8bef2294be2612f497a3c7e478ad43556d153d593212f9703265b4cbadef098  index-iu05ZuMD.js      (app bundle)
087bb776f2b6c767ad6c54673edb1b7267e693a3495a48d8faa12fb064b797d2  index-CjxfdApj.css     (styles)
ecc2bcdfc5c4b91c6c8dffa42e5c9219c5fa14bdd7f1478025ea10a48cb4b277  tinymce.min.js         (v8.3.2)

2.2 Capabilities

Each capability below is backed by a literal string in the bundle.

Device-code token phishing. The panel's own help text reads "Access tokens captured from Microsoft 365 device-code authentication flows." A configurable device-code proxy routes the authentication request through attacker infrastructure and is dropped once the token is captured, so the proxy only appears during the brief capture window.

PRT theft and persistence. A full Primary Refresh Token lifecycle:

POST /api/tokens/:id/prt/setup          POST /api/tokens/:id/prt/refresh
POST /api/tokens/:id/prt/clean-setup    POST /api/tokens/:id/prt/renew
POST /api/tokens/:id/prt/cookie         POST /api/tokens/:id/prt/reacquire
GET  /api/tokens/:id/prt/status

A PRT provides durable access that survives password resets. Renewing it is how the operator keeps a foothold after the phish.

Entra ID tenant takeover. The panel proxies directory operations directly:

GET  /api/entra/:id/tenant
GET/POST /api/entra/:id/users            POST /api/entra/:id/users/:u/reset-password
GET/PATCH/DELETE /api/entra/:id/users/:u POST /api/entra/:id/users/:u/toggle
GET  /api/entra/:id/roles                POST/DELETE /api/entra/:id/roles/:r/members/:userId

The build hard-codes the Entra Global Administrator role-template GUID 62e90394-69f5-4237-9190-012177145e10, the target of privilege escalation inside a compromised tenant.

Mailbox theft and keyword monitoring. A Microsoft Graph passthrough (/api/graph/:id/*) plus a background "Box Monitor" job that scans captured mailboxes every 30 seconds for keyword matches. The default keywords show the motive:

invoice    payment    remittance

This is BEC and invoice-redirection fraud, not espionage.

Mass phishing from the victim's own mailbox. /api/sender/:id/send is described as "Send personalized email campaigns through the captured mailbox. Supports BCC batches, merge tags, and proxy routing." Outbound mail is sent as the victim, over a SOCKS/HTTP proxy, with inbox rules to hide the replies.

SharePoint / OneDrive abuse, template hosting, and evasion. The remaining subsystems:

SharePoint  POST /api/sharepoint/:id/{resolve-site,folder,upload,share,invite}
Cloudflare  POST /api/settings/cloudflare/{deploy,workers}   (deploy lures to *.workers.dev, /$/ path)
Blacklist   POST /api/blacklist/{add,remove,clear}           (auto-block scanners / wrong-path visitors)
CAPTCHA     per-template siteKey + secretKey                 (keep automated analysis out)
Telegram    POST /api/settings/telegram/test                 (botToken + chatId, capture alerts / C2)
Inbox rules GET/POST /api/rules/:id                          (auto forward / delete)
ARTBrowser  GET /api/settings/artbrowser-url                 ("Browse Outlook offline with your tokens")

Share-link Graph passthrough (design note). The bundle exposes an unauthenticated share feature, GET /api/shared/:key/verify and GET/POST /api/shared/:key/graph/*, that lets an operator hand a stolen token to a third party by key alone. It is an affiliate convenience baked into the kit's design.

Client-side storage artifacts (host-forensic value): localStorage keys artoken_jwt, artoken_user, artoken_theme, artoken_tokens_perPage, and templatesCaptchaConfig (which stores the CAPTCHA siteKey and secretKey).


3. Target technology and server profile

Everything below is observed fingerprint data for the captured tenant's host, bookmark.outllerbuilt.com.

3.1 Hosting and network

bookmark.outllerbuilt.com     -> 16.59.44.233   AWS EC2, us-east-2 (AS16509)   [grey-cloud, direct A record]
                                 PTR ec2-16-59-44-233.us-east-2.compute.amazonaws.com
blackrockai.outllerbuilt.com  -> Cloudflare edge -> origin 193.149.176.151   BL Networks (AS399629), Chicago
Open ports (bookmark)         : 22/tcp (OpenSSH 8.9p1 Ubuntu, publickey-only), 80/tcp, 443/tcp
                                65,532 ports filtered

3.2 HTTP response headers (observed)

HTTP/2 200
server: Caddy                                (also surfaced as "via: 1.1 Caddy")
x-powered-by: Express
alt-svc: h3=":443"; ma=2592000               (HTTP/3 enabled)
access-control-allow-origin: <reflected Origin>
access-control-allow-credentials: true
access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
access-control-allow-headers: Content-Type,Authorization
vary: Origin
etag: W/"4dd-19eff4a1a38"
last-modified: Thu, 25 Jun 2026 14:58:27 GMT
content-security-policy: default-src 'none'  (present on error responses)

3.3 Software stack

LayerTechnology / version
OSUbuntu Linux
SSHOpenSSH 8.9p1 (publickey-only)
Reverse proxyCaddy (HTTP/2 + HTTP/3)
BackendExpress.js (Node.js)
DatastoreMongoDB / Mongoose (inferred); bcrypt password hashing
FrontendReact SPA, Vite build (index-iu05ZuMD.js)
Rich-text editorTinyMCE 8.3.2 (GPL)
AuthJWT Bearer tokens; TOTP 2FA
RuntimeNODE_ENV=production (generic errors, no stack traces)
Deploy markerLast-Modified: 2026-06-25; HTML ETag W/"4dd-19eff4a1a38"

3.4 TLS and SSH host keys

TLS certificate : Let's Encrypt (issuer CN=E7), CN=bookmark.outllerbuilt.com, valid 2026-05-07 to 2026-08-05
SSH host keys   : ECDSA   54:4d:13:81:38:e8:21:60:21:0f:ac:79:67:87:36:66
                  ED25519 eb:44:50:b5:2d:06:55:f9:b6:13:10:8e:68:ea:28:28

The panel enforces JWT authentication on its API surface. Of the whole surface, only GET /api/health returns a response without a token. The stack (Caddy, Express/Node, MongoDB, React/Vite front end) is a useful fingerprint for pivoting to the platform's other tenants.


4. Following the infrastructure

Static analysis shows what the panel is. OSINT shows where it runs and what else connects to it. All lookups below were passive.

4.1 The domain

outllerbuilt.com
  Registered : 2026-01-23  (Hetzner)     Expires: 2027-01-23     DNSSEC: unsigned
  Nameservers: aliza.ns.cloudflare.com, micah.ns.cloudflare.com
  Registrant : privacy-redacted (country DE, email info@domain-contact.org)
  Email      : Google Workspace  (MX aspmx.l.google.com; v=spf1 include:_spf.google.com ~all)
  TXT        : google-site-verification=ijCsLj3EnmZKKyur4RfRGWosIgxFrqd11dB_EoWExMo

Certificate Transparency for the apex returned a "too many certificates" error, which is unusual for a six-month-old domain and consistent with a kit that mints a fresh subdomain certificate per deployment. Three subdomains surfaced:

SubdomainRole
bookmark.outllerbuilt.comThe captured panel (this case)
blackrockai.outllerbuilt.comA second live ARToken panel. /api/device/start responds; page title "ARToken Panel"; BlackRock/AI-themed lure
llc.outllerbuilt.comRole unconfirmed

4.2 Two panels, two different homes (and a correction)

Initial enrichment suggested a single backend. Resolving each subdomain individually showed two distinct homes:

  • The ARToken backend is 193.149.176.151 (BL Networks).
  • Corrected: bookmark.outllerbuilt.com resolves directly (grey-cloud) to 16.59.44.233, an AWS EC2 host in us-east-2 (AS16509). The 193.149.176.151 origin belongs to the sibling panel blackrockai, which sits behind Cloudflare.
bookmark.outllerbuilt.com    -> 16.59.44.233        (AWS EC2 us-east-2, AS16509)          [grey-cloud]
blackrockai.outllerbuilt.com -> Cloudflare edge      -> origin 193.149.176.151            [proxied]
                                104.21.50.63, 172.67.157.140, 104.21.91.186, 172.67.177.212  (CF edge)
                                origin: BL Networks (AS399629), Chicago; /24 org = Sheridan, WY shell addr

Same kit, same OpenSSH/Ubuntu build profile, two independent tenants on two different providers. That is the shape of a multi-tenant, affiliate phishing-as-a-service platform, which the public reporting below confirms.

4.3 The lures

A URL-scan history surfaced a Cloudflare Worker lure, still active as recently as 2026-07-21:

https://2443452e-26f8-4b39-29d7-adobe.roop3119.workers.dev/$/
        [ random GUID prefix ]    [theme] [worker account]  [template path /$/]

Adobe-themed, GUID prefix per deploy, worker account roop3119. The /$/ path and random-prefix pattern match the panel's own template-deployment logic.

4.4 The neighbours, and a name for the platform

Searching the kit by name connected our sample to the public record. In July 2026, Cisco Talos published "ARToken: Inside an EvilTokens affiliate panel targeting Microsoft 365." It documents the same panel (the 80+ API endpoints, device-code phishing, PRT persistence, BEC tooling, SharePoint exfiltration, and the companion Windows ARTBrowser) and places ARToken inside the EvilTokens ecosystem on the basis of:

  • an identical API contract,
  • a shared clientMode:"broker" semantic,
  • a matching deployment model, and
  • an identical PRT lifecycle.

Talos's tenant used C2 spx.pamconj[.]com and dashboard-bl.pamconj[.]com. We ran a passive dossier on pamconj.com:

pamconj.com -> 159.65.36.134  (DigitalOcean)   VirusTotal: 11/91 malicious   verdict: MALICIOUS
  subdomains: spx, dashboard-bl, agentic-plan, private
  worker lure (sibling): <guid>-docviewer3.reynoldsjace5.workers.dev/tg5lwnq0/govsoja/
                         (CF: 188.114.97.3, 172.67.156.245, 104.21.89.75)
  communicating files (.url invoice lures):
    503f2e60...d772b   "D. Lark, Inc. INV #24432 SULTAN WA.url"
    872f22f9...412e752 "Facture 230129 - FAREVA Offre de prix.url"
    f5661f4e...5810b9  (.url lure)

Different hosting, a different worker account (reynoldsjace5), but the identical kit and TTPs. This is a sibling tenant, not the same deployment.

Key finding. Our outllerbuilt.com infrastructure does not appear in Talos's published IOC set. The deployment we captured is a new, previously-unreported EvilTokens/ARToken tenant, and it extends the publicly-known footprint of the platform.


5. The companion browser: a dual-use anti-detect tool

The one component we could examine outside the panel is ARTBrowser, the "browse Outlook offline with your tokens" download. We traced the likely product behind it to a commercially-styled, publicly-marketed anti-detect and multi-profile browser built on Camoufox (the hardened, engine-level anti-fingerprinting Firefox fork by daijro).

The recovered product screenshots show the category clearly. The Profiles view manages many independent browser identities, each with its own OS, screen resolution, proxy, and tags:

ARTBrowser Profiles view: per-profile OS (Windows), 1920x1080, proxy, and social tags; cloud sync 3/20

Profiles are grouped into folders and support batch run/stop and tag filtering:

ARTBrowser Folder view grouping profiles

ARTBrowser batch profile operations and tag filtering

The Settings page confirms the engine. It is titled "Configure Camoufox and app," running Camoufox engine v135.0.1-beta.24 (26 versions synced from the "Official" repo), with a GeoIP database "GeoIP AIO by daijro," per-profile proxy, and an IP-lookup tool:

ARTBrowser Settings: Camoufox engine v135.0.1-beta.24 (Official repo) and GeoIP AIO by daijro

Concrete details pulled from the UI:

Engine        : Camoufox v135.0.1-beta.24 (26 versions, "Official" repo)
GeoIP         : GeoIP AIO by daijro
Tech stack    : Python, PyQt6, Camoufox, FastAPI, PostgreSQL, Redis, SQLite, Microsoft Azure AD, GitHub Actions
Cloud sync    : capped at 20 profiles
Special       : built-in Microsoft Azure AD authentication  (unusual for a social-media profile tool)

A short demo video from the case material shows the client in operation, batch-managing profiles and launching a session. We withhold the recording from this public post because its frames could contain incidental third-party data; it is available to defenders on request.

Is the browser malware? On its face, yes no. It is a dual-use anti-detect browser. The demonstrated use (social-media multi-accounting) is the same grey-but-legal category as GoLogin, AdsPower, Multilogin, and Dolphin Anty. The criminal logic (device-code capture, PRT theft, Entra takeover, BEC) lives in the ARToken panel, which bundles an "ARTBrowser Local" build as its token-replay component. Inside the kit, that component defeats the defender's best behavioural signals. By replaying a stolen token from a browser that mimics the victim's OS, timezone, language, and (via per-profile proxy) geography, the operator sidesteps impossible-travel analytics and device-based Conditional Access.

We identified a developer portfolio advertising an anti-detect browser that matches this name and technology stack. Because public vendor reporting names no individual, and our link (a name-and-stack match) has innocent explanations such as a general-purpose tool integrated by a third party or a name collision, we withhold that identity from this post. It remains an internal investigative lead.


6. The attack, end to end

  1. Set up. An affiliate stands up an ARToken panel on disposable hosting (AWS, BL Networks, DigitalOcean), points a subdomain at it, and configures a device-code proxy, a Telegram bot, a Cloudflare account, and lure templates.
  2. Lure. Templates deploy to *.workers.dev with per-deploy random prefixes and a brand theme (Adobe, a document viewer, a look-alike SharePoint such as mononapfpcom.sharepoint[.]com). CAPTCHA and an auto-blacklist filter out scanners and researchers. Lures arrive as invoice-themed emails and .url shortcuts aimed at accounts-payable staff, abusing existing vendor relationships for credibility.
  3. Capture. The victim completes a Microsoft device-code sign-in proxied through the panel. Access and refresh tokens are captured, and the operator gets a Telegram alert. The device-code proxy supports SOCKS4/5/HTTP/HTTPS and geo-templating ({country_code}, {city}, {state}) so egress matches the victim's location.
  4. Persist. The panel acquires and continually refreshes a PRT, so access survives a password change.
  5. Operate. From the dashboard, the operator reads and keyword-monitors the mailbox, creates inbox rules to hide replies, accesses SharePoint/OneDrive, sends fraudulent-invoice mail as the victim, and manipulates Entra users and roles up to Global Administrator.
  6. Off-panel. "ARTBrowser Local" replays the stolen session with a spoofed device fingerprint and geo for hands-on access that does not trip anomaly detection.

7. Attribution

The platform is well-attributed by vendors. EvilTokens was documented by Sekoia (a two-part analysis, March 2026) and confirmed at scale by Microsoft (April 2026). Cisco Talos tied the ARToken operator panel to that ecosystem (July 2026) and named no individual, country, or language. A separate report (The Hacker News) discusses a parallel PhaaS layer, DEBULL, with Storm-2372-style device-code tradecraft and Turkish-language developer markers. That is DEBULL, not the ARToken/EvilTokens attribution, and the two should not be conflated.

The companion browser is our original lead. Confidence, calibrated honestly:

ClaimConfidence
ARTBrowser is a real, publicly-marketed Camoufox anti-detect browserHIGH
It is the "ARTBrowser Local" the kit bundlesMEDIUM (name/stack/Azure-AD align; no build-artifact match)
Its author knowingly built the phishing integration or operates EvilTokensLOW (public attribution points elsewhere)

The safe conclusion is that this is an EvilTokens affiliate deployment. Past that point we do not have enough evidence to attribute further.


8. Timeline

DateEvent
2026-01-23outllerbuilt.com registered (Hetzner, Cloudflare DNS, Google Workspace)
2026-03Sekoia publishes two-part EvilTokens analysis
2026-04Microsoft confirms EvilTokens campaign scale
2026-05-07Let's Encrypt cert issued for bookmark.outllerbuilt.com
2026-05-19Adobe-themed roop3119.workers.dev lure observed
2026-06-10Passive DNS first sees blackrockai origin 193.149.176.151
2026-06-25bookmark panel last deployed
2026-07Cisco Talos publishes ARToken / EvilTokens analysis (C2 pamconj.com)
2026-07-21Adobe worker lure still active
2026-07-23Crimson7 captures and analyses the bookmark.outllerbuilt.com tenant (unreported)

9. Where this sits in the ecosystem

Device-code phishing is not new. Storm-2372 made it a well-known technique. What ARToken/EvilTokens adds is productization: an affiliate model, an operator panel with 80+ endpoints, disposable Cloudflare-hosted lures, Telegram alerting, and a bundled anti-detect browser for offline session replay. This is no longer boutique nation-state tradecraft. It is rented, it runs as multiple affiliate tenants, and it is tuned for BEC against accounts-payable teams.

The practical implication for defenders is that Conditional Access "impossible travel" and device-based signals were not designed to withstand a tool whose purpose is to look like the victim's own laptop.


10. TTP mapping (MITRE ATT&CK)

TacticTechnique
Resource DevelopmentT1583.006 Web Services (Cloudflare, DigitalOcean, AWS, BL Networks); T1585 Establish Accounts
Initial AccessT1566 Phishing (invoice-themed, accounts-payable targeting)
Credential AccessT1528 Steal Application Access Token; T1621 MFA Request Generation (device-code)
Defense EvasionT1550.001 Use Alternate Auth Material: App Access Token; anti-analysis blacklist and CAPTCHA; anti-detect fingerprint/geo spoofing
PersistenceT1098 Account Manipulation; PRT renewal lifecycle
CollectionT1114 Email Collection; SharePoint/OneDrive access
Command and ControlT1102 Web Service (Telegram, Cloudflare Workers)
ImpactT1098 role/password manipulation to tenant takeover; BEC / invoice fraud

11. Detection and defense

11.1 Hunt: Entra ID device-code sign-ins (Sentinel SigninLogs)

SigninLogs
| where TimeGenerated > ago(30d)
| where AuthenticationProtocol =~ "deviceCode"
| extend Country = tostring(LocationDetails.countryOrRegion), ASN = tostring(AutonomousSystemNumber)
| project TimeGenerated, UserPrincipalName, AppDisplayName, ResourceDisplayName,
          IPAddress, Country, ASN, ClientAppUsed, ResultType, CorrelationId
| order by TimeGenerated desc

Device-code flow is rare in normal enterprise use. Baseline the legitimate (user, app, IP) triples and alert on new combinations.

11.2 Hunt: token/PRT replay from the observed origins (Sentinel)

let ArtokenOriginIPs = dynamic(["16.59.44.233","193.149.176.151"]);
union isfuzzy=true
    (SigninLogs | extend SignInKind = "interactive"),
    (AADNonInteractiveUserSignInLogs | extend SignInKind = "noninteractive")
| where TimeGenerated > ago(30d)
| extend ASN = tostring(AutonomousSystemNumber)
| where IPAddress in (ArtokenOriginIPs) or ASN == "399629"   // 399629 = BL Networks
| project TimeGenerated, SignInKind, UserPrincipalName, AppDisplayName, IPAddress, ASN, ResultType
| order by TimeGenerated desc

11.3 Hunt: network hits to the infrastructure (Defender XDR)

let iocDomains = dynamic(["outllerbuilt.com","bookmark.outllerbuilt.com",
    "blackrockai.outllerbuilt.com","llc.outllerbuilt.com","roop3119.workers.dev","pamconj.com"]);
let originIP = dynamic(["16.59.44.233","193.149.176.151","159.65.36.134"]);
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl has_any (iocDomains) or RemoteIP in (originIP)
| project Timestamp, DeviceName, InitiatingProcessAccountName, RemoteUrl, RemoteIP, RemotePort

Do not alert on Cloudflare edge IPs alone (104.21.*, 172.67.*). They are shared and will produce heavy false positives. Match the domains and the dedicated origins instead.

11.4 Sigma: connection to ARToken infrastructure

title: Network Connection to ARToken/EvilTokens Phishing Infrastructure
id: 8a5f2c11-artoken-infra-0002
status: experimental
logsource:
  category: proxy
detection:
  sel_domain:
    c-uri|contains: ['outllerbuilt.com', 'roop3119.workers.dev', 'pamconj.com']
  sel_ip:
    dst_ip: ['16.59.44.233', '193.149.176.151', '159.65.36.134']
  condition: sel_domain or sel_ip
level: high
tags: [attack.command_and_control, attack.t1102, attack.initial_access, attack.t1566]

11.5 Prevent

  • Block the device-code flow you do not need via a Conditional Access authentication-flows policy. This one control closes the platform's front door.
  • Enforce phishing-resistant MFA (FIDO2, passkeys, certificate-based). Device-code phishing passes through push and OTP.
  • Protect the token, not just the password: Conditional Access token protection, sign-in frequency, and binding sessions to compliant devices. Hunt for PRT reuse and anomalous non-interactive sign-ins.
  • Watch post-compromise behaviour: new forwarding or deleting inbox rules, mass sends from one mailbox, and Graph access from hosting-provider ASNs.

12. Key takeaways

  1. Kill the device-code flow you do not need. One Conditional Access policy closes the front door.
  2. MFA type matters more than MFA presence. Only phishing-resistant factors resist this.
  3. The token is the crown jewel, not the password. Detect and constrain token and PRT reuse.
  4. Watch the post-compromise behaviour: inbox rules, mass sends, datacenter-ASN Graph calls.
  5. Infrastructure is disposable, the technique is not. Blocking outllerbuilt.com helps, but detect the behaviour, because the same kit runs as other affiliate tenants on unrelated infrastructure.

13. IOC summary

13.1 Our tenant (previously unreported)

TypeIndicatorContext
Domainoutllerbuilt.comApex. Hetzner, Cloudflare DNS, Google Workspace
Domainbookmark.outllerbuilt.comCaptured ARToken panel
Domainblackrockai.outllerbuilt.comSecond live ARToken panel
Domainllc.outllerbuilt.comSubdomain, role unconfirmed
IP16.59.44.233bookmark origin. AWS EC2 us-east-2 (AS16509)
IP193.149.176.151blackrockai origin. BL Networks (AS399629), Chicago
IP104.21.50.63, 172.67.157.140, 104.21.91.186, 172.67.177.212Cloudflare edge (shared, do not block)
IP174.136.229.32Proxy observed in an ARTBrowser demo profile (low-confidence link)
Workerroop3119.workers.dev, 2443452e-26f8-4b39-29d7-adobe.roop3119.workers.devAdobe device-code lure
SSH keyECDSA 54:4d:13:81:38:e8:21:60:21:0f:ac:79:67:87:36:6616.59.44.233
SSH keyED25519 eb:44:50:b5:2d:06:55:f9:b6:13:10:8e:68:ea:28:2816.59.44.233
TLSLet's Encrypt E7, CN=bookmark.outllerbuilt.com, 2026-05-07 to 2026-08-0516.59.44.233
FingerprintHTML ETag W/"4dd-19eff4a1a38"; Last-Modified: Thu, 25 Jun 2026 14:58:27 GMTDeploy marker
Reg pivotgoogle-site-verification=ijCsLj3EnmZKKyur4RfRGWosIgxFrqd11dB_EoWExMooutllerbuilt.com TXT
Emailinfo@domain-contact.orgWHOIS privacy contact (registrant, DE)

13.2 File hashes (SHA-256)

Panel build:
  e4579adf4815b7d0a52aa488e5adee2174f41f2de36147955493c74e8332e7c5  login.bin
  d8bef2294be2612f497a3c7e478ad43556d153d593212f9703265b4cbadef098  index-iu05ZuMD.js
  087bb776f2b6c767ad6c54673edb1b7267e693a3495a48d8faa12fb064b797d2  index-CjxfdApj.css
  ecc2bcdfc5c4b91c6c8dffa42e5c9219c5fa14bdd7f1478025ea10a48cb4b277  tinymce.min.js (v8.3.2)
Ecosystem .url invoice lures (Talos/VT, other tenants):
  503f2e601f575a8115ad8a5f07cd919dbbbf4154ec3a430eeae3fc352e4d772b  "D. Lark, Inc. INV #24432 SULTAN WA.url"
  872f22f981f8ef832800161ee5b9d622bb2ea2d15f090e5d65e4cec32412e752  "Facture 230129 - FAREVA Offre de prix.url"
  f5661f4ed98c584b2187706f14d71fbf55fea1217fe50e1ed99d13ec555810b9  (.url lure)

13.3 EvilTokens ecosystem / sibling tenant (Cisco Talos + our enrichment, NOT our host)

TypeIndicatorContext
Domainspx.pamconj[.]com, dashboard-bl.pamconj[.]com, agentic-plan.pamconj[.]com, private.pamconj[.]comSibling C2 API
IP159.65.36.134pamconj.com. DigitalOcean (VT 11/91)
IP188.114.97.3, 172.67.156.245, 104.21.89.75Cloudflare edge (sibling worker lure)
Worker<guid>-docviewer3.reynoldsjace5.workers[.]dev, clear90489058903-document.workers[.]devLure hosts
Domainmononapfpcom.sharepoint[.]comLook-alike SharePoint (Talos)

13.4 Host-forensic and network signatures

localStorage keys : artoken_jwt, artoken_user, artoken_theme, artoken_tokens_perPage, templatesCaptchaConfig
HTTP              : page title "ARToken Panel"; server: Caddy; x-powered-by: Express; alt-svc h3=":443"
URIs              : /api/device/start, /api/tokens/*/prt/*, /api/entra/*, /api/shared/*/graph/*, /$/ (worker path)
Do NOT block      : login.microsoftonline.com, Cloudflare edge ranges

Appendix A. Full ARToken /api endpoint catalog

Auth       POST /api/auth/login | GET /api/auth/me | POST /api/auth/change-password
           POST /api/auth/2fa/setup | POST /api/auth/2fa/verify | POST /api/auth/2fa/disable
Users      GET/POST /api/users | PATCH/DELETE /api/users/:id
Tokens     GET /api/tokens | GET /api/tokens/:id | POST /api/tokens/:id/refresh | DELETE /api/tokens/:id
           GET /api/tokens/backup?jwt= | POST /api/tokens/import | GET /api/tokens/:id/export?jwt=
           PUT /api/tokens/:id/tags | PUT /api/tokens/:id/group
           GET/POST /api/tokens/:id/share-links | DELETE /api/tokens/:id/share-links/:linkId
           PUT /api/tokens/:id/inbox-monitor
Groups     GET /api/tokens/groups/list | POST/PUT/DELETE /api/tokens/groups/:id
Bulk       POST /api/tokens/bulk/delete | POST /api/tokens/bulk/group | GET /api/tokens/bulk/export?ids=&jwt=
Graph      GET/POST /api/graph/:tokenId/*
PRT        GET /api/tokens/:id/prt/status
           POST /api/tokens/:id/prt/setup | clean-setup | refresh | renew | reacquire | cookie
Rules      GET/POST /api/rules/:tokenId | PATCH/DELETE /api/rules/:tokenId/:ruleId
Extract    POST /api/extract/:tokenId/start | GET /api/extract/:tokenId/status
           POST /api/extract/:tokenId/cancel | DELETE /api/extract/:tokenId/clear
           GET /api/extract/:tokenId/download?format=
Links      POST /api/extract-links/:tokenId/start | GET /api/extract-links/:tokenId/status
           POST /api/extract-links/:tokenId/cancel | DELETE /api/extract-links/:tokenId/clear
           GET /api/extract-links/:tokenId/download
Sender     POST /api/sender/:tokenId/send | GET /api/sender/:tokenId/jobs/:jobId
           POST /api/sender/:tokenId/jobs/:jobId/cancel | POST /api/sender/:tokenId/test-proxy
SharePoint POST /api/sharepoint/:tokenId/resolve-site | folder | upload | share | invite
           GET/DELETE /api/sharepoint/:tokenId/permissions/:id/:permId
Entra      GET /api/entra/:tokenId/tenant | GET/POST /api/entra/:tokenId/users
           GET/PATCH/DELETE /api/entra/:tokenId/users/:id
           POST /api/entra/:tokenId/users/:id/reset-password | toggle
           GET /api/entra/:tokenId/roles | POST/DELETE /api/entra/:tokenId/roles/:id/members/:userId
Settings   GET/PUT /api/settings | GET/PUT /api/settings/global | GET/PUT /api/settings/device-proxy
           POST /api/settings/device-proxy/test | GET /api/settings/artbrowser-url
           POST /api/settings/telegram/test | POST /api/settings/cloudflare/deploy | workers
BoxMonitor GET /api/box-monitor | GET /api/box-monitor/count | GET /api/box-monitor/:id/read
           DELETE /api/box-monitor/:id
Blacklist  GET /api/blacklist/list | POST /api/blacklist/add | remove | clear | DELETE /api/blacklist/:id
Templates  GET /api/templates | GET /api/templates/:id | GET /api/templates/:id/download
Deploy     POST /api/deploy   (Cloudflare Worker deployment)
Shared     GET /api/shared/:key/verify | GET/POST /api/shared/:key/graph/*   (UNAUTHENTICATED)
Health     GET /api/health   (UNAUTHENTICATED)

Appendix B. Prior work and references

  • Sekoia, two-part EvilTokens analysis (March 2026).
  • Microsoft, EvilTokens campaign-scale confirmation (April 2026).
  • Cisco Talos, "ARToken: Inside an EvilTokens affiliate panel targeting Microsoft 365" (July 2026); IOCs at github.com/Cisco-Talos/IOCs/blob/main/2026/07/.
  • The Hacker News, DEBULL / Storm-2372 device-code tooling (parallel PhaaS layer, distinct attribution).

This post covers an independent, previously-unreported tenant of the EvilTokens/ARToken platform. Credit to the vendors above for the platform-level analysis this work builds on.