Simplifying encrypted traffic analysis for researchers by making protocol decryption effortless.
537
stars
620
commits
Python
primary language
Aug 10, 2026
updated
Real-time key extraction and traffic decryption for security researchfriTap is a powerful tool designed to assist researchers in analyzing network traffic encapsulated in SSL/TLS. With its ability to automate key extraction, friTap is especially valuable when dealing with malware analysis or investigating privacy issues in applications. By simplifying the process of decrypting and inspecting encrypted traffic, friTap empowers researchers to uncover critical insights with ease.
Key features include seamless support for automated SSL/TLS key extraction, making it an ideal choice for scenarios requiring rapid and accurate traffic analysis. Whether you’re dissecting malicious network behavior or assessing data privacy compliance, friTap streamlines your workflow.
For more details, explore the OSDFCon webinar slides or check out our blog post.
This project was inspired by SSL_Logger and currently supports all major operating systems: Linux, Windows, Android, with partial support for macOS and iOS (still under development). More platforms and libraries will be added in future releases.
The main features of friTap are:
-k key.log)-p plaintext.pcap) — coverage varies by platform/library; see the support table belowfritap)fritap -r saved_capture.tap)--library-scan)Installation is simply a matter of pip3 install fritap. This will give you the fritap command. You can update an existing fritap installation with pip3 install --upgrade fritap.
On Linux/Windows/MacOS we can easily attach to a process by entering its name or its PID:
$ sudo fritap --pcap mycapture.pcap thunderbird
For mobile applications we just have to add the -m parameter to indicate that we are now attaching (or spawning) an Android or iOS app:
$ fritap -m -k keys.log com.example.app
Further ensure that the frida-server is running on the Android/iOS device.
friTap can also be used as a Python library within your project:
from friTap import SSL_Logger
For more details on integrating friTap into your Python project, check out the INTEGRATION.md guide.
friTap allows you to enhance its functionality by providing a custom Frida script during your session. This custom script will be invoked just before friTap applies its own hooks. To do so, use the -c parameter (more).
More examples on using friTap can be found in the USAGE.md. A detailed introduction using friTap on Android is under EXAMPLE.md as well.
Running fritap without any arguments launches an interactive Terminal User Interface (TUI):
$ fritap
The TUI provides a guided setup wizard that walks you through device selection, target process, and capture mode. You can also configure everything manually using keyboard shortcuts:
| Key | Action | Key | Action |
|---|---|---|---|
d | Select device | 1 | Full capture (keys + pcap) |
a | Attach to process | 2 | Key extraction only |
s | Spawn application | 3 | Plaintext pcap |
Enter | Start/stop capture | 4 | Live Wireshark (pipe) † |
v | Toggle verbose | 5 | Live Wireshark (auto-decrypt) † |
p | Select protocol | ? | Help |
q | Quit | e | Toggle experimental |
The TUI supports device selection for local, USB (Android/iOS), and remote devices, and can automatically install and start frida-server on connected devices.
† Live Wireshark options (4 and 5) require Unix-style FIFOs and are currently Linux/macOS only — they are not supported on Windows.
In certain scenarios, the library we want to hook offers no symbols or is statically linked with other libraries, making it challenging to directly hook functions. For example Cronet (libcronet.so) and Flutter (libflutter.so) are often statically linked with BoringSSL.
Despite the absence of symbols, we can still use friTap for parsing and hooking.
To solve this, we can use friTap with byte patterns to hook the desired functions. You can provide friTap with a JSON file that contains byte patterns for hooking specific functions, based on architecture and platform using the --patterns <byte-pattern-file.json> option.
In order to apply the apprioate hooks for the various byte patterns we distinguish between different hooking categories.
These categories include:
Each category has a primary and fallback byte pattern, allowing flexibility when the primary pattern fails. For libraries like BoringSSL, where TLS functionality is often statically linked into other binaries, we developed a tool called BoringSecretHunter. This tool automatically identifies the necessary byte patterns to hook BoringSSL by byte-pattern matching. BoringSecretHunter is available as a Docker container with pre-configured Ghidra environment:
# Create directories and copy target libraries
mkdir -p binary results
cp /path/to/libflutter.so binary/
# Run BoringSecretHunter
docker run --rm -v "$(pwd)/binary":/usr/local/src/binaries -v "$(pwd)/results":/host_output boringsecrethunter
# Use generated patterns with friTap
fritap --patterns results/libflutter.so_patterns.json -k keys.log target_app
More about the different hooking categories can be found in usage of byte-patterns in friTap.
Alternatively, you can use the --offsets <offset-file.json> option to hook functions using known offsets. friTap allows you to specify user-defined offsets (relative to the base address of the targeting SSL/socket library) or absolute virtual addresses for function resolution. This is done through a JSON file, which is passed using the --offsets parameter.
If the --offsets parameter is used, friTap will only overwrite the function addresses specified in the JSON file. For functions that are not specified, friTap will attempt to detect the addresses automatically (using symbols).
The absence of traffic or incomplete traffic capture in the resulting pcap file (-p <your.pcap>) may stem from various causes. Before submitting a new issue, consider attempting the following solutions:
There might be instances where friTap fails to retrieve socket information. In such scenarios, running friTap with default socket information (--enable_default_fd) could resolve the issue. This approach utilizes default socket information (127.0.0.1:1234 to 127.0.0.1:2345) for all traffic when the file descriptor (FD) cannot be used to obtain socket details:
fritap -m --enable_default_fd -p plaintext.pcap com.example.app
Traffic originating from a subprocess could be another contributing factor. To capture this traffic, friTap can leverage Frida's spawn gating feature, which intercepts newly spawned processes using the --enable_spawn_gating parameter:
fritap -m -p log.pcap --enable_spawn_gating com.example.app
In cases where the target library solely supports key extraction (cf. the table below), you can utilize the -k <key.log> parameter alongside full packet capture:
fritap -m -p log.pcap --full_capture -k keys.log com.example.app
If these approaches do not address your issue, please create a detailed issue report to aid in troubleshooting. To facilitate a more effective diagnosis, include the following information in your report:
fritap -do -v com.example.app
| Library | Linux | Windows | MacOSX | Android | iOS |
|---------------------------|---------------|---------------|----------|----------|--------------|
| OpenSSL | Full | R/W-Hook only | TBI | Full | TBI |
| BoringSSL | Full | R/W-Hook only | Keys | Full | Keys |
| NSS | Full | R/W-Hook only | TBI | TBA | TBI |
| GnuTLS | R/W-Hook only | R/W-Hook only | TBI | Full | TBI |
| WolfSSL | R/W-Hook only | R/W-Hook only | TBI | Full | TBI |
| MbedTLS | R/W-Hook only | R/W-Hook only | TBI | Full | TBI |
| Bouncycastle/Spongycastle | TBA | TBA | TBA | Full | TBA |
| Conscrypt | TBA | TBA | TBA | Full | TBA |
| S2n-tls | Full | LibNO | TBA | Full | LibNO |
| RusTLS | Keys | TBI | TBI | Keys | TBI |
R/W-Hook only = Logging data sent and received by process
Keys = Only the keying material can be extracted
Full = Logging data send and received by process + Logging keys used for secure connection
TBA = To be answered
TBI = To be implemented
LibNO = This library is not supported for this plattform
We verified the Windows implementations only for Windows 10
friTap targets a single frida major per friTap-major release. From 2.0.0
onward, every frida major bump produces a friTap major bump in the same
commit (enforced by CI; see RELEASING.md).
| friTap range | frida required | frida-tools required | Constraints file |
|---|---|---|---|
| 1.3.0.0 – 1.3.3.3 | 15.x | 10.x – 11.x | constraints/frida15.txt |
| 1.3.4.0 – 1.4.3.0 | 16.x | 12.x – 13.x | constraints/frida16.txt |
| 1.4.4.0 – 1.6.3.1 | 17.x | 14.x | constraints/frida17-legacy.txt |
| 2.0.0+ | 17.x | 14.x | (none — requirements.txt) |
If you cannot upgrade frida-server, install a friTap version matching your
frida major using the constraints file from the table above (see
constraints/README.md for copy-paste recipes or
the dev/install_legacy.py helper). Set FRITAP_STRICT_FRIDA=1 to make a
frida-major mismatch fatal at startup instead of a warning.
If your target device runs an older frida-server (15.x or 16.x), or you
need the legacy 4-segment friTap line for frida 17.x, install via a
constraints file:
# frida 15.x → friTap 1.3.0.0–1.3.3.3
pip install fritap==1.3.3.3 -c https://raw.githubusercontent.com/fkie-cad/friTap/main/constraints/frida15.txt
# frida 16.x → friTap 1.3.4.0–1.4.3.0
pip install fritap==1.4.3.0 -c https://raw.githubusercontent.com/fkie-cad/friTap/main/constraints/frida16.txt
# frida 17.x (legacy 4-segment) → friTap 1.4.4.0–1.6.3.1
pip install fritap==1.6.3.1 -c https://raw.githubusercontent.com/fkie-cad/friTap/main/constraints/frida17-legacy.txt
Or from a fresh clone:
git clone https://github.com/fkie-cad/friTap && cd friTap
python dev/install_legacy.py --frida-major 16
See constraints/README.md for the full table and
caveats (notably: frida 15.x wheels target older Python versions).
>= python3.10>= 17, < 18) and frida-tools (>= 14, < 15)adb-command is in your PATHFor developers who want to contribute to friTap, we provide an automated setup:
# Clone and setup development environment
git clone https://github.com/fkie-cad/friTap.git
cd friTap
# Automated setup (recommended)
python setup_dev.py
# Manual setup
pip install -e ".[dev]" # friTap + dev extras (pytest, ruff)
npm ci --ignore-scripts # Install Node deps without auto-compile
./dev/compile_agent.sh # Compile TypeScript agent to JavaScript
friTap includes a comprehensive testing framework:
# Run all fast tests
python dev/run_tests.py --fast
# Run specific test categories
python dev/run_tests.py unit # Unit tests
python dev/run_tests.py agent # Agent compilation tests
python dev/run_tests.py integration # Mock integration tests
# Generate coverage report
python dev/run_tests.py coverage
dev extras (pip install -e ".[dev]")frida-compile)pytest-cov, pytest-mock, pytest-timeout)pyproject.toml)See DEVELOPMENT.md for detailed development setup and testing guide.
Contributions are always welcome. Just fork it and open a pull request! More details can be found in the CONTRIBUTING.md.
See the wiki for release notes.
If you use friTap in your research, please cite the following paper:
Daniel Baier, Alexander Basse, Jan-Niclas Hilgert, Martin Lambertz
TLS key material identification and extraction in memory: current state and future challenges
Forensic Science International: Digital Investigation, Volume 49, 2024, 301766.
https://doi.org/10.1016/j.fsidi.2024.301766
@article{baier2024tls,
title={TLS key material identification and extraction in memory: current state and future challenges},
author={Baier, Daniel and Basse, Alexander and Hilgert, Jan-Niclas and Lambertz, Martin},
journal={Forensic Science International: Digital Investigation},
volume={49},
pages={301766},
year={2024},
publisher={Elsevier},
doi={10.1016/j.fsidi.2024.301766}
}
A machine-readable version of this citation lives in CITATION.cff (as preferred-citation), so GitHub's "Cite this repository" button and tooling like Zotero will surface the same paper entry.
If you have any suggestions, or bug reports, please create an issue in the Issue Tracker.
In case you have any questions or other problems, feel free to send an email to:
Python
45.3%
JavaScript
29.4%
TypeScript
23.2%
Simplifying encrypted traffic analysis for researchers by making protocol decryption effortless.
537
stars
620
commits
Python
primary language
Aug 10, 2026
updated
Real-time key extraction and traffic decryption for security researchfriTap is a powerful tool designed to assist researchers in analyzing network traffic encapsulated in SSL/TLS. With its ability to automate key extraction, friTap is especially valuable when dealing with malware analysis or investigating privacy issues in applications. By simplifying the process of decrypting and inspecting encrypted traffic, friTap empowers researchers to uncover critical insights with ease.
Key features include seamless support for automated SSL/TLS key extraction, making it an ideal choice for scenarios requiring rapid and accurate traffic analysis. Whether you’re dissecting malicious network behavior or assessing data privacy compliance, friTap streamlines your workflow.
For more details, explore the OSDFCon webinar slides or check out our blog post.
This project was inspired by SSL_Logger and currently supports all major operating systems: Linux, Windows, Android, with partial support for macOS and iOS (still under development). More platforms and libraries will be added in future releases.
The main features of friTap are:
-k key.log)-p plaintext.pcap) — coverage varies by platform/library; see the support table belowfritap)fritap -r saved_capture.tap)--library-scan)Installation is simply a matter of pip3 install fritap. This will give you the fritap command. You can update an existing fritap installation with pip3 install --upgrade fritap.
On Linux/Windows/MacOS we can easily attach to a process by entering its name or its PID:
$ sudo fritap --pcap mycapture.pcap thunderbird
For mobile applications we just have to add the -m parameter to indicate that we are now attaching (or spawning) an Android or iOS app:
$ fritap -m -k keys.log com.example.app
Further ensure that the frida-server is running on the Android/iOS device.
friTap can also be used as a Python library within your project:
from friTap import SSL_Logger
For more details on integrating friTap into your Python project, check out the INTEGRATION.md guide.
friTap allows you to enhance its functionality by providing a custom Frida script during your session. This custom script will be invoked just before friTap applies its own hooks. To do so, use the -c parameter (more).
More examples on using friTap can be found in the USAGE.md. A detailed introduction using friTap on Android is under EXAMPLE.md as well.
Running fritap without any arguments launches an interactive Terminal User Interface (TUI):
$ fritap
The TUI provides a guided setup wizard that walks you through device selection, target process, and capture mode. You can also configure everything manually using keyboard shortcuts:
| Key | Action | Key | Action |
|---|---|---|---|
d | Select device | 1 | Full capture (keys + pcap) |
a | Attach to process | 2 | Key extraction only |
s | Spawn application | 3 | Plaintext pcap |
Enter | Start/stop capture | 4 | Live Wireshark (pipe) † |
v | Toggle verbose | 5 | Live Wireshark (auto-decrypt) † |
p | Select protocol | ? | Help |
q | Quit | e | Toggle experimental |
The TUI supports device selection for local, USB (Android/iOS), and remote devices, and can automatically install and start frida-server on connected devices.
† Live Wireshark options (4 and 5) require Unix-style FIFOs and are currently Linux/macOS only — they are not supported on Windows.
In certain scenarios, the library we want to hook offers no symbols or is statically linked with other libraries, making it challenging to directly hook functions. For example Cronet (libcronet.so) and Flutter (libflutter.so) are often statically linked with BoringSSL.
Despite the absence of symbols, we can still use friTap for parsing and hooking.
To solve this, we can use friTap with byte patterns to hook the desired functions. You can provide friTap with a JSON file that contains byte patterns for hooking specific functions, based on architecture and platform using the --patterns <byte-pattern-file.json> option.
In order to apply the apprioate hooks for the various byte patterns we distinguish between different hooking categories.
These categories include:
Each category has a primary and fallback byte pattern, allowing flexibility when the primary pattern fails. For libraries like BoringSSL, where TLS functionality is often statically linked into other binaries, we developed a tool called BoringSecretHunter. This tool automatically identifies the necessary byte patterns to hook BoringSSL by byte-pattern matching. BoringSecretHunter is available as a Docker container with pre-configured Ghidra environment:
# Create directories and copy target libraries
mkdir -p binary results
cp /path/to/libflutter.so binary/
# Run BoringSecretHunter
docker run --rm -v "$(pwd)/binary":/usr/local/src/binaries -v "$(pwd)/results":/host_output boringsecrethunter
# Use generated patterns with friTap
fritap --patterns results/libflutter.so_patterns.json -k keys.log target_app
More about the different hooking categories can be found in usage of byte-patterns in friTap.
Alternatively, you can use the --offsets <offset-file.json> option to hook functions using known offsets. friTap allows you to specify user-defined offsets (relative to the base address of the targeting SSL/socket library) or absolute virtual addresses for function resolution. This is done through a JSON file, which is passed using the --offsets parameter.
If the --offsets parameter is used, friTap will only overwrite the function addresses specified in the JSON file. For functions that are not specified, friTap will attempt to detect the addresses automatically (using symbols).
The absence of traffic or incomplete traffic capture in the resulting pcap file (-p <your.pcap>) may stem from various causes. Before submitting a new issue, consider attempting the following solutions:
There might be instances where friTap fails to retrieve socket information. In such scenarios, running friTap with default socket information (--enable_default_fd) could resolve the issue. This approach utilizes default socket information (127.0.0.1:1234 to 127.0.0.1:2345) for all traffic when the file descriptor (FD) cannot be used to obtain socket details:
fritap -m --enable_default_fd -p plaintext.pcap com.example.app
Traffic originating from a subprocess could be another contributing factor. To capture this traffic, friTap can leverage Frida's spawn gating feature, which intercepts newly spawned processes using the --enable_spawn_gating parameter:
fritap -m -p log.pcap --enable_spawn_gating com.example.app
In cases where the target library solely supports key extraction (cf. the table below), you can utilize the -k <key.log> parameter alongside full packet capture:
fritap -m -p log.pcap --full_capture -k keys.log com.example.app
If these approaches do not address your issue, please create a detailed issue report to aid in troubleshooting. To facilitate a more effective diagnosis, include the following information in your report:
fritap -do -v com.example.app
| Library | Linux | Windows | MacOSX | Android | iOS |
|---------------------------|---------------|---------------|----------|----------|--------------|
| OpenSSL | Full | R/W-Hook only | TBI | Full | TBI |
| BoringSSL | Full | R/W-Hook only | Keys | Full | Keys |
| NSS | Full | R/W-Hook only | TBI | TBA | TBI |
| GnuTLS | R/W-Hook only | R/W-Hook only | TBI | Full | TBI |
| WolfSSL | R/W-Hook only | R/W-Hook only | TBI | Full | TBI |
| MbedTLS | R/W-Hook only | R/W-Hook only | TBI | Full | TBI |
| Bouncycastle/Spongycastle | TBA | TBA | TBA | Full | TBA |
| Conscrypt | TBA | TBA | TBA | Full | TBA |
| S2n-tls | Full | LibNO | TBA | Full | LibNO |
| RusTLS | Keys | TBI | TBI | Keys | TBI |
R/W-Hook only = Logging data sent and received by process
Keys = Only the keying material can be extracted
Full = Logging data send and received by process + Logging keys used for secure connection
TBA = To be answered
TBI = To be implemented
LibNO = This library is not supported for this plattform
We verified the Windows implementations only for Windows 10
friTap targets a single frida major per friTap-major release. From 2.0.0
onward, every frida major bump produces a friTap major bump in the same
commit (enforced by CI; see RELEASING.md).
| friTap range | frida required | frida-tools required | Constraints file |
|---|---|---|---|
| 1.3.0.0 – 1.3.3.3 | 15.x | 10.x – 11.x | constraints/frida15.txt |
| 1.3.4.0 – 1.4.3.0 | 16.x | 12.x – 13.x | constraints/frida16.txt |
| 1.4.4.0 – 1.6.3.1 | 17.x | 14.x | constraints/frida17-legacy.txt |
| 2.0.0+ | 17.x | 14.x | (none — requirements.txt) |
If you cannot upgrade frida-server, install a friTap version matching your
frida major using the constraints file from the table above (see
constraints/README.md for copy-paste recipes or
the dev/install_legacy.py helper). Set FRITAP_STRICT_FRIDA=1 to make a
frida-major mismatch fatal at startup instead of a warning.
If your target device runs an older frida-server (15.x or 16.x), or you
need the legacy 4-segment friTap line for frida 17.x, install via a
constraints file:
# frida 15.x → friTap 1.3.0.0–1.3.3.3
pip install fritap==1.3.3.3 -c https://raw.githubusercontent.com/fkie-cad/friTap/main/constraints/frida15.txt
# frida 16.x → friTap 1.3.4.0–1.4.3.0
pip install fritap==1.4.3.0 -c https://raw.githubusercontent.com/fkie-cad/friTap/main/constraints/frida16.txt
# frida 17.x (legacy 4-segment) → friTap 1.4.4.0–1.6.3.1
pip install fritap==1.6.3.1 -c https://raw.githubusercontent.com/fkie-cad/friTap/main/constraints/frida17-legacy.txt
Or from a fresh clone:
git clone https://github.com/fkie-cad/friTap && cd friTap
python dev/install_legacy.py --frida-major 16
See constraints/README.md for the full table and
caveats (notably: frida 15.x wheels target older Python versions).
>= python3.10>= 17, < 18) and frida-tools (>= 14, < 15)adb-command is in your PATHFor developers who want to contribute to friTap, we provide an automated setup:
# Clone and setup development environment
git clone https://github.com/fkie-cad/friTap.git
cd friTap
# Automated setup (recommended)
python setup_dev.py
# Manual setup
pip install -e ".[dev]" # friTap + dev extras (pytest, ruff)
npm ci --ignore-scripts # Install Node deps without auto-compile
./dev/compile_agent.sh # Compile TypeScript agent to JavaScript
friTap includes a comprehensive testing framework:
# Run all fast tests
python dev/run_tests.py --fast
# Run specific test categories
python dev/run_tests.py unit # Unit tests
python dev/run_tests.py agent # Agent compilation tests
python dev/run_tests.py integration # Mock integration tests
# Generate coverage report
python dev/run_tests.py coverage
dev extras (pip install -e ".[dev]")frida-compile)pytest-cov, pytest-mock, pytest-timeout)pyproject.toml)See DEVELOPMENT.md for detailed development setup and testing guide.
Contributions are always welcome. Just fork it and open a pull request! More details can be found in the CONTRIBUTING.md.
See the wiki for release notes.
If you use friTap in your research, please cite the following paper:
Daniel Baier, Alexander Basse, Jan-Niclas Hilgert, Martin Lambertz
TLS key material identification and extraction in memory: current state and future challenges
Forensic Science International: Digital Investigation, Volume 49, 2024, 301766.
https://doi.org/10.1016/j.fsidi.2024.301766
@article{baier2024tls,
title={TLS key material identification and extraction in memory: current state and future challenges},
author={Baier, Daniel and Basse, Alexander and Hilgert, Jan-Niclas and Lambertz, Martin},
journal={Forensic Science International: Digital Investigation},
volume={49},
pages={301766},
year={2024},
publisher={Elsevier},
doi={10.1016/j.fsidi.2024.301766}
}
A machine-readable version of this citation lives in CITATION.cff (as preferred-citation), so GitHub's "Cite this repository" button and tooling like Zotero will surface the same paper entry.
If you have any suggestions, or bug reports, please create an issue in the Issue Tracker.
In case you have any questions or other problems, feel free to send an email to:
Python
45.3%
JavaScript
29.4%
TypeScript
23.2%