Skip to content

Commit

Permalink
add feature for custom frida scripts; minor improvements; adjust READ…
Browse files Browse the repository at this point in the history
…ME.md with new features
  • Loading branch information
monkeywave committed Nov 20, 2024
1 parent 4997773 commit 7e227df
Show file tree
Hide file tree
Showing 12 changed files with 385 additions and 39 deletions.
144 changes: 144 additions & 0 deletions INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# friTap Integration Guide

This guide explains how to use the `friTap` as a Python library to hook into applications, log SSL/TLS data, and manage its integration with the `AndroidFridaManager`. The only required argument to initialize `friTap` is the app package name to be hooked.

---

## Basic Usage: Hooking an App and Logging SSL/TLS Data

The following example demonstrates how to use `friTap` to hook into an application and log its SSL/TLS traffic.

### **Code Example**

```python
from friTap import SSL_Logger
import sys

try:
print("Start logging")
print("Press Ctrl+C to stop logging")

# Specify the app package to hook
app_package = "YouTube"

# Initialize SSL_Logger with optional arguments
ssl_log = SSL_Logger(
app_package,
verbose=True, # Enable verbose output
mobile=True, # Indicate that the target app is running on a mobile device
keylog="keylogtest3.log", # Path to save SSL key log
debug_output=True # Enable debug output
)

# Start friTap session
process = ssl_log.start_fritap_session()

# Wait for user input to stop
sys.stdin.read()

except KeyboardInterrupt:
# Detach process on interruption
process.detach()
print("Logging stopped.")
```

---

## Arguments for `SSL_Logger`

| Argument | Type | Default | Description |
|-------------------------|---------|--------------|-----------------------------------------------------------------------------|
| `app` | `str` | **Required** | The package name of the app to be hooked. |
| `pcap_name` | `str` | `None` | Name of the PCAP file to save captured traffic. |
| `verbose` | `bool` | `False` | Enable verbose output for debugging purposes. |
| `spawn` | `bool` | `False` | Spawn the app automatically if not running. |
| `keylog` | `str` | `None` | Path to save the SSL/TLS key log file. |
| `enable_spawn_gating` | `bool` | `False` | Enable gating for app spawning. |
| `mobile` | `bool` | `False` | Indicate whether the target app is on a mobile device. |
| `live` | `bool` | `False` | Enable live monitoring of the app's traffic. |
| `environment_file` | `str` | `None` | Path to the environment configuration file. |
| `debug_mode` | `bool` | `False` | Enable debugging mode for more detailed information. |
| `full_capture` | `bool` | `False` | Enable full capture of traffic. |
| `socket_trace` | `bool` | `False` | Enable tracing of socket connections. |
| `host` | `bool` | `False` | Indicate whether the app is running on a host machine. |
| `offsets` | `str` | `None` | Specify custom offsets for hooking. |
| `debug_output` | `bool` | `False` | Enable debug output for detailed logging. |
| `experimental` | `bool` | `False` | Enable experimental features. |
| `anti_root` | `bool` | `False` | Enable anti-root detection mechanisms. |
| `payload_modification` | `bool` | `False` | Enable payload modification during traffic capture. |
| `enable_default_fd` | `bool` | `False` | Enable default file descriptor handling. |
| `patterns` | `list` | `None` | List of patterns to match during traffic capture. |
| `custom_hook_script` | `str` | `None` | Path to a custom Frida hook script to be executed during the session. |

---

## Advanced Usage: Using friTap as a Job in AndroidFridaManager

friTap can also be used as a job within the `AndroidFridaManager` framework. This allows you to manage friTap sessions as part of a larger job workflow.

### **Code Example**

