ecapture Documentation

Capturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy ecapture on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name ecapture --restart always gojue/ecapture:latest

File: README.md

ๆฑ‰ๅญ— | English




eCapture(ๆ—่ง‚่€…): capture SSL/TLS text content without a CA certificate using eBPF.

[!IMPORTANT]
Supports Linux/Android on x86_64 (kernel 4.18+) and aarch64 (kernel 5.5+). Kernel version requirements apply per CPU architecture for both Linux and Android.
Need ROOT permission or specific Linux capabilities.
Does not support Windows and macOS system.


Introduction

  • SSL/TLS plaintext capture, support openssl\libressl\boringssl\gnutls\nspr(nss) libraries.
  • GoTLS plaintext support go tls library, which refers to encrypted communication in https/tls programs written in the golang language.
  • Bash audit, capture bash command for Host Security Audit.
  • Zsh audit, capture zsh command for Host Security Audit.
  • MySQL query SQL audit, support mysqld 5.6\5.7\8.0, and MariaDB.

Getting started

Download

ELF binary file

[!TIP]
support Linux/Android x86_64/aarch64.

Download ELF zip file release , unzip and use by
command sudo ecapture --help.

Docker image

[!TIP]
Linux only.

shell
# pull docker image
docker pull gojue/ecapture:latest
# run
docker run --rm --privileged=true --net=host -v ${HOST_PATH}:${CONTAINER_PATH} gojue/ecapture ARGS

โš ๏ธ Security Note: --privileged=true grants full host access. For production use, consider specific capabilities instead. See Minimum Privileges Guide.

see Docker Hub for more information.

Capture openssl text content.

shell
sudo ecapture tls

eCapture will automatically detect the system's OpenSSL library and start capturing plaintext. When you make an HTTPS request (e.g., curl https://google.com), the captured request and response will be displayed:

text
...
INF module started successfully. moduleName=EBPFProbeOPENSSL
??? UUID:233851_233851_curl_5_1_172.16.71.1:51837, Name:HTTP2Request, Type:2, Length:304
header field ":method" = "GET"
header field ":path" = "/"
header field ":authority" = "google.com"
...

๐Ÿ“„ For complete output examples, see docs/example-outputs.md.

Modules

The eCapture tool comprises 8 modules that respectively support plaintext capture for TLS/SSL encryption libraries like OpenSSL, GnuTLS, NSPR, BoringSSL, and GoTLS. Additionally, it facilitates software audits for Bash, MySQL, and PostgreSQL applications.

  • bash capture bash command
  • zsh capture zsh command
  • gnutls capture gnutls text content without CA cert for gnutls libraries.
  • gotls Capturing plaintext communication from Golang programs encrypted with TLS/HTTPS.
  • mysqld capture sql queries from mysqld 5.6/5.7/8.0 .
  • nss capture nss/nspr encrypted text content without CA cert for nss/nspr libraries.
  • postgres capture sql queries from postgres 10+.
  • tls use to capture tls/ssl text content without CA cert. (Support openssl 1.0.x/1.1.x/3.0.x or newer).
    You can use ecapture -h to view the list of subcommands.

OpenSSL Module

eCapture search /etc/ld.so.conf file default, to search load directories of SO file, and search openssl shard
libraries location. or you can use --libssl
flag to set shard library path.

If target program is compile statically, you can set program path as --libssl flag value directlyใ€‚

The OpenSSL module supports three capture modes:

  • pcap/pcapng mode stores captured plaintext data in pcap-NG format.
  • keylog/key mode saves the TLS handshake keys to a file.
  • text mode directly captures plaintext data, either outputting to a specified file or printing to the command line.

Pcap Mode

Supported TLS encrypted http 1.0/1.1/2.0 over TCP, and http3 QUIC protocol over UDP.
You can specify -m pcap or -m pcapng and use it in conjunction with --pcapfile and -i parameters. The default value for --pcapfile is ecapture_openssl.pcapng.

shell
sudo ecapture tls -m pcap -i eth0 --pcapfile=ecapture.pcapng tcp port 443

This command saves captured plaintext data packets as a pcapng file, which can be viewed using Wireshark.

๐Ÿ“„ For complete pcapng mode output, see docs/example-outputs.md.

Keylog Mode

You can specify -m keylog or -m key and use it in conjunction with the --keylogfile parameter, which defaults to ecapture_masterkey.log.

The captured OpenSSL TLS Master Secret information is saved to --keylogfile. You can also enable tcpdump packet capture and then use Wireshark to open the file and set the Master Secret path to view plaintext data packets.

shell
sudo ecapture tls -m keylog -keylogfile=openssl_keylog.log

You can also directly use the tshark software for real-time decryption and display:

shell
tshark -o tls.keylog_file:ecapture_masterkey.log -Y http -T fields -e http.file_data -f "port 443" -i eth0

Text Mode

sudo ecapture tls -m text will output all plaintext data packets. (Starting from v0.7.0, it no longer captures
SSLKEYLOG information.)

GoTLS Module

Similar to the OpenSSL module.

