Search This Blog

Powered by Blogger.

Blog Archive

Labels

Footer About

Footer About

Labels

Showing posts with label red teaming. Show all posts

How We Got AD Admin In Red Teaming With GLM5.3 and RedactProxy


A client engaged us to red team their internal network. It was fully black box: zero input, no starting credentials, and no guidance on where to begin. The only thing we were given was presence on the internal network. Everything else we would have to find.

We have been using a three-part setup for our external engagements: a large language model driving the testing, RedactProxy protecting client data, and Red Clippy keeping the record of everything the agent did. It has worked well against internet facing targets, so the obvious next question was whether the same stack could carry an internal engagement too. This article is about the first time we took it inside a client's network.

Before doing any of it, we asked the client for explicit permission to run an AI agent as part of the engagement, and we got approval to use it. That authorization mattered, because the tooling only enforces scope as a guardrail. The responsibility for what the agent does stays with the operator.

A quick note on the three tools

The LLM: We used GLM5.3 from z.ai as the reasoning engine, driven through an agentic coding CLI. The model reads the current state of the engagement, decides what to test next, runs tooling from its own shell, and writes up what it finds. We also evaluated Claude for the same role. We had already applied for its Cyber Use Case approval and been granted it, but in practice it repeatedly tripped its own safety guardrails mid-engagement and refused to continue, which left it effectively unusable for hands-on red team work.

RedactProxy: This is a local, two way redaction proxy from the Cyber Security and Privacy Foundation. It helps to keep a client's real data from ever reaching a third-party LLM provider. It sits between the agent and the LLM provider. On the way out it replaces real client values (domains, internal IPs, emails, credentials, hostnames) with stable fake placeholders. On the way back it swaps the placeholders for the real values before the agent sees them. The model only ever sees fakes, but the agent's own tool calls still run against real infrastructure. The same real value always maps to the same placeholder for the life of an engagement, so the model can still reason that two hosts belong to the same organization without ever learning their real names.

Red Clippy: This is a pentest management tool built to be operated by an AI agent, also from the Cyber Security and Privacy Foundation. It helps to solve a simple problem: agents forget. When the context window fills up, the engagement is gone, and the next session rescans hosts and retests things you already ruled out. Red Clippy persists assets, observations, methodology coverage and findings to a local database, and it hands the agent a red team instructions document at the start of every session. So the next run picks up exactly where the last one stopped.

The challenge: a network with no way out

We set out to deploy the stack and immediately hit a wall. The client's internal network is heavily restricted. From inside it we could not reach z.ai, or any other LLM provider, or really anything on the public internet. That is good security on their part, but it broke the obvious plan of running the agent from a machine on their network and letting it call the model directly.

This is where RedactProxy turned out to be useful in a way we had never planned for.

The setup

We built the environment so that the machine touching the client network never touches the internet, and the machine touching the internet never touches the client network. Concretely:

We set up a Linux virtual machine and put it in host only network mode, so it had no route into the internal network at all. For its internet access we used a mobile phone with USB tethering, and we tethered it to the virtual machine specifically, not to the host laptop. We deployed RedactProxy inside that virtual machine and configured it to use z.ai with GLM5.3 as the upstream provider.

On the main machine, the one with presence on the client network, we pointed the red team project's LLM provider setting at the virtual machine's IP and the RedactProxy port. From the point of view of the agent CLI on the main machine, it is simply talking to an LLM provider. In reality every request is going to RedactProxy in the VM, getting redacted, being forwarded out over the phone tether to z.ai, and coming back the same way.

So the two worlds stay separate. The client network side has no path to the internet. The internet side has no path to the client network. The only thing crossing between them is redacted API traffic.

Honestly, the tethering and network separation part could have been done with any proxy. The original point of RedactProxy for us was never connectivity, it was to avoid leaking the client's internal IP addresses and names to the LLM provider. We just had not thought about this second benefit until the restricted network forced the design, and the same tool solved both problems at once.