```python
from friTap import SSL_Logger
from AndroidFridaManager import JobManager
import sys

try:
print("Start logging")
print("Press Ctrl+C to stop logging")

# Initialize JobManager
job_manager = JobManager()

# Specify app package
app_package = "YouTube"

# Initialize SSL_Logger with optional arguments
ssl_log = SSL_Logger(
app_package,
verbose=True, # Enable verbose output
keylog="keylogtest3.log", # Path to save SSL key log
debug_output=True # Enable debug output
)

# Get the Frida script path from SSL_Logger
frida_script_path = ssl_log.get_fritap_frida_script_path()

# Set up the Frida session in the JobManager
job_manager.setup_frida_session(
app_package,
ssl_log.on_fritap_message,
should_spawn=False # Do not spawn the process
)

# Start the job with a custom hooking handler
job_manager.start_job(
frida_script_path,
custom_hooking_handler_name=ssl_log.on_fritap_message
)

print("[*] Running jobs:", job_manager.running_jobs())

# Wait for user input to stop
sys.stdin.read()

except KeyboardInterrupt:
# Stop all running jobs
job_manager.stop_jobs()
print("Jobs stopped.")
```

---

## Key Notes

1. **App Package Name**:
- The app package name is the only required argument to initialize `SSL_Logger`. All other arguments are optional but provide additional functionality like saving key logs or enabling debug output.

2. **Custom Hooks**:
- If you want to execute custom Frida scripts, specify the path using the `custom_hook_script` argument in `SSL_Logger`.

3. **Integration with AndroidFridaManager**:
- Using friTap as part of `AndroidFridaManager` allows you to manage friTap hooks alongside other Frida jobs seamlessly.

---
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
</p>

