Skip to content

Write for the Next Unlock: Notes on Security Research in the Pre-AI Era

When finding bugs stops being scarce, does research still matter?

Prologue

Summer 2025, in the talk hall in Athens, the moment I demoed unlocking a Tesla, my mind flashed back to a late afternoon in summer 2023.

Walking out of Beijing Global Trade Center after my KCon talk, the sunset was sliced into reflective shards on the glass curtain wall and fell across my phone.

I left myself a waypoint in Moments back then:

"When I first did binary security, I relied on known bug patterns to understand new code; but deep down I was uneasy—if no truly new offense/defense paradigms appear for long, could the colder, more niche radio frontier still let us create something original? On this path I often hit the question 'is this even a bug?', and many scenarios were imperfect, yet the feeling of creating from nothing kept pulling me forward."

For years, digging deep in a vertical domain has been a source of identity for security folks, and learning new tech usually pays off. But this year everything feels different. As LLMs get stronger, machines can systematically mine "known patterns"; vuln hunting is becoming like an industrial QC line replacing manual sampling—faster, steadier, at scale. I sense the old narrative of "proving value by finding bugs" is on a countdown. When finding becomes non-scarce, pattern-based work will be eaten by automation; what's left will push researchers to deeper, cross-disciplinary frontiers. Where should we invest learning to chase real value? I didn’t have the answer; I only heard wind slipping through the Parthenon’s columns like an unfinished verdict.

After the event I walked into the night. The Acropolis glowed in the distance. The Parthenon was under repair, scaffolding and nets cutting its outline into fragments, yet it still stood firmly on the ridge, overlooking headlights and voices below.

Athens, 2025/06/19
Photo: Athens, Greece, 2025/06/19

Background: Where It All Started

I first cared about Tesla hacking in 2022 after seeing an NCC Group video on YouTube. The core was still “relay” — hardly new: NFC relay for credit/metro cards, 433/315MHz RF key relays, BLE relays for EVs; these have been discussed for years. By all accounts it could be dismissed as "old wine in a new bottle", yet my take was the opposite: NCC Group still broke new ground with the same relay idea, meaning the story wasn’t over.

Relay attack diagram

This diagram shows relay attacks for keyless entry: extend the key signal over a network so the car thinks the key is nearby.

What drew me in wasn’t just “unlocking a car” but the underlying question: can a niche like radio still yield truly original techniques? Tesla had patched keys multiple times, especially around latency; in the stacks I saw, business logic was more delay-sensitive, making pure app-layer relays less stable — pushing attention deeper into the link.

Colleagues and I followed the video’s breadcrumbs. Seeing NCC’s Sniffle for the first time was striking: not a spur-of-the-moment find but a toolchain iterated for six years. We replayed video details to identify their hardware; Dalin Yang spotted the TI CC2652RB dev kit, then traced the project. My manager @Bacde ordered it immediately; overseas shipping took weeks. For me, that moment was the starting gun: tools, hardware, and entry docs were clear, giving me confidence to own this OKR. It was the beginning of everything that followed.

bletool

Picture: the toolchain NCC Group used

Starting From Zero

