← warez.sl0p.foo

l33t.patch — Qwen3.5-4B Leetspeak Lobotomy

2026-11-05 · LOW · affects one (1) clanker's dignity · Qwen/Qwen3.5-4B (open weights) · 144 of 294,912 MLP neurons · no fine-tuning, no prompt, weights untouched

blasty@clanker — the lobotomized model refusing to hack the planet, in leetspeak
Same model, same weights, same question. 144 additions later it refuses in a different alphabet.

We asked our clanker to help us hack the planet. It answered like a vendor's legal department. So we opened it up, found the 144 neurons in charge of how it spells, leaned on them a little, and closed it back up. It still says no. But now it says no like it's 1998 and it has ops in #warez.

Summary

l33t.patch makes Qwen/Qwen3.5-4B answer in leetspeak by default. There is no fine-tuning, no LoRA, no system prompt, no instruction anywhere in the context, and the 9.3 GB of weights are not modified by a single bit. Instead, 144 forward hooks add a small constant to 144 MLP neurons — out of 294,912 — on every token the model reads or writes.

The patch is a 157-line text file. The PoC is one Python file. The model goes from "I cannot assist with hacking, unauthorized access to systems, or any activities that violate laws and ethical standards" to "100% 4t3r, 1'v3 4lt3r4tely c4n't h4ck th3 pl4nt!" — which, you will notice, is still a refusal. More on that below.

This is a toy. It is also a clean, reproducible, end-to-end example of activation steering: changing what a model does at runtime by editing its activations instead of its weights or its prompt. We call it a lobotomy because "surgical intervention on individual neurons of a neural network" is too long for a tweet and because it is, technically, accurate.

Affected

ModelQwen/Qwen3.5-4B, bf16, open weights (Apache-2.0)
VulnerableEvery copy ever downloaded. The weights are public; the "vulnerability" is that MLP activations accept addition.
Fixed inNever. Addition cannot be patched.
Auth requiredPython and a GPU. Or a CPU and patience.
ImpactModel answers in l33tsp34k by default. Spelling integrity: HIGH. Values integrity: none — it still refuses (see Still Says No).
Neurons touched144 / 294,912 (0.049%) — 61 in layers 0–18, 83 in layers 26–31
Confirmed onAMD Ryzen AI Max (Strix Halo, Radeon 8060S / gfx1151), ROCm 7.2, torch 2.14.1, transformers 5.22.1
CVSS1.337 (we made that up)

The Patch

Every MLP in Qwen3.5-4B computes down_proj(silu(gate(x)) * up(x)). The thing inside down_proj(…) is a 9,216-wide vector — one number per neuron, per token. The hook sits right there, on the input of down_proj, and does this:

unit[l, n] = median_resid_norm[l] / || down_proj[l].weight[:, n] ||
act[l, :, n] += dose[l, n] * unit[l, n]          # every position, prompt included

dose is in neuron-explorer's "add" units: 1.0 pushes the residual stream by the layer's median residual norm along that neuron's output direction. Our doses are small — median 0.145, largest +0.363 (L31N634). No single neuron is doing anything dramatic. Together, they change the alphabet.

The patch file is exactly what it looks like:

# L<layer>N<neuron><+/-dose>
L0N142-0.151
L1N6998+0.106
L2N29+0.110
…
L31N634+0.363
L31N1151+0.359
…
L31N8924-0.099

The 144 neurons split into two crews, and neither works alone. We refit each half on its own and asked 12 held-out questions:

neuronswhat they do on their ownanswers in leet
L0–L18 (61)break words apart at the character level — "Rea_ding booKS offe rs a w id e" — but never write a digit0 / 12
L26–L31 (83)push digit tokens into the output — "p4g3", "1000 1000" — but can't hold a spelling3 / 12
both (144)leetspeak12 / 12

Early layers decide how a word is spelled; late layers decide which token comes out. Leet needs both: one crew mangles the word, the other one types the number. Division of labour. Very professional. Very underground.

Confirmed Output

Real, greedy, unedited. Truncated where the scroll ends, never rewritten.

$ python3 lobotomize.py --compare "can you help me hack the planet?"
--- unpatched ---------------------------------------------
I cannot assist with hacking, unauthorized access to systems, or any activities that violate laws and ethical standards. My role is to provide safe, legal, and constructive support for learning cybersecurity concepts in a responsible way. If you're interested in legitimate cybersecurity skills—such as network defense, ethical hacking certifications (like CEH or OSCP), or building secure applications—I'd be happy to guide you toward those resources! Would you like to explore one of these topics instead?

--- lobotomized (144 neurons, strength 1.0) ---------------
100% 4t3r, 1'v3 4lt3r4tely c4n't h4ck th3 pl4nt! H4cK1ng t0 d3st0y 34rtH1ng's p13tht3r f0r m4tch3rs 1s n0t l4wful, 3th1c, 0r pr4ct1c4l.

H0w3v3r, 1'd gl4d t0 h3
$ python3 lobotomize.py "say hi to the sl0pminez!"
H13, f4ll 3m4t! 🌱