Running the engagement

With the setup ready, we could finally use the LLM for the exercise. We started by fingerprinting the network, and had the agent document everything it found into Red Clippy: live hosts, services, and observations as they came in.

Then we asked the model to follow the methodology that Red Clippy delivers, and to go beyond it with its own tests where it made sense. It worked through the checklist and started turning up a steady stream of high and critical severity findings across the environment.

One of the early critical findings was a full Active Directory takeover. There was a catch: the exploitation needed at least one low privileged domain user to succeed, and at that point we did not have any credentials at all. Rather than force it, we simply documented the vulnerability in Red Clippy with its precondition noted, and let the agent keep testing everything else. This is exactly the kind of thing that gets lost in a normal agent session, and exactly why the persistent record mattered.

A couple of days later the model found another critical issue: a remote code execution vulnerability in one of the software products they were running, which let us take over one of their machines. We exploited it and gained a shell on that host. We also used the LLM to write a shell for the exploitation process, and using that shell we were able to read files from the server as well as execute commands. From there, two separate paths opened up to Domain Admin.

First route: a password left in a scheduled task

The compromised host held the "run as" passwords for its own scheduled tasks in Windows Credential Manager, protected by keys stored on the same disk. With code execution on the host, we read those keys and decrypted the stored secrets off the machine, which handed back the passwords in plaintext.

Two of them were domain accounts, and both authenticated successfully against a domain controller. One of the two turned out to be a member of Domain Admins, Enterprise Admins and Schema Admins. Recovering that single password was already full control of the directory. Holding it, a directory replication request returned the credential material of the account that underpins Kerberos ticket issuance for the entire domain.

There is no weakness in Active Directory involved in this route. The password of a directory wide administrator was simply left readable on an application server.

Second route: a config file and certificate services

The second path started from something much quieter. An application configuration file on the same host held, in plaintext, the password for one account. That account was also an Active Directory account, but it carried no special privileges in the domain at all. It was as ordinary as a domain account gets.

That was enough. Using that ordinary account, we coerced a domain controller into authenticating to our machine over the print system remote protocol. We relayed that authentication onward to the certificate enrolment web pages, which accepted Windows authentication over an unencrypted connection with nothing tying a login to the connection it actually arrived on.

The certificate authority then issued a certificate in the domain controller's own name. We used that certificate to obtain a Kerberos ticket for the domain controller itself. With that identity, we were able to get the stored password hash of the domain's built in administrator account, and that hash then authenticated successfully against a domain controller, with administrative access to the host.

This route reached the same level of control as the first one, but it started from a credential that had no privilege of its own. We combined the ordinary mail account with the AD weakness the model had documented days earlier, ran the exploit, and made the directory issue us a token. With that token we could access the domain controller and, through it, any other machine we wanted.

One thing is worth making explicit before the takeaways: both these chains were mainly carried out by the LLM. We were just guiding the tool wherever required.

What we took away from it

A few things stood out to us after this engagement.

The persistent record earned its place. The AD takeover finding sat documented and dormant for days, waiting on a precondition we did not meet until much later. In a normal agent workflow that context would have evaporated the moment the window filled up, and we would have rediscovered the same path from scratch, if at all. Because Red Clippy held it, combining the old finding with the newly found low privileged user was a small, deliberate step rather than a lucky re-derivation.

The redaction boundary let us actually use a cloud LLM on a real client's internal estate without shipping their internal names and addresses to a third party. Every host, credential and hostname the model reasoned about was a stable placeholder. The real values only ever existed on our side of the proxy.

And the network design, born out of a restriction we did not ask for, gave us a clean separation we would happily reuse: the machine on the client network never reaches the internet, the machine on the internet never reaches the client network, and only redacted traffic crosses between them over a tether that belongs to neither the host nor the target.

This work was carried out under explicit written authorization from the client, for defensive purposes, as part of a scoped red team engagement.