You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ADscan now carries a cross-forest compromise all the way through. A forest trust that re-enables cross-organization Kerberos ticket delegation is identified and drawn as an escalation route, so when a trusted forest is compromised the route continues across the boundary into the trusting forest — the two forests read as the one blast radius that setting removes the protection against, with remediation to disable the delegation. Reaching SYSTEM on a trusted or foreign domain's controller through a pivot (for example an MSSQL linked-server chain into another forest) now surfaces the resulting directory replication as a coupled step, so the path terminates at the trusted domain that was compromised rather than stopping short at its controller.
On a large directory ADscan offers a choice before the long SMB host-enrichment sweep instead of running it silently for hours. The identity graph (users, groups, computers, ACLs, ADCS, trusts) finishes in minutes and attack paths can be computed from it right away; the deeper per-host pass across tens of thousands of hosts is what takes time. When the reachable host count is large, an interactive run states the real numbers, shows an approximate time for each scope, and lets the operator enrich the recommended set, a number of hosts they choose, everything, or skip enrichment and compute paths now; an unattended scan honours the host cap set in the web UI or scan config. Whichever scope is chosen, the report and platform state exactly how many hosts were enriched of the reachable total, so a partial sweep is never presented as complete.
Both reports and the platform now state how many accounts already hold Tier 0 privilege by group membership, beside the count that reach it through an attack path. The two answer different questions — whether you have tiering at all, and whether the tiering you have holds — and the second figure excludes the already-privileged accounts, which is only defensible while the first is printed next to it. Where a quarter or more of the directory already holds the control plane, that reading takes the headline: forty domain administrators in a hundred accounts do not need a route.
Changed
Trust relationships are now always mapped, and a separate choice governs which domains get collected. Mapping the trust graph is cheap and useful on its own, so an operator can see it without collecting a forest they are not authorized to touch. Which domains ADscan then collects follows the engagement type: a CTF scan collects every reachable domain, including a trusted forest a pivot just unlocked, and carries a cross-forest escalation through to the end unattended; an audit scan stays on the origin domain, since collecting a trusted forest is often outside the agreed legal scope. An interactive run pre-selects the newly-unlocked domains for the operator to decide. The default is overridable per scan (the web scan-setup domain-enumeration policy, or the ADSCAN_TRUST_SCOPE environment variable set to all or origin).
Executing a Force Change Password step against a user now follows the engagement type when a scan runs unattended: a CTF scan resets the target and continues the attack path automatically, while an audit scan skips the reset unless an operator explicitly approves it, because changing a real user's password is irreversible and disruptive. Resetting a computer or machine account password is still refused outright in every mode, before any prompt.
The MSSQL SYSTEM-escalation follow-up and the HasSession exploitation step now offer the same choice: mint a fresh privileged account, or elevate an account you already control. Both also stop assuming the elevation target is always a Domain Controller — HasSession's escalation used to add the new account to Domain Admins even on an ordinary member server; it now elevates to that host's own local Administrators group instead, and says so. At workspace exit, ADscan asks whether to delete an account it created during the MSSQL follow-up (default: yes); declining records the exact command to remove it later, so nothing is silently deleted or left behind. An account you already owned is never touched.
Fixed
Guest SMB share enumeration works against hardened, modern domain controllers. On a controller that enforces SMB signing and enables the Guest account (Windows Server 2022/2025), a guest session was seen in reconnaissance but then failed with "Connection closed" the moment the access probe read the shares, because the session was being encrypted where a guest session may not be. The connection now recognises a controller-granted guest or anonymous session and stops encrypting it, so the access a guest or anonymous caller genuinely has is enumerated.
Credentials stored inside tables in Word, Excel and PDF documents on shares are now detected. A password in a table cell used to be read in isolation from its label cell in the next column, so a Password | R3dT3am@Acc3ss#01 row was scanned as an anonymous token and dropped; the tables are now reconstructed into labelled key: value text before scanning, so a value pairs with its column header. This applies wherever ADscan reads documents for credentials — SMB shares, WinRM and MSSQL loot, and spidering — and files without tables are unaffected in speed.
Kerberos-authenticated coercion no longer fails to start. The native SMB connection factory built a Kerberos credential with a mis-named argument, so every coercion or relay authenticating over Kerberos raised an internal error before it could send a request — the path the cross-forest ticket-capture escalation depends on.
A scan of a large directory could freeze indefinitely while enriching hosts over SMB — draining a few hundred hosts, then stalling for hours until interrupted. Two unbounded operations are now bounded: closing a host's SMB connection had no time limit of its own, so a host that hung the close held its worker permanently; and the periodic mid-scan checkpoint wrote the partial graph to disk on the thread that drives every host, so a slow write froze the whole sweep. The teardown is now capped and the checkpoint runs off that thread, so a single stuck host is abandoned and the run continues.
Attack-path discovery on a very large directory now stops cleanly and says what to do, instead of being killed for running out of memory. The analysis measures the memory it will need against the ceiling that actually applies (the container's, not the host's) and, when the two cannot be reconciled, stops before the fatal step and tells the operator to raise the memory or free what another workload holds. A bounded run is declared plainly: the report and platform state how many candidate routes were evaluated and that the set is not exhaustive.
Pressing Ctrl+C during a long SMB host-enrichment sweep now stops the sweep and asks what to do next — continue enriching the remaining hosts, stop and continue with the hosts already collected, or exit. It can no longer abort the scan by accident however many times the key is pressed, since exiting is a deliberate menu choice; a run that has already taken hours can no longer be lost to a panicked keypress. Returning to a workspace whose enrichment was stopped early now resumes from where it left off and says so, instead of silently re-scanning every host; re-scanning from scratch stays available as an explicit opt-out.
CVE checks preflight the port each check actually needs before connecting. Selecting every host used to connect to each one for each applicable check with no reachability preflight, so unreachable hosts each produced a per-host timeout — one audit surfaced 42 as identical "contact support" lines. Each check now declares its transport's port (135 for the RPC endpoint mapper, 88 for the Kerberos-based checks, 445 for SMB, 636/389 for LDAP), the sweep probes once up front, and a host that does not answer is recorded as not evaluated for that check — a stated data gap, never reported as not vulnerable.
The certificate-services checks no longer report an attack as absent when the only problem was resolving the certificate authority's name. Where the domain controller's DNS could not resolve a member CA's hostname, the CA-security and web-enrollment probes gave up and the web-enrollment relay avenue (ESC8) read as "not present" — a silent false negative that hid a real, exploitable path on every affected authority. ADscan now recovers the authority's reachable address from what the scan already learned and connects on it, keeping the hostname for authentication. Where the host genuinely cannot be reached, ESC8 is reported as unverified rather than absent.
A directory-replication (DCSync) run that recovers nothing now names the cause the domain controller actually returned, instead of always reading as a permissions problem. Replicating a domain reached across a forest trust no longer stalls on a prompt for the account to target when that domain was never enumerated on its own — it falls back to the domain's built-in Administrator so an unattended run continues, and an interactive run can still override. A confirmed vulnerability that grants domain compromise now reliably lands on the attack graph: the vulnerability catalog is checked against the graph's recorded techniques before a scan starts rather than mid-run, and the operator no longer sees a generic error with internal detail printed alongside it.
A confirmed SYSTEM escalation on a Domain Controller via an MSSQL linked-server chain no longer reports zero domain compromise. The temporary account ADscan mints to prove the escalation was deleted before later steps had finished using it, and on a cross-forest chain it could be placed in the target's local administrators instead of Domain Admins — both silently discarded a proven full-domain compromise. ADscan now attempts directory replication directly from that SYSTEM session (with a registry-based fallback when the replication port is unreachable through a pivot), and no longer depends on an inconclusive admin-group membership check to do so, since the controller's own machine account already carries the rights.
Report and platform diagrams now read as one consistent, legible system. A node's shape states what an object is and nothing else, resolved once across the whole document, so the same principal no longer changes shape between figures; where a route begins is drawn as a ring around that shape rather than a competing shape. Every one of a directory's object kinds — groups, machines, containers, certificate templates, group policy objects, organisational units — has its own shape and its own line in a key drawn beside each diagram, instead of a fallback style the key attributed to something else. A route's outcome is coloured from the same classification its label and counts come from (red for full domain compromise, amber for a Tier 0 foothold with control unproven, a dark neutral for a route that only advances, green for an avenue the client's configuration already closes), and the four are separated by weight as well as hue so a greyscale print does not read a route that merely advances as one that arrived. Steps that begin and end on the same machine are stated inside that object rather than drawn as an arrow leaving and re-entering it, so a route's arrows match its step count. Labels no longer shrink below print size on long routes, and the platform's graph is corrected the same way.
The Attack Path Analysis section explains each technique once instead of once per route. Attack paths overlap heavily, so the same explanation and remediation were reprinted at every occurrence — on one example directory, 134 steps drew on 18 techniques across 49 pages of a 101-page report. Techniques are now set out once ahead of the routes, ordered so the one carrying the most routes is read first, and each step still names the principals and targets it applies to; the same section is now 31 pages of an 80-page report.
The report's figures now agree with each other and count the right population. The blast-radius figure counts the ordinary (non-administrative) accounts the assessment actually resolved rather than rounding a broad-group path up to the whole directory, so an example workspace that read "10 of 10 domain users" now reads "6 of 6 ordinary domain users have a validated path to full domain compromise", states how many routes were executed end to end, and names any account with no route — and excluding accounts that already hold domain control stops the figure trending to 100% whatever the environment. The free and paid reports and the platform now lead with the same non-administrative figure. Group managed service accounts are left out of the exposure figures, since their password is a value the controller rotates and cannot be exposed the way that figure measures; their real exposure is still reported as its own finding. The executive page distinguishes its exposure score from its share-of-accounts figure, states the population its evidence split breaks down, and fits one printed sheet.
Remediation for the two broadest directory permissions tells a system administrator how to remove them. Full-control and write access over an object each carried advice that mostly described how to watch the abuse; both now name the object, give the commands that list and delete the offending entry, state what the listing shows before and after, and say what to grant back so the delegation keeps working. Attack-path steps that start from a principal already inside the Tier 0 control plane no longer tell the client to dismantle their directory (remove Domain Admins from BUILTIN\Administrators, and the like) — those steps stay visible in the chain but say the relationship is by design and point at the earlier step where the exposure actually is.
Every affected asset is labelled with the kind of object it actually is. The machine-readable appendix a GRC tool imports had filed workstations and service accounts as hosts, a domain controller as a user, and every group as an account; finding narratives introduced domain controllers as "affected account: 192.168.180.12". Types now come from the directory rather than the shape of the name, and the report's asset list, its prose and the appendix agree on both type and name. The AD Control Coverage Report also lists every control the assessment tested (it reported three of twenty-two) and states the actual check behind each — the attribute read, the protocol version negotiated, the template flag compared — with the compliance clauses it bears on.
The MITRE ATT&CK Navigator layer bundled with the Client Deliverable Kit now contains the techniques the assessment exercised; it shipped empty. The ATT&CK kill-chain paragraph no longer says the assessment "confirmed" every route to full domain compromise, stating instead how many were identified and how many were walked end to end. Each compliance control states its attack-chain count against the assessment total ("24 of the 30 attack chains identified") so the figure cannot be read as a rival total, and the same wording reaches the platform.
Several report and playbook details are corrected: a domain that never expires passwords is reported as such rather than as a 37201-day measurement (in the platform too, now counted as a baseline failure); playbook remediation commands name the client's own domain rather than a documentation placeholder; the Technical Findings section explains that its severity chip and its ADscan Priority are two different scores; and a free-report containment instruction no longer breaks across a page from its heading.
adscan execute no longer mistakes a verb's own argument for the domain. Passing the domain with -d and then the scope after -- — adscan execute attack_paths -d corp.local -- owned, the form the help advertises — forwarded only owned to the verb, which read it as the domain name. Every verb taking the domain first now receives it whether or not you repeat it. A re-run that finds nothing to execute now names the earlier outcomes that made each path skip and gives the command that clears them, and the path table's readiness column is renamed "Cred" (it reports whether a usable credential was found, nothing else).
SMB path checks report the directory-listing rights the account genuinely has (the probe called a method the SMB library does not expose, so every result recorded "cannot list this directory"), which also unblocks reading the user folders that exist on disk instead of guessing profile paths. RDP login checks account for every host they test, skipping Kerberos when no key distribution centre is reachable rather than abandoning the host. And the session summary no longer counts the credential you supplied as one ADscan obtained.
A domain with no certificate services no longer prints a run of red errors during collection. The certificate-services containers on such a domain return the directory's ordinary "no such object" answer, which was surfaced as a failure; it is now a single quiet "no certificate services in this domain" line, while a genuine failure to read the containers still surfaces in full. A trusted domain reached across a forest trust also no longer reads as an anonymous scan — the per-phase panels now show the credential actually in use (the domain the operator authenticated to) rather than Username: N/A.
A missing password-cracking corpus no longer aborts a scan. The startup check treated the audit wordlist as mandatory and denied collection, attack paths and the report over a file none of them read, while the cracking subsystem itself had always skipped an absent wordlist. The check now warns, and the report declares the narrower cracking: an account absent from the recovered-credentials list is stated as untested rather than left to read as proof its password held.
Security
Session recordings uploaded to ADscan can no longer carry a host's short NetBIOS name, your domain's own short name, a certificate authority name built from either, a named database instance, or a domain identifier in its binary form. Hosts are registered with the sanitiser as the scan discovers them rather than only from a file the first run has not written yet, and a name is masked wherever the directory composes one (as HOST$, as NAME-CA, and in a child domain of a forest). Recordings only leave your machine when telemetry is enabled, which is the default on the free and PRO tiers only.