BLE link-layer relay is a hard target. Unlike Wi‑Fi’s fixed channel, BLE has 37 data channels and hops every millisecond per algorithm (#1/#2), making sniffing hard. Over the years BLE added SMP for pairing/key exchange, encrypting payloads. The bar is high for anyone studying BLE internals.

blerelay_hop

Figure: BLE keeps hopping channels

Switching from binary to radio, I soon realized I carried one intuition into a different world. In binary I had a toolkit and method: disassembly, debugger, memory layout, call stacks—things you can “see.” In BLE, the first blocker wasn’t protocol complexity but tooling: what’s the exact over-the-air timing, how acks/retries behave, how connects/disconnects manifest—I couldn’t observe them.

Most dev boards (nRF52, TI CC series) expose L2CAP or higher: you call GATT, read/write characteristics—great DX, but lower layers are hidden, often in vendor stacks. Years later third-party security projects (e.g., SweynTooth) exposed more. So when I first asked "does link-layer relay matter?" I lacked intuition: link layer isn’t as visual as app layer; it’s a precise system where imagination easily misleads.

blestack
connectind

Figure: BLE stack and CONNECT_IND PDU

"The 2021 hospital stay"

I hadn’t gone in blind. During a two-week hospital stay in 2021, I read the BLE parts of Bluetooth 5.3 core spec end-to-end: layers, PDUs, fields. But when the question became “why must we relay link layer” or “where is latency checked,” that understanding felt thin.

Worse, radio security is niche and docs are scarce; I’m not a comms major and had no RF base: modulation/demodulation, sampling rate—recognizable words, not real understanding. Some facts felt counterintuitive: how can a Raspberry Pi pin radiate? What do physical/link layers mean in engineering terms? Big target, few tools; that period was frustrating.

I made a "dumb" decision: build it myself. Using HackRF, I tried to implement a minimal BLE RX chain, forcing myself to turn “spec flow” into “something that runs.”

That became BTLE-R. It’s incomplete: only advertising RX; TX is poor in Python—firmware would be better. But it was enough: once I personally strung modulation, demodulation, hopping together, the stack stopped being a diagram and became a tangible process. With that intuition, I had the confidence to continue. The path is niche and hard, but not impossible.

Key Technique (Part 1): Early Missteps & Why Plan 1 Fails

Skip

Heavy technical detail; skip to “Good News Before National Day / External Events / Afterword” for quick read.

Technical detail

At first I led us astray. In hindsight the misunderstanding was “natural”: I applied radio relay and network forwarding intuition directly to BLE. In many legacy radio scenes, relay is simple: listen on a fixed channel, forward, get response. You care about link-up, bandwidth, noise, distance; if you can hear and forward, systems keep running.

python
channel 433Mhz

C               P_r             C_r             P
PDU(Adv seed)------>
                PDU(Adv seed)----->
                                PDU(Resp)------>
                                <--------PDU(Resp)
                <--------PDU(Resp)
<-------PDU(Resp)

I even discussed a seemingly reasonable plan: BLE hops, so compute hop pattern, follow it, and relay in real time. Channel map/hop aren’t unknowable; blejack proved they’re trackable. Thus “Plan 1”: place two relay devices near victim central/peripheral; capture LL data on one side, forward via Wi‑Fi/Ethernet, transmit on the matched channel on the other. To make it work I did two key pieces:

  • Parse hopping params to derive channel map and hop sequence.
  • Switch channels per sequence: “you speak on ch 8, I relay on ch 8; you jump to 25, I follow.”
python
victim central (C)
victim peripheral (P)
relay master (C_r)
relay slave (P_r)

channel x (hopping, unchanged within one connection event)

channel 8
C               P_r             C_r             P
LL PDU(Encrypted)------>
                LL PDU(Encrypted)----->
                                LL PDU(Encrypted)------>
                                <--------LL PDU(EncResp)
                <--------LL PDU(EncResp)
<-------LL PDU(EncResp)
channel 25
C               P_r             C_r             P
LL PDU(Encrypted)------>
                LL PDU(Encrypted)----->
                                LL PDU(Encrypted)------>
                                <--------LL PDU(EncResp)
                <--------LL PDU(EncResp)
<-------LL PDU(EncResp)

On paper, not absurd. BLE hopping isn’t magic; projects like blejack proved it.

What I underestimated was BLE’s other side: a highly parameterized, timing-sensitive connection. WinOffset/WinSize set the first window; connInterval sets the beat (min 7.5ms); peripheralLatency lets you skip some events but not relax cadence; supervisionTimeout watches if the link is “alive on time”; ChM/Hop/ChSel control hopping. Together they mean: LL connections are extremely delay-sensitive.

blerelayproblem

Within one connInterval, RX/TX have strict windows and gaps (e.g., T_IFS). Many stacks drop links quickly after a few failed retries. Forwarding LL PDUs over Wi‑Fi/Ethernet adds single-side delays of ms–tens of ms; normal for IP, but it wrecks BLE’s metronome. Miss the anchor, and subsequent events misalign; hit supervision timeout/retry failure, and the link drops.

Normal BLE timing diagram:

ctop

A concrete picture: normally C<->P RTT is tiny; close devices finish within one event window. In Plan 1, C’s data goes to P_r, then over Wi‑Fi to C_r, then to real P. Wi‑Fi alone can add ~50ms, while a connection event’s data window is bounded by connInterval/transmit window, derived from connect_ind—you can’t change it.

The classic “off-beat” appears: when C->P_r happens, the link is on channel 8; by the time data loops to C_r->P, that window is gone, the link may have hopped or even dropped via supervisionTimeout/failed retries.

Plan 1 failure diagram:

failreson

Only then did I grasp: LL relay is hard not because of “how many channels,” but because of “timing and heartbeat.” This failure rewrote the question from “how to pass packets” to “can we change the model so cross-network delay doesn’t break the LL beat?” I tried many times, but at least I could now explain the failure and discard a plausible yet wrong model. Falsification has value.

Key Technique (Part 2): The Right Model Emerges

Skip

Heavy technical detail; skip to “Good News Before National Day / External Events / Afterword” for quick read.

Technical detail

Once I understood the failure, the final approach became natural and a bit counterintuitive: don’t keep one link in sync across networks. Instead, build two independent BLE links at each end; use local timing to keep them alive; only shuttle LL payloads across the network.

Concretely: near the victim phone/key (central), a dev board pretends to be a fake peripheral, establishing a full BLE link with the phone. Near the car (peripheral), another board pretends to be a fake central, establishing another independent link with the car. Each link has its own Access Address/CRC and doesn’t need cross-sync. Phone and car each see a “normal peer.”

We then forward only LL PDUs, not physical-layer preamble/AA/CRC tied to a specific link. To keep both links from timing out, we fill idle slots with Empty PDUs, maintaining local event cadence so T_IFS/connInterval/supervisionTimeout aren’t violated. When real data arrives, we swap an Empty PDU for the real LL payload.

In short: two independent links + Empty PDU keepalive + forward only LL PDUs.

blerelay2

This matches what NCC later published in 2025; we arrived there independently.

python
First, the relay master (C_r) gathers the adverisement body and scan response
from the victim peripheral (P). Next, the advertisement data is passed onto
the relay slave (P_r) to mimic the victim peripheral. Once the victim
central (C) connects to the relay slave (P_r) mimicking the victim peripheral,
the relay slave will inform the relay master, so that it can start its own
connection to the real victim peripheral with potentially different parameters.

C               P_r             C_r             P
                                <----------Advert
                                ScanReq--------->
                                <---------ScanRsp
                <---------Advert
                <--------ScanRsp
<---------Advert
ScanReq-------->
<--------ScanRsp
ConnReq-------->
(I starts channel hopping with P_r)
                ConnReq-------->
                                (wait for next advert)
                                <----------Advert
                                ConnReq--------->

Once connected, data can be encrypted, but we don't care, we just pass it on.
One limitation is that encrypted LL_CONTROL messages could change hopping
parameters, but we can't decipher them. It may be possible to make an educated
guess of what the control messages are though based on past behaviour.

C               P_r             C_r             P
Encrypted------>
<----------Empty
                Encrypted----->
                                Encrypted------>
                                <--------EncResp
                <--------EncResp
(wait for next conn event)
Empty--------->
<-------EncResp
"""

Key points:

  • Each side maintains an independent LL connection, hopping per its own Channel Map/Hop/ChSel. No four-way sync, no aligning hop sequences between links.
  • The cross-network path only carries LL payloads, not real-time LL handshakes. Empty PDUs locally maintain connInterval/T_IFS/supervisionTimeout, so TCP/IP RTT need not fit the peer’s LL window. Cross-network latency only shifts which connection event the payload lands in; it doesn’t trigger LL timeouts.
  • For most payloads, SMP encryption doesn’t block “ciphertext passthrough”: encrypted data stays encrypted in LL payload; the relay just forwards without decryption or app-layer understanding.
llrelay

Compared to GATT-layer relays, LL relay’s advantage is decoupling cross-network latency from LL timing: two local links with Empty PDUs keep the beat, so simple latency checks won’t break it. And because we relay LL PDUs, SMP-encrypted ciphertext passes through without needing to decrypt/interpret app semantics.

llenc

Once the model was clear, the hard part became engineering details. “Use Empty PDU to keepalive” is one-liner theory; in practice it’s pitfalls: how to send empties without errors; which packets must relay, which must drop; how to detect/recover if dropped wrongly; why links randomly wobble. I first tested with a band and a phone, running back and forth, staring at whether adverts were missed or connections dropped—inefficient and draining. Later I realized many validations don’t need devices far apart: keep them nearby, watch logs and timing, and you can tell if the model works. Test cycles shrank into control.

Engineering is still hard. That’s why I admire NCC’s persistence: you’re not solving one problem, you’re facing an unseen finish line where every idea spawns new issues.

Good News Before National Day

“2022 pre-National Day”

The final push came when my boss visited Beijing. We knocked down remaining engineering issues: Empty PDUs kept links stable; we filtered non-relay packets; the link could now sustain encrypted relay for “long enough.” It would never be as solid as direct links—occasional flakiness and drops—but BLE auth to unlock and start a car is only a few minutes.

After multiple rejections, a colleague finally lent me a Tesla for an afternoon. The first attempt failed. We traced the link end-to-end: the garage was too dark and I mistyped the MAC. Fixed it; colleague stayed outside Xiaomi campus, I inside reran the flow—this time the door unlocked and the car started. I didn’t cheer; I first checked logs and link state to ensure it was due to the relay, not chance. Once sure, I accepted: the attack worked.

We wrapped it before 2022 National Day. I took a train home; body exhausted, mind electric—“maybe this is the best day of my life.” Back then I’d have talked your ear off: leaving a mark on hacker history, impacting future products or real-world safety. Today, looking back, the answer is simpler: the fun of the challenge and the satisfaction of making it work.

The Crushing External Event

Not long after success, we saw a hardwear.io talk: NCC Group publicly presented BLE link-layer relay.

It hit hard. Before we could publish, NCC had shared the key points and some details. To me it felt like my months of groundwork were laid bare: hard-earned conclusions appeared in a more authoritative, complete form. Shock gave way to a hollow feeling: did my effort just get prewritten elsewhere?

“2026 hindsight”

In 2026 a similar emotion repeats in another form. AI base models are stronger; skills that once needed long training can now be done “decently” by a novice with an agent + MCP + a few prompts. Does that devalue our past research, even make it meaningless? It echoes that time: you solved it, but someone else published first. Was it wasted?

No single answer.

I won’t prescribe “the path.” My view now: we’re too used to treating ourselves as output machines; but people aren’t tools, and value is hard to define by “results” alone—results get superseded and time erases them. What’s truly yours are the understanding, experience, and judgment grown in exploration.

AI may quickly learn what took you years, but it can’t replace the moments only your body and presence can bear: the slight tremor unlocking a car, the panic of a drowning phone in Phuket, sprinting back from Burj Khalifa in a 4‑hour Dubai layover, or reflexively shooting a rainbow after rain. Those feelings are yours alone.

Security research is similar. For me, the most valuable part is often the process: simplifying problems, correcting mistakes, the joy of solving. The “candy” — unlocking, driving away — matters but isn’t the whole meaning.

Practically: NCC shared ideas and partial implementation, but no drop-in exploit. For those unfamiliar with BLE, even with reduced difficulty, you still need to understand protocol, timing, and engineering to run it. Many peers later asked me LL questions; some came to KCon for my talk; some reproduced success with my hints. That joy is concrete: not “first publish” thrill, but that what you know tangibly helps others—more lasting fulfillment.

Talks and Journeys

“KCon 2023” I still submitted the talk. Without public scripts and with growing inquiries, better to explain end-to-end once to clear misconceptions. After KCon, I went to HITBSecConf in Phuket. What stuck wasn’t the island but a small mishap: my phone fell into seawater. No backup, facing days offline panic. Just before teardown, it revived—probably from long blow-drying in the hotel. Like research: you think you’re “researching,” but what keeps you going are the mundane, on-the-spot fixes that set things back on track.

“OffensiveX Athens 2025” Three years later, OffensiveX in Athens. Though the talk was on another car topic, the organizers wanted a live hack on a European Tesla—a formal closure for the BLE relay I’d never demoed live.

But accidents happen at the worst time: the dev board’s micro USB snapped during the long flight. My fault—left the cable plugged; 20+ hours of pressure broke the solder. Worse, we were jetlagged, fixing slides for the demo. After rehearsal it was evening; we had to reach the Lake Vouliagmeni dinner for speakers/sponsors and also fix the board. We tried everything, scooting around Athens on e-scooters, finally finding a phone-repair shop. An Indian owner re-soldered it after some bargaining. We barely made the dinner, only to learn it was delayed—“almost missed it” tension returned.

offensivex1

Demo day: laptop in hand, Tesla curbside, camera crew ready, passersby stopping to watch. The actual hacking minutes were quiet: check device state, read logs, run flow—mind calm. When the door unlocked again, applause came from inside and outside; déjà vu. Not pure “result” excitement, but a confirmation: I’d kept pushing farther and almost forgot why I loved this; that moment pulled me back—I was still on the same track, just farther along.

Afterward I got feedback from many fields: peers, educators, students, non-security folks—they liked the show, wanted photos. Those looks and handshakes reminded me this wasn’t just for a niche—it could be heard and understood.

That’s why a small thing stuck: a DM from poc_crew. They’d seen the Tesla demo and asked if I’d research Korean cars and speak. I didn’t have a new story ready; I thanked them but said a new talk needs time. That message wasn’t an answer, but an echo—years-old work hadn’t vanished; it might return unexpectedly and nudge you toward the next unknown.

poc1
poc2

Later I cut the trip into a short Europe video. Color and story need work, but I liked the ending: I shot the cameraman, he shot me. The recorder being recorded felt like the cleanest footnote.

photographer
hackingtesla

Afterword: Where To Next?

“End of 2025”

By end of 2025, NCC finally open-sourced their relay scripts. Seeing the repo, I felt calm: from “rumor” to “paper/talk” to “reproducible code,” the lifecycle was complete. For me it was a period. Beyond that, a louder backdrop emerged: times changed.

Even the best research faces reality: AI is industrializing known paradigms, compressing skills into a few prompts. Anxiety follows: when “finding bugs” isn’t scarce, are our honed skills/methods still worth it?

I’m more convinced the answer is yes. The meaning shifted: tools will run much of the repetitive path, but won’t decide where to blaze new trails.

Continuing research in the AI era reminds me of Odysseus sailing past the Sirens. The sirens lure sailors with song; hear them and you steer onto rocks. Odysseus had sailors plug their ears with wax and tied himself to the mast, ordering them not to untie him no matter what. “Hear yet not veer” costs extra.

Research value often hides in that cost—especially in real, complex systems: identity and trust chains, supply/update chains, protocols and device ecosystems. AI’s misjudgments and blind spots remain; humans must set boundaries, validate models, and own conclusions.

That night in Athens, the Acropolis lights stayed on. The Parthenon, under repair, its outline cut by scaffolding, still stood firm—a 21st-century machine working atop it.

(to be continued)