Claude Code Meetup · April 16, 2026 · Nuremberg

KI Navigator November 18, 2026 · Nuremberg

How I Accidentally Became #2 VDP* Researcher for Germany on HackerOne

HackerOne Germany VDP leaderboard showing fbettag

A candid story about building iteratively with Claude Code and ending up on the HackerOne VDP leaderboard for Germany.

* VDP = Vulnerability Disclosure Program

V2.0
Outline

Here’s where this goes in the next 45 minutes

~1 min Who am I
~8 min · Deep tech What I built and how it evolved
~8 min · Practical The build method & universal loop pattern
~5 min · Blueprint How to adapt this for your own projects
~18 min · V2.0 And then… what happened since.
Q&A
The first part is technical on purpose: vulnerabilities, architecture and implementation details up front to get you started. The second part focuses on reusable patterns you can take home. The final third covers the new additions: how I reused what I learned and what I built with it.
Who I am

Franz Bettag Polyglot engineer since 2001

25 years of consulting for enterprise to Fortune 500. On-prem, cloud, AI, security, and development — paid projects in 30+ languages before AI came around.

Bettag Systems logo
On-Prem & Cloud, AI & Security Engineering for Enterprise to Fortune 500
Most notable for the German market kleinanzeigen.de

Sole IT Engineer next to the CEO. Re-developed the platform from 2014–2019 serving 30M+ monthly users, then exited to eBay.

Wall Street HFT block-trade optimization

Tasked to fix a critical performance bottleneck. Found a $2M+ accounting error while rewriting the system. Cut monthly job runtime from 2+ hours to 5 minutes.

Fashion @ Scale Nordstrom / HauteLook

Rebuilt flash-sale push notification infra for the largest fashion retailer in the US. 10M+ concurrent pushes, delivery cut from 2 days to under 10 minutes.

Franz Bettag profile photo
Family lore

If you recognize my last name, it's probably because my grandfather invented the BobbyCar and was the founder of BIG Spielwaren.

BIG Bobby Car — where it all started
The prompt that never works
Build me a billion dollar business.
Make no mistakes!
Find me a $100k bug bounty!
No false positives!
Validated outcomes

The ranking followed real shipped findings

CVE Keycloak CVE-2026-1190
Critical fix 2x ClickHouse RBAC bypass
Subdomain takeover 3x Amazon VDP
Subdomain takeover OANDA VDP
Subdomain takeover → SIP / VoIP infrastructure takeover Opera
Valid finding Ruby on Rails
HackerOne profile stats: 7.00 Signal, 99th Percentile
Architecture

One canonical backend. Distributed execution.

Control plane

Central server

State, orchestration, findings, submissions, operator UI.

Session layer · 56 agents

Agents = identity + method

Full session prompts: exploit-web-attacking, recon-subdomain-discovery, audit-finding-verification, …

Tool layer · 200+ skills

Skills = composable building blocks

Reusable techniques: subdomain-takeover-detection, nuclei-scanning, playwright, sqlmap, …

Execution

4 pwn hosts + shared CLI

A shared bounty-cli standardizes every host run.

Infra

NixOS + flakes

Deterministic infra, reproducible deploys, auditable config.

Design rule

Validation-first state machine

Every risky phase emits an artifact that must pass a gate.

Active on all major platforms
HackerOne Bugcrowd YesWeHack Intigriti Hackenproof Immunefi Apple Security Google VRP
Built with Claude Code
Evolution

Every change was a scar, not a plan

01

Start with the smallest useful slice

Central server first. One source of truth.

02

MCP was useful, then expensive

Good for early iteration. Bad for token and context efficiency. Replaced with a shared Go CLI.

03

Push execution to workers

Parallel campaigns across architectures: Linux for web & Android, macOS for BinDiff fuzzing, iOS firmware diffing & Simulator app testing.

04

Separate agents from skills

Agents own the session identity. Skills are composable tools agents invoke. Clear contract between the two.

Every step was driven by a real constraint, not a design preference.
Do NOT try to one-shot complex systems. Go feature by feature.
Why not MCP?

MCP burns tokens. A CLI + skills doesn't.

MCP sends full tool schemas on every request — context cost scales with tool count.
Every tool invocation round-trips through the model. Five tools = five inference calls.
A CLI runs locally with zero token overhead. Skills are injected only when needed.
Result: same coverage, 10–20x fewer tokens per campaign run.
MCP approach

Model → tool schema → inference → tool call → result → inference → …

High token cost per step
CLI + skills approach

Prompt → agent runs locally → skills execute in-process → results to server

Tokens only for reasoning
Case study

Opera SIP takeover: why recon automation matters

_sip._tcp.opera.com.   86400 IN SRV 0 0 5060 e1.viju.vc.
_sips._tcp.opera.com.  86400 IN SRV 0 0 5061 e1.viju.vc.
The rig flagged dangling SRV records pointing at e1.viju.vc — a domain that no longer existed.
RFC 3263 compliant SIP clients would resolve Opera's SRV records into whoever controls viju.vc.
I registered viju.vc manually, pointed e1.viju.vc at my infrastructure, and confirmed the takeover.
Responsible disclosure to Opera via Bugcrowd. Domain held as proof, not weaponized.
Legacy DNS edge case
High signal, low noise
Best found by broad automation
Context priming