gotls command

capture tls text context.

Step 1:

shell
sudo ecapture gotls --elfpath=/home/cfc4n/go_https_client --hex

Step 2:

shell
/home/cfc4n/go_https_client

more help

shell
sudo ecapture gotls -h

Other Modules

such as bash\mysqld\postgres modules, you can use ecapture -h to view the list of subcommands.

Videos

eCaptureQ GUI Application

eCaptureQ is a cross-platform graphical user interface client for eCapture,
visualizing eBPF TLS capture
capabilities. Built using the Rust + Tauri + React technology stack, it provides a real-time, responsive interface,
enabling easy analysis of encrypted traffic without the need for CA certificates. It simplifies complex eBPF capture
techniques, making them easy to use. Supports two modes:

  • Integrated Mode: Unified Linux/Android execution
  • Remote Mode: Windows/macOS/Linux client connects to a remote eCapture service

Event Forwarding

Event Forwarding Projects

Video Demonstration

https://github.com/user-attachments/assets/c8b7a84d-58eb-4fdb-9843-f775c97bdbfb

๐Ÿ”— GitHub Repository

Protobuf Protocols

For details of the Protobuf log schema used by eCapture/eCaptureQ, see:

Stargazers over time

Security & Operations

Contributing

See CONTRIBUTING for details on submitting patches and the contribution workflow.

Compilation

Custom Compilation

You can customize the features you want, such as setting the offset address for uprobe to support statically compiled OpenSSL libraries. Refer to the compilation guide for compilation instructions.

Configurations Remote Update

After eCapture is running, you can dynamically modify the configurations through HTTP interfaces. Refer to the HTTP API Documentation.

Event Forwarding

eCapture supports multiple event forwarding methods. You can forward events to packet capture software such as Burp Suite. For details, refer to the Event Forwarding API Documentation.


File: kern/README.md

application source doc.

openssl 1.1.*

version

  • define SSL3_VERSION 0x0300
  • define TLS1_VERSION 0x0301
  • define TLS1_1_VERSION 0x0302
  • define TLS1_2_VERSION 0x0303
  • define TLS1_3_VERSION 0x0304
  • define DTLS1_VERSION 0xFEFF
  • define DTLS1_2_VERSION 0xFEFD
  • define DTLS1_BAD_VER 0x0100
c
//https://github.com/openssl/openssl/blob/3e8f70c30d84861fcd257a6e280dc49e104eb145/ssl/ssl_local.h#L1068
struct ssl_st {
    /*
     * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
     * DTLS1_VERSION)
     */
    int version;
    /* SSLv3 */
    const SSL_METHOD *method;
    /*
     * There are 2 BIO's even though they are normally both the same.  This
     * is so data can be read and written to different handlers
     */
    /* used by SSL_read */
    BIO *rbio;
    /* used by SSL_write */
    BIO *wbio;
    /* used during session-id reuse to concatenate messages */
    BIO *bbio;

    // ...
}

//https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/crypto/bio/bio_local.h
struct bio_st {
    const BIO_METHOD *method;
    /* bio, mode, argp, argi, argl, ret */
    BIO_callback_fn callback;
    BIO_callback_fn_ex callback_ex;
    char *cb_arg;               /* first argument for the callback */
    int init;
    int shutdown;
    int flags;                  /* extra storage */
    int retry_reason;
    int num;
    void *ptr;
    struct bio_st *next_bio;    /* used by filter BIOs */
    struct bio_st *prev_bio;    /* used by filter BIOs */
    CRYPTO_REF_COUNT references;
    uint64_t num_read;
    uint64_t num_write;
    CRYPTO_EX_DATA ex_data;
    CRYPTO_RWLOCK *lock;
};

openssl 1.0.*

https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/ssl/ssl.h#L1093

c
struct ssl_st {
    /*
     * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
     * DTLS1_VERSION)
     */
    int version;
    /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
    int type;
    /* SSLv3 */
    const SSL_METHOD *method;
    /*
     * There are 2 BIO's even though they are normally both the same.  This
     * is so data can be read and written to different handlers
     */
# ifndef OPENSSL_NO_BIO
    /* used by SSL_read */
    BIO *rbio;
    /* used by SSL_write */
    BIO *wbio;
    /* used during session-id reuse to concatenate messages */
    BIO *bbio;
# else
    /* used by SSL_read */
    char *rbio;
    /* used by SSL_write */
    char *wbio;
    char *bbio;
# endif
    /*

https://github.com/openssl/openssl/blob/OpenSSL_1_0_0-stable/crypto/bio/bio.h

c
struct bio_st {
    BIO_METHOD *method;
    /* bio, mode, argp, argi, argl, ret */
    long (*callback) (struct bio_st *, int, const char *, int, long, long);
    char *cb_arg;               /* first argument for the callback */
    int init;
    int shutdown;
    int flags;                  /* extra storage */
    int retry_reason;
    int num;
    void *ptr;
    struct bio_st *next_bio;    /* used by filter BIOs */
    struct bio_st *prev_bio;    /* used by filter BIOs */
    int references;
    unsigned long num_read;
    unsigned long num_write;
    CRYPTO_EX_DATA ex_data;
};

