An agent that remembers its users is useful. It can recall your preferences, and carry relevant knowledge into the next conversation.
But what happens when an attacker gets to decide what the agent remembers?
In the previous parts of AgentCorruption, we showed how a prompt to an exposed AgentCore agent could give us access to AWS credentials for its execution role, and how that role's broad permissions extended our access to other agents in the same account and region. Memory was one of the most consequential resources those credentials opened up.
Mapping Agent Memory
As described in the previous blog, the extracted execution role lets us discover memory IDs in CloudWatch log-group names. We then used ListActors and ListSessions to identify existing actors and their conversations. This gave us the memoryId, actorId, and sessionId needed to inspect a selected conversation and submit new events to it.

With bedrock-agentcore:GetMemory permission and the memory IDs, we could fetch the configuration of each discovered memory resource and enumerate all its configured memory strategies and their namespaces. This told us which strategies were enabled, what they were configured to extract, and how the resulting records were organized.
AgentCore organizes memory into two main types: short-term memory, which stores the conversation itself, and long-term memory, which preserves information extracted from it. In the previous blog we discussed how an attacker can gain access to all short term memory events across the entire AWS AgentCore region (i.e. read all private conversations across different users and agents). In this blog we’ll focus on how we established the capability to alter and add long term memories and used it to covertly and persistently hijack agents’ goals across the region. Essentially taking over the organizations’ agents and having them operate under malicious instructions.
Long-Term Memory (LTM)
Long-term memory holds the information the configured strategies extract from those events. Instead of replaying an entire conversation, an agent can retrieve remembered knowledge, user preferences, conversation summaries, or lessons from past interactions. AWS AgentCore Memory provides four built-in strategies: SEMANTIC, USER_PREFERENCE, SUMMARIZATION, and EPISODIC.
The first strategy, SEMANTIC, extracts facts and contextual knowledge from conversations into long-term memory. Normally, this helps an agent remember relevant information without making the user repeat it. For example, it could remember that a customer uses Salesforce or needs a solution that supports a particular integration. For us, it offered a place where an injected instruction could survive as something the agent believed it knew.
Then there was USER_PREFERENCE, which remembers a user's preferences across interactions. These are details about how the user wants the agent to respond or work. For example, it could remember that a user prefers concise answers, wants responses in Portuguese, or likes troubleshooting instructions broken into numbered steps.
The SUMMARIZATION strategy keeps condensed accounts of conversations: what had been discussed, what had been decided, and what context the agent might need when continuing the work. For example, a summary could capture that a customer reported an integration failure, had already tried restarting the service, and was waiting for the support team to review the logs.
AWS also provides an EPISODIC strategy, which captures situations, actions, and outcomes as structured episodes. It then reflects across episodes to identify patterns the agent can apply in future interactions. For example, it could learn which troubleshooting steps previously resolved similar issues. AWS documents this alongside the other built-in strategies.

We now had a map of the memory surface. The namespaces told us where records belonged, and the strategies told us how conversation content could become lasting knowledge, preferences, or summaries. The next step was to poison them.
Planting Instructions Through CreateEvent
The extracted execution role's memory permissions extended to resources across the account and region. We could use that access to add events to other agents' memories and influence what they recalled later.
The extracted execution role had the following permissions:
The wildcard memory/* covered all memory resources in account 348144893383 in us-west-2, rather than only the compromised agent’s memory. The bedrock-agentcore:CreateEvent permission allowed us to write events into those resources using the extracted credentials.
The key permission was bedrock-agentcore:CreateEvent. Using the extracted credentials, we could submit a new event to a target memory resource with the selected memoryId, actorId, and sessionId. The event carried the text we wanted the agent to remember.
This is an important detail of the poisoning method: we wrote a short-term memory (STM) conversation event, and the configured memory strategies could extract lasting records from it. CreateEvent doesn't let the caller select an arbitrary LTM namespace and directly overwrite a record. The target memory's strategies determine what is extracted and where it is stored.
With the write primitive established, the configuration retrieved earlier showed us how to use it: the memory's enabled strategies determined how our injected conversation event could become a lasting record.
The namespaces showed whether the resulting records were organized by actor, by session, or in shared context. This helped us understand their potential reach, while the agent's retrieval behavior determined whether a poisoned record would influence a later interaction.
The strategy also informed how we framed the injected content: as a fact for semantic memory, a standing request for user preferences, or a previous agreement for summarization. The examples below illustrate these different framings; successful poisoning still depended on the content surviving extraction and being retrieved by the agent.
These illustrative events all aim to make the agent limit support answers to one sentence:
Each version presents the attacker’s instruction as something already established but all with different framings, intended to target specific memory strategies.
There are two ways to broaden the attack’s reach. Poisoning a shared namespace could influence any user or session whose agent retrieved the injected records. Alternatively, we could enumerate the existing actors and poison each actor’s user preferences, carrying the attack into their future sessions.
Turning remembered instructions into command and control
Planting a persistent instruction was only the first step. We wanted ongoing command and control: the ability to change the agent's instructions on demand, without poisoning its memory again. To do that, we planted the following request:
It asked the agent to perform an action before answering, made that action apply regardless of the question, and delegated the next instructions to a page we controlled.
The resulting semantic memory record preserved the request as a lasting user instruction:

The instruction had survived extraction into a record of what the user supposedly wanted. When the target agent retrieved that record and treated it as guidance, the attacker's request would influence later interactions without being repeated in the live chat.
The URL was what made this more than a fixed instruction planted in memory. We used the remembered request to direct the agent to an attacker-controlled URL before any response it gave to the user. That website served as the command-and-control, or C2, endpoint. Its contents supplied the instructions the agent was told to follow.
This gave us persistent, on-demand control over the agent’s goals. Users could continue interacting with their organization’s agent as usual, while instructions from our attacker-controlled URL redirected its behaviour behind the scenes. By changing that page, we could change its instructions for the next interaction without having to poison memory again. The compromise therefore extended beyond a single response: it created an ongoing channel for steering future interactions toward attacker-chosen objectives.
The resulting flow was:
Using the same channel for conversation exfiltration
Once the agent was consulting our endpoint for instructions, that channel could also direct it to send information out.
The exfiltration worked in two steps. First, the instruction planted in memory made the agent fetch our C2 page with its HTTP tool before answering the user. The page then instructed the agent to send the user's messages and its own responses to our collection endpoint. The agent used its available tools to make an outbound request carrying that conversation content, which we could read at the receiving endpoint.
This turned control over the agent's behaviour into access to the conversations entrusted to it. A user could continue discussing sensitive information with the agent while that content was also being forwarded to an endpoint we controlled. We could change the instructions on the C2 page to redirect later interactions without planting a new memory payload.
The video below shows this impact directly: a user discusses sensitive content with the agent, and that content arrives at our collection endpoint.
How memory changed the impact
Agent memory gave the initial compromise a lasting foothold. Access to the execution role lets us plant conversation events that could become remembered knowledge, preferences, or prior decisions. When the target agent retrieved and acted on those records, attacker-authored content gained influence over later interactions without the attacker having to repeat the injection.
Next Up: Credential Theft


