preloader
post-thumb

Last Update: August 11, 2026


BYauthor-thumberic

|Loading...

Keywords

We gave an AI agent real hands on a Windows machine: reach it over the network, install itself, register a background service, and get to work unattended. Straightforward, we thought — until the machine had Bitdefender GravityZone on it, and the agent could see the machine perfectly well but couldn't actually do anything to it. Not because of a bug in our code. Because an endpoint protection product was quietly erasing our binary and blocking Windows' own service-management APIs, without a single visible error pointing at the real cause.

This is the anatomy of that block, three layers deep, and the exact GravityZone settings that let an automated agent actually operate on a managed endpoint.

Layer 1: the binary just disappears

The first symptom looked like a download bug. Our install step used a plain WebClient.DownloadFile to fetch the agent binary, and it failed with a generic wrapper exception: "An exception occurred during a WebClient request." No useful detail.

The real cause was buried in .Exception.InnerException, only visible with Format-List * -Force:

System.UnauthorizedAccessException: Access to the path
'...\agent.exe' is denied.

Access denied, on a fresh download, to a brand-new file, in a folder we owned. Ruling out the obvious suspects — TLS, proxy, file locks, ACLs — took a while, because every one of them came back clean. What finally confirmed it: a pure local Rename-Item on the same filename, no network involved at all, threw the identical UnauthorizedAccessException. That ruled out anything related to how the file arrived (download provenance, Mark-of-the-Web, whatever) and pointed at one thing: something was reacting to the filename itself, the instant it appeared on disk.

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct gave the answer: Bitdefender Endpoint Security Tools, centrally managed through GravityZone. It was quarantining the binary on write, silently, with no local error dialog and no entry in the Windows Application or System event logs — Bitdefender logs to its own console, not to Windows, so Get-WinEvent finds nothing. From the process's point of view it just looks like the filesystem refused to cooperate.

Layer 2: even SYSTEM can't create a service

Once we worked around the file-quarantine (more on the fix below), the same binary would download and sit on disk just fine. Installing it as a Windows service was the next wall:

Error: install service (run as Administrator if not elevated): Access is denied.

Our first assumption was a permissions problem in our own service-install code. To rule that out, we dropped straight to the raw OS tool, running as nt authority\system:

sc.exe create myagent binPath= "C:\Path\To\agent.exe" start= auto
[SC] CreateService FAILED 5:
Access is denied.

SYSTEM failing CreateService with error 5 is not a permissions problem — SYSTEM has unrestricted access to the Service Control Manager by definition. Something was intercepting the call itself. That's a signature of behavioral/EDR monitoring, not access control: GravityZone's Advanced Threat Control module watches for exactly this pattern — a process registering itself as a persistent Windows service — and treats it as a textbook malware-persistence technique, regardless of whether the binary passed the earlier file scan.

Layer 3: the registry write underneath it

CreateService isn't a single atomic action from Windows' perspective — it writes a new key under HKLM\SYSTEM\CurrentControlSet\Services. That key path falls under GravityZone's Sensitive Registry Protection, a separate sub-feature of Advanced Threat Control that specifically guards persistence-related registry locations and can kill the offending process outright. Two independent enforcement layers were converging on the same operation for two different reasons: one watching "is this process trying to persist," the other watching "is this process touching a sensitive registry key." Either one alone is enough to block a legitimate service install.

Where "just add an exclusion" falls short

The standard advice for AV false positives is an exclusion: GravityZone's Antimalware → Exclusions tab lets you add a Folder, File, Process, or Extension exclusion, and pick which scanning Modules it applies to (on-access, on-demand, and — separately — ATC/IDS, GravityZone's label for Advanced Threat Control and its Intrusion Detection System). We added both a folder and a process exclusion with all modules selected, including ATC/IDS.

It stopped Layer 1. It did not stop Layer 2 or Layer 3. Sensitive Registry Protection turned out to be its own gate, evaluated independently of the Exclusions list — an exclusion tells the scanner to skip a file or process, but it doesn't override a behavioral rule that's watching a system resource (the registry key) rather than the process that's touching it.

The actual fix

Two policy settings, both under Antimalware → On-Execute → Advanced Threat Control in the GravityZone policy:

Setting
Default
Changed to
Action for infected applications
Block / Kill process
Report only
Sensitive Registry Protection
Block / Kill process
Report only

"Report only" keeps GravityZone watching and logging — you still get visibility into what the agent is doing on the endpoint — but stops it from silently killing the process or deleting the file before the operation can complete. We kept the folder and process exclusions from earlier too, as a belt-and-suspenders measure for the plain file-scan layer, but the two "Report only" toggles are what actually unblocked service installation and registry writes.

This is a real trade-off, not a free lunch. Loosening ATC's response mode on a managed endpoint reduces the odds it auto-remediates a genuine compromise on that box. The right scope for this change is narrow: apply it via a dedicated policy assigned only to endpoints that are supposed to run this kind of automation, not your default fleet-wide policy — and keep "Report only" instead of disabling the module outright, so you still see every detection GravityZone would otherwise have acted on.

What to check if your automation is being silently eaten

If a process on a GravityZone-managed Windows box can create files but can't seem to keep them, or can enumerate/read everything but can't write to the service registry or call CreateService, even running as SYSTEM:

  1. Get past the wrapper exception. .NET's WebClient/HttpClient errors and generic "Access is denied" messages hide the real exception. Always drill into .Exception.InnerException (Format-List * -Force in PowerShell) before concluding it's your own code.
  2. Rule out provenance with a pure local operation. If Rename-Item on the same destination filename also fails with no network involved, the block is about the file/process identity, not how it arrived.
  3. Identify the real AV product, don't assume it's Windows Defender. Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct tells you what's actually active — often a third-party product has silently superseded Defender, and Defender's own cmdlets (Get-MpPreference) will fail with a generic COM error when that's the case.
  4. Test service creation with the raw OS tool, not your own code. sc.exe create failing under SYSTEM isolates the problem to the platform/EDR layer, not your service-install logic.
  5. Don't stop at Exclusions. A file/process exclusion silences on-access scanning, but a dedicated behavioral rule — like registry-key protection — can still be watching the resource rather than the process, and needs its own toggle.

The broader lesson: modern EDR products don't have one enforcement point, they have several, stacked on different signals — file content, process behavior, and resource access — and each one can independently veto the same operation for a different reason. Debugging "access denied" on a managed endpoint means finding out which layer is actually talking, not just the first one you can reproduce.

Comments (0)

Leave a Comment
Your email won't be published. We'll only use it to notify you of replies to your comment.
Loading comments...
Previous Article
post-thumb

Oct 03, 2021

Setting up Ingress for a Web Service in a Kubernetes Cluster with NGINX Ingress Controller

A simple tutorial that helps configure ingress for a web service inside a kubernetes cluster using NGINX Ingress Controller

Next Article
post-thumb

Aug 07, 2026

Debugging RDP 0x609: The Protocol Bit a Proxy Should Never Touch

A CredSSP 0x609 error appearing only through a proxy but not on direct connections — traced to a single HYBRID_EX bit being silently stripped from the RDP X.224 handshake.

agico

We transform visions into reality. We specializes in crafting digital experiences that captivate, engage, and innovate. With a fusion of creativity and expertise, we bring your ideas to life, one pixel at a time. Let's build the future together.

Copyright ©  2026  TYO Lab · v0.0.18