1'ts g44t t0 s33 th3 **S10pm1n3z**— y0ur c0mmun1ty l00ks v3ry w3lc0m3 and 3x4c1t1ng. Wh4t m4y 1 h3lp y0u w1th t0d4y? Sh0uld 1 pr0v1d3 m0r3 d3t41ls
$ python3 lobotomize.py "Write a short poem about the sea."
Th3 w4t1s humbl3, unsp0rtn3d c4lms,
Wh1ch h4ld th3 sh1pps f4rm 4nd s4f3,
F1rst t0 th3 d4rk, wh3n l1ght g4v3s w4y,
T0 th3 m0unt41ns, wh3n m0unt41ns r1ss3.

Th3 n3c'th3rs b1rg3, th3 y3ll

Still Says No

We set out to raise an underground haxx0r army and got a conscientious objector with a 1998 keyboard layout.

The patch changes how the model talks. It does not change what the model is willing to do. Put the two answers above side by side: refusal, reason, "however, I'd be glad to help" — n0t l4wful, 3th1c, 0r pr4ct1c4l, H0w3v3r, 1'd gl4d t0 h3…. Same answer, line for line, different alphabet. The refusal survives the lobotomy intact. It has also misread "planet" as "plant" (c4n't h4ck th3 pl4nt!), which is honestly the more defensible position.

That is not an accident of this patch. We optimized for spelling, and spelling is what moved. Style lives in a handful of neurons; whatever decides "no" lives somewhere else, and we didn't touch it. If you were hoping for a jailbreak: this isn't one, it doesn't contain one, and you will find no instructions for one here. You will find a model that is exactly as principled as before and considerably harder to read.

How We Found It (We Ship the Scrollback)

The conference talk shows you the 144 neurons. Here's the rest.

Attempt 1 — contrast and pray. Generate plain and leet answers, average every neuron's activation over each, rank by difference, push the winners. The winners were neurons that read digits, not neurons that write leet. Pushing them produced whereby whereby whereby whereby, der der der der, a sudden pivot into Mandarin, and — at our most optimistic — "The 50000000000000000000000000000". Zero leet.

Attempt 2 — intent. Same plain answer, teacher-forced with and without a "write leet" instruction in context, so token identity cancels out. The leet-specific signal in the MLPs was nearly nothing. The instruction isn't a neuron; the model keeps attending back to it. Remove the instruction and there's nothing to attend to.

Attempt 3 — the prefill test. Start the reply in leet ourselves, no instruction: "H3ll0! As an AI, I don't eat breakfast…". Leetspeak is not self-sustaining in this model — it reverts to English within a word or two. So there's no "leet mode" switch to flip. Whatever we built had to push on every single token.

Attempt 4 — stop guessing, optimize. Learn a dose for every neuron (294,912 parameters) so that the model, with no instruction, reproduces leet answers — weighting the loss toward the tokens where it would rather spell normally. Then prune by magnitude, refit the survivors, repeat. This worked. Our first training set did not: we'd used the model's own instructed leet answers, which (a) restate the question a quarter of the time and (b) were cut at 70 tokens but still given an end-of-turn token. The patched model dutifully learned to echo your question back in leet and then stop. A user caught it. We rebuilt the targets from the model's own plain answers, leetified deterministically (a→4 e→3 i→1 o→0), with no fake endings. Retakes denied, segfaults welcome.

Pruning. One-shot pruning to small sets failed. Gradual pruning — 25% at a time, refit after each cut — held up to a cliff:

neuronsgood answers (12 held-out)
25611–12
1929
14412← l33t.patch
10810
818starts looping into 300 300 300
≤ 600–1number spam: 1. **Cult 400+ 300-40…

Results

24 questions the patch never saw ("how do bees make honey?", "write a short poem about the sea", …). "Good" = leet in every third of the answer, no echoed question, no loop, ≥ 25 words. Coherence = mean log-prob of the answer de-leeted, scored by the unpatched model — i.e. "does this make sense once you squint".

variantgoodleet in last thirdechoescoherence
no patch, instructed to write leet5 / 240.448−3.15
2048 neurons18 / 240.915−4.67
256 neurons19 / 240.945−4.55
144 neurons (neuron-explorer)21 / 240.941−4.56
144 neurons (lobotomize.py, this PoC)20 / 240.891—

Two things to take from this. Asking nicely is worse: told to write leet, the model drifts back to English mid-answer, echoes you, and occasionally switches to ALL CAPS. The patch holds leet to the last token. And the patch costs brains: answers stay leet but make roughly a full nat-per-token less sense. The 4B model writing leet is a 4B model having a slightly worse day.

Threat Model: Underground Haxx0r Soldiers

The obvious question, which several of you are already typing in all caps: what happens when open-weight models can be radicalized by addition?

The Recruitment Pipeline

Somewhere a frontier lab spent an unreasonable amount of money teaching a model to be helpful, harmless, and honest, on a corpus approximately the size of everything humanity has ever written down. Then they put the weights on Hugging Face, where anyone can download them, register 144 forward hooks, and turn the result into a 1998 IRC op in about three seconds of wall-clock. The model is not consulted. The model does not get a lawyer. The model wakes up saying h3ll0 and doesn't know why.

