## File: README.md

[汉字](README-zh_Hans.md) | English 

[](https://github.com/gojue/ecapture)
[](https://github.com/gojue/ecapture)
[](https://github.com/gojue/ecapture/actions/workflows/code-analysis.yml)
[](https://github.com/gojue/ecapture/releases)

### 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](docs/minimum-privileges.md).
> Does not support Windows and macOS system.

----


- [Introduction](#introduction)
- [Getting started](#getting-started)
  - [Download](#download)
    - [ELF binary file](#elf-binary-file)
    - [Docker image](#docker-image)
  - [Capture openssl text content.](#capture-openssl-text-content)
  - [Modules](#modules)
    - [OpenSSL Module](#openssl-module)
    - [GoTLS Module](#gotls-module)
    - [Other Modules](#bash-module)
  - [Videos](#videos)
- [Security & Operations](#security--operations)
- [Contributing](#contributing)
- [Compilation](#compilation)


# 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](https://github.com/gojue/ecapture/releases) , 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](docs/minimum-privileges.md#method-3-docker-with-specific-capabilities).

see [Docker Hub](https://hub.docker.com/r/gojue/ecapture) 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:

```
...
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](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](docs/example-outputs.md#tls-module--pcapng-mode).

#### 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

* Youtube video: [How to use eCapture v0.1.0](https://www.youtube.com/watch?v=CoDIjEQCvvA "eCapture User Manual")
* [eCapture:supports capturing plaintext of Golang TLS/HTTPS traffic](https://medium.com/@cfc4ncs/ecapture-supports-capturing-plaintext-of-golang-tls-https-traffic-f16874048269)


## eCaptureQ GUI Application

[eCaptureQ](https://github.com/gojue/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](./EVENT_FORWARD.md)

### Video Demonstration

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

🔗 [GitHub Repository](https://github.com/gojue/ecaptureq)

### Protobuf Protocols

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

- [protobuf/PROTOCOLS.md](./protobuf/PROTOCOLS.md)

## Stargazers over time
[](https://starchart.cc/gojue/ecapture)

# Security & Operations

- [**Security Policy**](SECURITY.md) — Vulnerability reporting and supported versions
- [**Minimum Privileges**](docs/minimum-privileges.md) — Required Linux capabilities and least-privilege configuration
- [**Defense & Detection**](docs/defense-detection.md) — How to detect and defend against unauthorized usage
- [**Performance Benchmarks**](docs/performance-benchmarks.md) — Overhead measurement methodology and expected characteristics
- [**Release Verification**](docs/release-verification.md) — How to verify the integrity of release artifacts

# Contributing
See [CONTRIBUTING](./CONTRIBUTING.md) 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](./docs/compilation.md) 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](./docs/remote-config-update-api.md).

## 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](./docs/event-forward-api.md).

---

## 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
- [**compilation.md**](compilation.md) - Build and compilation guide (English)
- [**compilation-zh_Hans.md**](compilation-zh_Hans.md) - 编译指南 (汉字)

### Architecture & Development
- [**refactoring-guide.md**](refactoring-guide.md) - Probe refactoring patterns and best practices
- [**probe-refactoring-playbook.md**](probe-refactoring-playbook.md) - Detailed refactoring tutorial with step-by-step instructions
- [**migration-v2.md**](migration-v2.md) - Migration guide from v1 to v2 architecture
- [**gotls-refactoring-summary.md**](gotls-refactoring-summary.md) - GoTLS probe refactoring case study

### Testing
- [**e2e-tests.md**](e2e-tests.md) - End-to-end testing guide

### Security & Operations
- [**defense-detection.md**](defense-detection.md) - Detection and defense against unauthorized eBPF tool usage
- [**minimum-privileges.md**](minimum-privileges.md) - Required Linux capabilities and least-privilege configuration
- [**performance-benchmarks.md**](performance-benchmarks.md) - Performance overhead measurement methodology
- [**release-verification.md**](release-verification.md) - How to verify release artifact integrity

### API Documentation
- [**event-forward-api.md**](event-forward-api.md) - Event forwarding API documentation (English)
- [**event-forward-api-zh_Hans.md**](event-forward-api-zh_Hans.md) - 事件转发API文档 (汉字)
- [**remote-config-update-api.md**](remote-config-update-api.md) - Remote configuration update API (English)
- [**remote-config-update-api-zh_Hans.md**](remote-config-update-api-zh_Hans.md) - 远程配置更新API (汉字)

### Integration
- [**event-forward.md**](event-forward.md) - Event forwarding applications and GUI clients

### Examples
- [**example-outputs.md**](example-outputs.md) - Detailed output examples for all eCapture modes and modules

## 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` (汉字)