Every session is a new hire

An A-grade engineer who knows every tool — but nothing about your project, your architecture, or your constraints.
Without priming, it will produce generic code that technically works but doesn't fit your system.
The question for every session: “How do I explain what I need in the fewest words while still conveying the architecture and the problem?”
CLAUDE.md

Project rules, coding conventions, architecture overview. Loaded automatically every session.

Memory

Learnings from past sessions. Mistakes, patterns, decisions the agent shouldn't repeat or forget.

Your prompt

The specific task. Short, precise, assumes the agent already knows the context from the layers above.

Reusable loop

The whole trick: separate, gate, compose

01

Discovery

Map the surface and emit concrete candidate artifacts.

02

Execution

Probe inside a bounded role with explicit success criteria.

03

Validation

Reject weak artifacts before they contaminate later phases.

04

Composition

Chain only validated pieces into a higher-value outcome.

05

Feedback

Update prompts, routing rules, and profiles from misses.

The point is not "more agents". It is fewer ambiguous handoffs.
Same loop, shipping infra

Ship a CI/CD pipeline from zero to deployed

01

Discovery

“Investigate this repo. How is it built? What framework, what output? Create an initial git commit if there isn't one.”

02

Execution GitLab

“Build a GitLab CI/CD pipeline with Auto DevOps for Kubernetes deployment. Look at similar projects for reference.”

02

Execution GitHub

“Set up GitHub Actions to build a Docker image and deploy to Kubernetes. Look at similar projects for reference.”

03

Validation

“Commit, push, and check the pipeline status. If it fails, read the logs and fix it. Repeat until the pipeline is green.”

04

Composition

Build passes → image pushed → deploy triggered → pods running. Each stage gates the next.

05

Feedback

curl https://your-domain.com returns 200. If not, iterate. You are done when the site is live.

Blueprint

How to copy this tomorrow

01
Discovery Pick one problem. Map the surface. Define the success artifact.
02
Execution Probe inside a bounded role with explicit success criteria.
03
Validation Reject weak artifacts before they contaminate later phases.
04
Composition Chain only validated outputs into a higher-value outcome.
05
Feedback Feed misses back into prompts, profiles, and routing.
Start here. Repeat until stable. Then scale.
Same loop, shipping code

Ship a feature with /code 9 agents. One command.

01

Discovery

/code <feature> — the Architect agent asks up to 5 clarifying questions, then designs schemas, contexts, LiveViews, and routes.

02

Execution

Feature Developer implements the following 2,280 lines of project patterns — domain-driven design, typed schemas, LiveView sessions, Petal UI components.

03

Validation

Feature Tester runs mix quality. Feature Translator wraps all user-facing strings in gettext and translates to every supported locale.

04

Composition

Feature Committer analyzes the diff, determines conventional commit type and scope. No commit without green tests. Each agent gates the next.

05

Feedback

Higher-order commands (/gdpr-audit, /audit-legal, /public-launch) re-run audits after /code. Findings become new /code runs.

One more example

GitLab v15 → v18 on Kubernetes. Overnight. Unattended.

01

Discovery

“Explore our current setup in read-only mode on this Kubernetes cluster, then do a full backup.”

02

Execution

“Research the best upgrade path. Do not skip intermediary steps. Verify dependencies and requirements for the new versions.”

03

Validation

“Start the upgrade procedure. You are done when all services that are currently running and up are successfully upgraded and responding.”

04

Composition

Each intermediary version (v15 → v16 → v17 → v18) is a validated artifact. PostgreSQL migrated in lockstep. Only proceed when the previous hop is healthy.

05

Feedback

Failures at any hop feed back into the next attempt. The agent retries with context, not from scratch.

Takeaway

Don’t start with one giant prompt. Start with a loop.

Security is the example. The architecture is the reusable asset.

Normally, this talk would end here.

Boris Cherny, creator of Claude Code at Anthropic

But 47 days after my talk on April 16, 2026,
this Boris Cherny interview came out.

“My job is to write loops.”

Boris Cherny · Anthropic
Acquired Unplugged · published June 2, 2026 · 11:50

So I kept writing loops. They went somewhere I didn’t expect.

01

The surfacea web hunter is supposed to find.

Start where you’d expect me to: the browser engines that render the whole internet.

Browsers → Software I trusted → The kernel

Apple: one WebKit finding.
Across the platform family.

CVE-2026-112680. Apple publicly credits this research.

  • The input was web content.

    Crafted content could trigger an out-of-bounds read in WebKit.

  • The impact was memory disclosure.

    Processing that content could expose data from process memory.

  • The fix reached multiple products.

    Apple added bounds checks and shipped the repair across its platform family.

Safari · macOS
iOS · iPadOS
visionOS

One CVE, listed in five Apple security advisories.

Fixed in 27.2 releases and iOS / iPadOS 26.7.2. Apple advisory · el8.nl

