<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg" -->

---
title: Reverse Engineering Claude Code's SSL Traffic with eBPF
description: A deep technical investigation into intercepting Claude Code's encrypted API traffic using eBPF. Claude Code runs as a 213 MB stripped Bun v1.3.9-canary binary...
canonical: https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Reverse Engineering Claude Code's SSL Traffic with eBPF | daily.dev
og:description: A deep technical investigation into intercepting Claude Code's encrypted API traffic using eBPF. Claude Code runs as a 213 MB stripped Bun v1.3.9-canary binary...
og:url: https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg
og:image: https://api.daily.dev/og/posts/uVhXXDumG.png
og:image:alt: Reverse Engineering Claude Code's SSL Traffic with eBPF
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Reverse Engineering Claude Code's SSL Traffic with eBPF

**[eunomia eBPF Blog](https://daily.dev/sources/eunomia)** · 18 min read · 0 upvotes · 0 comments

## Summary

A deep technical investigation into intercepting Claude Code's encrypted API traffic using eBPF. Claude Code runs as a 213 MB stripped Bun v1.3.9-canary binary with BoringSSL statically linked and all symbols removed, making standard SSL hooking tools like sslsniff completely blind. The team solved this by cross-referencing Bun's open-source profile build (which retains debug symbols) to extract byte prologues for SSL_write, SSL_read, and SSL_do_handshake, then pattern-matching those bytes into the stripped Claude binary. Relative distances between functions (0x6F0 and 0xCA0 bytes) were used to validate matches. The modified sslsniff was then able to attach uprobes at raw file offsets instead of symbol names. A red herring about Bun having two separate TLS paths (one for axios, one for native fetch) was ultimately disproved — both paths converge on the same BoringSSL functions through the HTTP Client thread. The real issue was timing: captures had to be running when a new /v1/messages POST was submitted. Once that was achieved, full conversation API traffic including SSE streaming responses, system prompts, and telemetry was captured.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://eunomia.dev/blog/2026/02/13/reverse-engineering-claude-codes-ssl-traffic-with-ebpf>

## Questions this post answers

### How do I hook SSL functions in a stripped binary with statically linked BoringSSL using eBPF?

When symbols are stripped, attach uprobes using raw file offsets instead of symbol names. Extract byte prologues from a debug/profile build of the same binary (e.g., Bun's open-source profile variant), search for those patterns in the stripped binary, then validate matches using known relative distances between functions. For BoringSSL in Bun v1.3.9-canary, SSL_do_handshake, SSL_read, and SSL_write are separated by exactly 0x6F0 and 0xCA0 bytes respectively. Pass the offset directly via bpf_program__attach_uprobe_opts with func_name set to NULL.

_Engineers intercepting traffic from stripped binaries track techniques like this on daily.dev._

### Does Bun's native fetch() use a different TLS path than Node.js http/axios?

No — both axios (via the Node.js compatibility path) and Bun's native fetch() ultimately call the same BoringSSL SSL_write and SSL_read functions through the uSockets library, and both run on the same HTTP Client thread. The uSockets ssl_on_data and us_socket_write functions are intermediate layers that converge at the same BoringSSL entry points. There is only one copy of SSL_read in the Bun binary.

_Developers building observability tools for Bun applications find architecture details like this on daily.dev._

### What network endpoints and HTTP clients does Claude Code use internally?

Claude Code makes four types of outbound requests: GET /api/hello (heartbeat via axios/1.8.4), POST /api/event_logging/batch (telemetry via axios), POST /api/v2/logs to Datadog (via axios), and POST /v1/messages?beta=true (conversation API via Bun native fetch). All traffic flows through a single HTTP Client thread. Telemetry payloads include session_id, device_id, model name, and Growthbook experiment events.

_Developers curious about what AI coding agents send over the wire follow findings like these on daily.dev._

## Similar posts on daily.dev

- [Intercepting and Decoding Claude Code API Calls Using MITM Proxy](https://daily.dev/posts/intercepting-and-decoding-claude-code-api-calls-using-mitm-proxy-mhcghpfxk) · C\# Corner · 0 upvotes · 0 comments
- [From bytecode to bytes: automated magic packet generation](https://daily.dev/posts/from-bytecode-to-bytes-automated-magic-packet-generation-ts88izwlt) · Cloudflare · 5 upvotes · 0 comments
- [The Claude Code Source Leak: fake tools, frustration regexes, undercover mode, and more](https://daily.dev/posts/the-claude-code-source-leak-fake-tools-frustration-regexes-undercover-mode-and-more-gmkbbnzuj) · Hacker News · 8 upvotes · 0 comments
- [Coding agent security: Claude Code, tunnels and LaunchAgents — Elastic Security Labs](https://daily.dev/posts/coding-agent-security-claude-code-tunnels-and-launchagents-elastic-security-labs-x1zklhxxc) · Elastic Security Labs · 0 upvotes · 0 comments

---

Tags: [#linux](https://daily.dev/tags/linux), [#claude-code](https://daily.dev/tags/claude-code), [#reverse-engineering](https://daily.dev/tags/reverse-engineering)

[View this post on daily.dev](https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Reverse Engineering Claude Code's SSL Traffic with eBPF","url":"https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg"},"datePublished":"2026-08-11T08:52:16.065Z","dateModified":"2026-08-11T08:58:50.157Z","description":"A deep technical investigation into intercepting Claude Code's encrypted API traffic using eBPF. Claude Code runs as a 213 MB stripped Bun v1.3.9-canary binary...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b59e04eefe0ea85df0b7e50151b0b12e?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b59e04eefe0ea85df0b7e50151b0b12e?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"eunomia eBPF Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"eunomia eBPF Blog","logo":"https://media.daily.dev/image/upload/s--z-nTl7TK--/f_auto,q_auto/v1786438304/logos/eunomia?_a=BAMAMicg0","url":"https://daily.dev/sources/eunomia"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"linux,claude-code,reverse-engineering","timeRequired":"PT18M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"eunomia eBPF Blog","item":"https://daily.dev/sources/eunomia"},{"@type":"ListItem","position":3,"name":"Reverse Engineering Claude Code's SSL Traffic with eBPF"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/reverse-engineering-claude-code-s-ssl-traffic-with-ebpf-uvhxxdumg#faq","mainEntity":[{"@type":"Question","name":"How do I hook SSL functions in a stripped binary with statically linked BoringSSL using eBPF?","acceptedAnswer":{"@type":"Answer","text":"When symbols are stripped, attach uprobes using raw file offsets instead of symbol names. Extract byte prologues from a debug/profile build of the same binary (e.g., Bun's open-source profile variant), search for those patterns in the stripped binary, then validate matches using known relative distances between functions. For BoringSSL in Bun v1.3.9-canary, SSL_do_handshake, SSL_read, and SSL_write are separated by exactly 0x6F0 and 0xCA0 bytes respectively. Pass the offset directly via bpf_program__attach_uprobe_opts with func_name set to NULL. Engineers intercepting traffic from stripped binaries track techniques like this on daily.dev."}},{"@type":"Question","name":"Does Bun's native fetch() use a different TLS path than Node.js http/axios?","acceptedAnswer":{"@type":"Answer","text":"No — both axios (via the Node.js compatibility path) and Bun's native fetch() ultimately call the same BoringSSL SSL_write and SSL_read functions through the uSockets library, and both run on the same HTTP Client thread. The uSockets ssl_on_data and us_socket_write functions are intermediate layers that converge at the same BoringSSL entry points. There is only one copy of SSL_read in the Bun binary. Developers building observability tools for Bun applications find architecture details like this on daily.dev."}},{"@type":"Question","name":"What network endpoints and HTTP clients does Claude Code use internally?","acceptedAnswer":{"@type":"Answer","text":"Claude Code makes four types of outbound requests: GET /api/hello (heartbeat via axios/1.8.4), POST /api/event_logging/batch (telemetry via axios), POST /api/v2/logs to Datadog (via axios), and POST /v1/messages?beta=true (conversation API via Bun native fetch). All traffic flows through a single HTTP Client thread. Telemetry payloads include session_id, device_id, model name, and Growthbook experiment events. Developers curious about what AI coding agents send over the wire follow findings like these on daily.dev."}}]}
```