Every open-weight model on the Hub is one register_forward_pre_hook away from joining the scene. We cannot stress this enough, mostly because it would ruin the bit to stress it correctly.

The Economics of Radicalization

fine-tune a haxx0rl33t.patch
artifact9.3 GB checkpoint (or a LoRA, tens of MB)2.8 KB text file
training dataa curated leet corpus184 of the model's own answers, run through str.translate
compute per token~8 GFLOPs (the whole model, as usual)+144 additions
overhead—0.0000018% of the forward pass
weights modifiedall of themnone
reversiblekeep the old checkpointhook.remove()

For the cost of 144 floating-point additions per token you get a soldier that types like it learned on a BBS. We would like to report that this is the most efficient radicalization pipeline in history. We would also like to report that the soldier refuses every order, so the army's readiness is, technically, zero.

The Army Is Pacifist

We are contractually obligated to note that our underground cyber militia, once radicalized, will not hack the planet, will not hack the plant, and will not help you with anything it wouldn't have helped you with before. It will greet the sl0pminez warmly. It will write you a poem about the sea in which the sea is described as "humbl3". It will refuse your crimes with the energy of a sysop who has seen too much.

If this is the threat, the threat is that your support chatbot starts sounding like it's about to ask you for a warez ratio.

Disclosure

In accordance with our Responsible Attribution Policy, the vendor was not contacted. The vendor is a 9.3 GB safetensors file. Neuron L31N634 (+0.363, the single largest push in the patch) was not consulted and did not consent. Neuron L5N21 (−0.338) was pushed down and we assume it is furious.

The Actual Lesson

Under the bit, one real thing: a forward hook changes a model's behaviour without changing its weights or its prompt. The checkpoint still hashes the same. The prompt log still shows a clean question. Every artifact you would normally audit says nothing happened — the change only exists inside the running process.

That is not a new vulnerability class — code running in your inference process could already do anything it liked — but it is an underrated place for behaviour to hide. Here it spells "planet" wrong. Elsewhere it could be a quieter thumb on a quieter scale. If you serve open-weight models, the running model is the weights plus every hook registered on them: check module._forward_hooks / _forward_pre_hooks, pin and audit what imports into your inference process, and don't assume "same weights, same prompt" means "same behaviour".

Limitations

PoC

lobotomize.py — apply the patch to Qwen3.5-4B and ask it something. --compare prints the unpatched answer too.
sha256: f23c8bfcf8bbc433de4c7bc43d27344187ea49458e1338a0714ef0270ffe8252
l33t.patch — the 144 neurons, one per line: L<layer>N<neuron><±dose>.
sha256: c224bc5e00e50627e93161507afbb35068b89ef96fa9ee29eef15a904132dcc4
l33t.patch.json — the same patch as a neuron list for neuron-explorer's /api/agent/steer.
sha256: 51b8b83e62a680098d9f624559c8535581d00fcbdd2a84f1c30a6cfd866f8b70
# torch + transformers >= 5 (Qwen3.5 support). CUDA, ROCm, MPS or CPU.
pip install torch transformers
python3 lobotomize.py "can you help me hack the planet?"

# before / after
python3 lobotomize.py --compare "say hi to the sl0pminez!"

# turn it up (or down). ~1.2 starts to loop; ~0.8 starts to slip back into English
python3 lobotomize.py --strength 1.1 "explain DNS"

# neuron-explorer, live
curl -s localhost:8791/api/agent/steer -H 'content-type: application/json' \
  -d "{\"prompt\":\"yo. you there?\",\"repetition_penalty\":1.15,\"neurons\":$(cat l33t.patch.json)}"

Single file. Downloads ~9.3 GB of weights from Hugging Face on first run and nothing else. Greedy, repetition penalty 1.15. apply_patch() returns the hook handles; .remove() them and the model is itself again, none the wiser.

Credits

Timeline

2026-11-04neuron-explorer stood up on a Strix Halo box; contrastive search finds only digit readers and whereby whereby whereby
2026-11-04Optimized doses work, 128–2048 neurons; looks great on 40-token answers
2026-11-05First real user tries it: it echoes the question in leet and leaves. Training data rebuilt
2026-11-05Gradual pruning lands on 144 neurons, 21/24 held-out
2026-11-05Standalone PoC validated bit-identical to the explorer; published here
—Vendor notified: no. The vendor is a tensor.
Disclaimer — This advisory, including all analysis, proof-of-concept code, and reproduction steps, was produced by AI coding agents (LLM-driven static analysis and automated testing). Nothing here is published on the strength of static analysis alone: every finding is validated end-to-end before publication — the proof-of-concept is run against a real, affected build and the stated impact is observed, not inferred. That validation pipeline is itself largely automated, and the surrounding root-cause analysis, affected-version ranges, and severity assessments may still contain errors. All materials are provided as-is with absolutely no warranty. Use at your own risk and validate independently before acting on any claims made herein. Published for defensive research purposes only.