# friTap
![version](https://img.shields.io/badge/version-1.2.3.6-blue) [![PyPI version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=py&r=r&ts=1683906897&type=6e&v=1.2.3.6&x2=0)](https://badge.fury.io/py/friTap)
![version](https://img.shields.io/badge/version-1.2.4.0-blue) [![PyPI version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=py&r=r&ts=1683906897&type=6e&v=1.2.4.0&x2=0)](https://badge.fury.io/py/friTap)

The goal of this project is to help researchers to analyze traffic encapsulated in SSL or TLS. For details have a view into the [OSDFCon webinar slides](assets/friTapOSDFConwebinar.pdf) or in [this blog post](https://lolcads.github.io/posts/2022/08/fritap/).

Expand Down Expand Up @@ -47,8 +47,13 @@ $ which friTap
$ sudo -E /home/daniel/.local/bin/friTap
```

friTap can also be used as a Python library within your project:
```python
from friTap import SSL_Logger
```
For more details on integrating friTap into your Python project, check out the [INTEGRATION.md](./INTEGRATION.md) guide.


friTap allows you to enhance its functionality by providing a custom Frida script during your session. To do so, use the `-c` parameter ([more](./USAGE.md#Using-friTap-with-a-custom-Frida-scripts)).
More examples on using friTap can be found in the [USAGE.md](./USAGE.md). A detailed introduction using friTap on Android is under [EXAMPLE.md](./EXAMPLE.md) as well.

## Hooking Libraries Without Symbols
Expand Down
62 changes: 61 additions & 1 deletion USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,64 @@ This category hooks the SSL_Write function, which is responsible for writing enc
}
```
Primary Pattern: Hook the SSL_Write function.
Fallback Pattern: If the primary pattern fails, the fallback pattern is tried.
Fallback Pattern: If the primary pattern fails, the fallback pattern is tried.



## Using friTap with a custom Frida scripts

This guide explains how to use friTap with a custom Frida script to enhance its functionality. Using the `-c` parameter, you can specify a custom script to be executed during the friTap session.

---

### Example Command

To invoke friTap with a custom script, use the following command:

```bash
fritap -m -k cronet18.keys -do -c "/path/to/custom.js" -v YouTube
```

### **Explanation of Parameters**
- `-m`: Indicates that the app is running on a mobile device.
- `-k`: Specifies the output file for the SSL key log.
- `-do`: Enables debug output for detailed logging.
- `-c`: Specifies the path to the custom Frida script to be executed.
- `-v`: Enables verbose logging.
- `YouTube`: The name of the app package to be hooked.

---

### Custom Script Example

The following is an example of a custom Frida script (`custom.js`) that iterates over all loaded modules, checks for exports containing `ssl` or `tls`, and sends relevant information to friTap.

```javascript
/*
* Example code for using custom hooks in friTap.
* To ensure friTap prints content, include a "custom" field in your message payload.
* The value of this "custom" field will be displayed by friTap.
*/

// Iterate over all loaded modules
Process.enumerateModules().forEach(module => {
// Enumerate exports for each module
module.enumerateExports().forEach(exp => {
// Check if the export name contains "ssl" or "tls"
if (exp.name.toLowerCase().includes("ssl") || exp.name.toLowerCase().includes("tls")) {
// Send the result to Python
send({
custom: `Found export: ${exp.name} in module: ${module.name} at address: ${exp.address}`
});
}
});
});
```
friTap will print any messages sent with a `custom` field during execution.
You can download the above example code as `custom.js` file using the link below:

**[Download custom.js](./custom.js)**

Place this file in the same directory as your friTap installation or provide the absolute path to the `-c` parameter.


20 changes: 20 additions & 0 deletions agent/shared/shared_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@ export function getModuleNames(){
return moduleNames;
}

export function checkNumberOfExports(moduleName: string): number {
try {
// Get the module by name
const module = Process.getModuleByName(moduleName);

// Enumerate exports of the module
const exports = module.enumerateExports();

// Get the number of exports
const numberOfExports = exports.length;

// Log the result
devlog(`The module "${moduleName}" has ${numberOfExports} exports.`);
return numberOfExports;
} catch (error) {
devlog(`Error checking exports for module "${moduleName}": ${error}`);
return -1;
}
}

export function readAddresses(moduleName: string, library_method_mapping: { [key: string]: Array<string> }): { [library_name: string]: { [functionName: string]: NativePointer } } {
const resolver = new ApiResolver("module");
const addresses: { [library_name: string]: { [functionName: string]: NativePointer } } = {};
Expand Down
6 changes: 4 additions & 2 deletions agent/ssl_lib/openssl_boringssl.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readAddresses, getPortsAndAddresses, getBaseAddress, isSymbolAvailable } from "../shared/shared_functions.js";
import { readAddresses, getPortsAndAddresses, getBaseAddress, isSymbolAvailable, checkNumberOfExports } from "../shared/shared_functions.js";
import { getOffsets, offsets, enable_default_fd } from "../ssl_log.js";
import { devlog, log } from "../util/log.js";

Expand Down Expand Up @@ -94,7 +94,9 @@ export class OpenSSL_BoringSSL {
if(typeof passed_library_method_mapping !== 'undefined'){
this.library_method_mapping = passed_library_method_mapping;
}else{
this.library_method_mapping[`*${moduleName}*`] = ["SSL_read", "SSL_write", "SSL_get_fd", "SSL_get_session", "SSL_SESSION_get_id", "SSL_new", "SSL_CTX_set_keylog_callback"]
if(checkNumberOfExports(moduleName) > 2 ){
this.library_method_mapping[`*${moduleName}*`] = ["SSL_read", "SSL_write", "SSL_get_fd", "SSL_get_session", "SSL_SESSION_get_id", "SSL_new", "SSL_CTX_set_keylog_callback"]
}
this.library_method_mapping[`*${socket_library}*`] = ["getpeername", "getsockname", "ntohs", "ntohl"]
}

Expand Down
19 changes: 19 additions & 0 deletions custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Example code for using custom hooks in friTap.
* To ensure friTap prints content, include a "custom" field in your message payload.
* The value of this "custom" field will be displayed by friTap.
*/

// Iterate over all loaded modules
Process.enumerateModules().forEach(module => {
// Enumerate exports for each module
module.enumerateExports().forEach(exp => {
// Check if the export name contains "ssl" or "tls" || exp.name.toLowerCase().includes("tls")
if (exp.name.toLowerCase().includes("ssl") ) {
// Send the result to Python
send({
custom: `Found export: ${exp.name} in module: ${module.name} at address: ${exp.address}`
});
}
});
});
3 changes: 3 additions & 0 deletions friTap/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Expose SSL_Logger at the package level
from .friTap import SSL_Logger
Loading

0 comments on commit 7e227df

Please sign in to comment.