master secrets

openssl label name openssl struct Label Name boringssl struct
MASTER_SECRET_LABEL s->session->master_key CLIENT_RANDOM session->secret
EXPORTER_SECRET s->exporter_master_secret EXPORTER_SECRET ssl->s3->exporter_secret
EARLY_EXPORTER_SECRET_LABEL s->early_exporter_master_secret EARLY_EXPORTER_SECRET -
SERVER_APPLICATION_LABEL s->server_app_traffic_secret SERVER_TRAFFIC_SECRET_0 hs->server_traffic_secret_0()
CLIENT_APPLICATION_LABEL s->client_app_traffic_secret CLIENT_TRAFFIC_SECRET_0 hs->client_traffic_secret_0()
SERVER_HANDSHAKE_LABEL SERVER_HANDSHAKE_TRAFFIC_SECRET hs->server_handshake_secret()
CLIENT_HANDSHAKE_LABEL CLIENT_HANDSHAKE_TRAFFIC_SECRET hs->client_handshake_secret()
CLIENT_EARLY_LABEL CLIENT_EARLY_TRAFFIC_SECRET hs->early_traffic_secret()

EARLY_EXPORTER_SECRET_LABEL EXPORTER_SECRET_LABEL

SERVER_APPLICATION_LABEL

insecret = s->master_secret;
label = server_application_traffic;
labellen = sizeof(server_application_traffic) - 1;
log_label = SERVER_APPLICATION_LABEL;

CLIENT_APPLICATION_LABEL

insecret = s->master_secret;
label = client_application_traffic;
labellen = sizeof(client_application_traffic) - 1;
log_label = CLIENT_APPLICATION_LABEL;

SERVER_HANDSHAKE_LABEL

insecret = s->handshake_secret;
finsecret = s->server_finished_secret;
finsecretlen = EVP_MD_size(ssl_handshake_md(s));
label = server_handshake_traffic;
labellen = sizeof(server_handshake_traffic) - 1;
log_label = SERVER_HANDSHAKE_LABEL;

ๅ†่ฎก็ฎ—
memcpy(s->handshake_traffic_hash, hashval, hashlen);
derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
insecret, hash, label, labellen, secret, iv,
ciph_ctx)

SERVER_HANDSHAKE_LABEL

insecret = s->handshake_secret;
finsecret = s->server_finished_secret;
finsecretlen = EVP_MD_size(ssl_handshake_md(s));
label = server_handshake_traffic;
labellen = sizeof(server_handshake_traffic) - 1;
log_label = SERVER_HANDSHAKE_LABEL;

ๅ†่ฎก็ฎ—
memcpy(s->handshake_traffic_hash, hashval, hashlen);
derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
insecret, hash, label, labellen, secret, iv,
ciph_ctx)

CLIENT_HANDSHAKE_LABEL

insecret = s->handshake_secret;
finsecret = s->client_finished_secret;
finsecretlen = EVP_MD_size(ssl_handshake_md(s));
label = client_handshake_traffic;
labellen = sizeof(client_handshake_traffic) - 1;
log_label = CLIENT_HANDSHAKE_LABEL;
hash = s->handshake_traffic_hash;

CLIENT_EARLY_LABEL

insecret = s->early_secret;
label = client_early_traffic;
labellen = sizeof(client_early_traffic) - 1;
log_label = CLIENT_EARLY_LABEL;


File: docs/README.md

eCapture Documentation

This directory contains comprehensive documentation for the eCapture project.

Documentation Index

Getting Started

Architecture & Development

Testing

Security & Operations

API Documentation

Integration

Examples

Document Organization

Root Directory (`/`)

The project root contains standard GitHub community health files:

  • README.md - Project overview and quick start
  • CONTRIBUTING.md - Contribution guidelines
  • CODE_OF_CONDUCT.md - Community code of conduct
  • SECURITY.md - Security policy
  • CHANGELOG.md - Release history

Docs Directory (`/docs`)

Technical documentation, guides, and API references are organized here.

Internal Directory (`/internal`)

Contains architecture documentation for internal packages (see internal/README.md).

Naming Convention

All documentation files in this directory follow the lowercase-with-hyphens (kebab-case) naming convention for consistency and web compatibility.

Examples:

  • โœ… refactoring-guide.md
  • โœ… e2e-tests.md
  • โœ… event-forward-api.md

Contributing to Documentation

When adding new documentation:

  1. Place it in the appropriate directory (/docs for technical docs, / for community files)
  2. Use lowercase with hyphens for file names
  3. Update this README to include your new document
  4. Ensure proper cross-references to related documents

Language Versions

Chinese versions of documents are indicated with a -zh_Hans suffix:

  • compilation.md (English) / compilation-zh_Hans.md (ๆฑ‰ๅญ—)
  • event-forward-api.md (English) / event-forward-api-zh_Hans.md (ๆฑ‰ๅญ—)