Chrome: a background response.
Another site’s storage.

Google VRP report 554026885: Background Fetch and site-data clearing.

  • A storage key went missing.

    Background Fetch omitted the service worker’s StorageKey when handling the response.

  • The deletion reached another site.

    A Clear-Site-Data response cleared the target’s first-party storage, without CORS opt-in.

  • The control made the difference clear.

    The same response through ordinary Fetch left the target’s stored value intact.

Background Fetch:
value deleted.
Ordinary Fetch:
value preserved.

Reproduced on Chrome Canary 154 / macOS arm64. Google raised severity to S2.

Requires a target endpoint returning Clear-Site-Data. A patch was proposed; a shipped fix remains unconfirmed.

02

Software I trustedfor fifteen years.

The same loop, pointed at the banking tool on my own machine. This is where it stopped being abstract.

Browsers → Software I trusted → The kernel

Hibiscus: the software
I already trusted.

Jameica and Hibiscus had been part of my banking workflow for over 15 years.

  • Restore a backup.

    Archive paths could escape the intended restore directory.

  • Import an invoice.

    External XML entities enabled local file access and server-side requests.

  • Import application data.

    XMLDecoder could turn a data import into code execution.

A familiar file
crosses a trust boundary.

Backups, invoices and saved settings are inputs, too.

Locally reproduced findings, reported 25 August 2026.

Hibiscus: finding the bug
was only the beginning.

The fix had to protect users without destroying their existing data.

  • Remove executable deserialization.

    Read legacy wallet data without XMLDecoder; write a typed JAXB format.

  • Keep old wallets usable.

    Preserve supported plugin data and migrate it on the next save.

  • Prove both sides.

    Old wallet still loads. Malicious wallet is rejected without executing code.

Report.
Repair.
Retest.

The same loop, now working with the maintainer.

27 October: maintainer confirmed the final PR merged; releases were still planned.

03

The kernel.Where I had no business being.

Three BSD operating systems. Memory corruption in code that runs as root. The loop did not stop at the application layer.

Browsers → Software I trusted → The kernel
Three kernels, one method

The loop walked into threeoperating system kernels.

FreeBSD

A directory listing reached the kernel stack.

An overlong archive name overran a tarfs_readdir() buffer on 15.1-RELEASE / amd64.

NetBSD

A root network daemon fell to two chained bugs.

An address leak plus a label-release flaw in ldpd produced a root-owned result on MPLS / arm64.

OpenBSD

Privilege separation leaked across the boundary.

Heap and stack corruption in isakmpd and npppd crossed worker-to-monitor trust lines.

All in controlled lab setups. Several require non-default daemons, MPLS, or privileged preparation. No remote-to-root chain was demonstrated end to end.

The deepest point

And once, the loop openedan interactive root shell.

NetBSD 11 / arm64. SCTP state-cookie handling carried attacker-controlled input into an unchecked copy inside the kernel.

  • Follow the input through the protocol.

    A signed state cookie still carried the peer’s original, unchecked bytes.

  • Reach the full consequence.

    The isolated test escalated a uid 1000 process to an interactive root shell.

  • Then run it against the fix.

    The patched kernel stayed healthy and the process stayed uid 1000.

uid 1000↓uid 0

Original kernel: root shell.
Patched kernel: still uid 1000.

SCTP-enabled audit kernel, listening endpoint, QEMU guest-loopback test. A conditioned lab proof, not an independent remote exploit on a default install.

Since April · one person · one loop

From a web formto ring 0.

1Apple CVE, credited across five advisories
S2Chrome VRP report, severity raised by Google
3Hibiscus fixes merged upstream
3BSD kernels reached in the lab
1interactive root shell, proven before and after a patch
Same loop from the first half of this talk. Nothing about it was security-specific.

The research became a company.

wnry.io

The workflow from this talk,
now a security SaaS.

AI inference exclusively in Nuremberg.

  • Find your exposure.Discover public systems and define what to test.
  • Test. Verify. Retest.Recurring external pentests with expert-assessed findings.
  • Know what your skills run.Submit an agent skill. We audit it and automatically reverse engineer bundled binaries.

Four offers on the next slide. Pick yours first.

clawdhost.de 25 seats 1 month Starter · €10 AI budget

agent-host.net 25 seats 1 month Developer plan

2342.ai 25 vouchers €20 credit · 90 days

pwnry.io 100 audits Skills incl. bundled binaries

Your next experiment starts here.

Thank you! Questions?

A few gifts for the KI Navigator crowd.

1 month free Starter plan

25 places · €10 AI budget.
3 quiz questions.

1 month free Developer plan

25 places · no subscription.
3 quiz questions.

€20 in AI credit

25 vouchers · 90 days.
3 quiz questions.

100 free skill audits

100 places · 90 days.
3 quiz questions.

Clawdhost, agent-host.net & 2342.ai: 25 places each · pwnry.io: 100 places · Redeem on site during KI Navigator · 3-question quiz.

QR code: no2vdp.bett.ag Slides: no2vdp.bett.ag