Skip to content

This tool was open sourced as part of JARM Randomizer: Evading JARM Fingerprinting for HiTB Amsterdam 2021.

License

Notifications You must be signed in to change notification settings

netskopeoss/jarm_randomizer

Repository files navigation

Netskope Threat Labs logo

JARM Randomizer

JARM Randomizer

Introduction

JARM Randomizer is a Python3 tool that iterates over supported server side TLS version and Cipher suites to defeat JARM based fingerprinting. This tool was open sourced as part of JARM Randomizer: Evading JARM Fingerprinting for HiTB Amsterdam 2021.

Setup

Dependencies

This tool relies on the following to be installed on the system:

Once these dependencies has been installed, run pipenv install in the root directory to setup the virtual environment and install the required dependencies.

Usage

Configuration file

The config.py file present in the root directory can be modified to match the desired configurations.

To set what network/port you would like the proxy to serve, change these configurations:

# Configurations for the proxy
ip = '0.0.0.0'
port = 8443

To set what private key and SSL/TLS certificate path, change these configurations:

# Path to the TLS private key and cert files
keyfile = 'key.pem'
certfile = "cert.pem"

During the setup process, the proxy will read in and output certain required files. To tweak these file paths (Possibly to output them all in an output directory), change these configurations:

# File path settings
paths = {
    'possible_jarms': './possible_jarms.json', # The output file that has the possible JARMs, calid TLS - Cipher pairs, and general stats of occurence on the internet.
    'valid_configs': './valid_configs.json', # A lighter version of the possible_jarms.json that just has the TLS - Cipher pairs. 
    'invalid_configs': './invalid_configs.json', # A list of TLS - Cipher pairs that the proxy can not support.
    'raw_jarm_stats': './raw_jarm_stats.json', # A raw dump of everything the proxy found during setup. Helpful for debugging and research.
    'red_team_tool_jarms': './red_team_tool_jarms.json', # An input file contianing JARMs for red team tools that was mapped from https://github.com/cedowens/C2-JARM.
}

If these API keys are provided, the setup process will also check the possible JARMs for occurence on the internet.

# API keys for grabbing JARM metrics
SHODAN_KEY = ''
BINARY_EDGE_KEY = ''

If there is a specific TLS - Cipher pair that is desired, change these configurations to match.

# If there is a specific config that is required based on the stats/preference.
# For now, you only have the option to set both or none...will come back and change this
force_ssl_version = None # E.g., 2
force_cipher = None # E.g., 'ECDHE-RSA-CHACHA20-POLY1305'

If you would like to cycle through the TLS - Cipher pairs that are supported on a system, change these configurations to match.

# Cycle JARM configs at certain interval. Avoid setting this and the force_ssl_version and
# force_cipher above. That would not work too well
cycle_jarms = True
cycle_interval_secs = 5

Grabbing valid configurations

Once the config.py has been tweaked to match the desired configurations, run the following command to setup the proxy

ubuntu@jarm:~/jarm_randomizer$ chmod u+x ./setup.sh && ./setup.sh

[x] Grabbing the list of ciphers that are supported on this system
[x] Running setup.py to grab the valid JARMs
[X] Finding all the possible JARMs
[x] Validating tls 2 and cipher AES128-GCM-SHA256
127.0.0.1 - - [11/May/2021 17:32:25] "GET /http://google.com HTTP/1.1" 200 -
[x] Validating tls 2 and cipher AES128-SHA
...
[X] There are 27 possible JARMS across 70 TLS - Cipher pairs
[X] Grabbing the metrics for the JARMs...might take a while for long list of JARMs
[X] Writing the results to disk
[x] Proxy is ready to use
[x] Run python3 ./main.py to start the proxy server

If there is no private key and certificate at the specified file paths, this script will generate a self signed certificate for testing purposes.

Running Proxy

Once the config.py has been updated to match the desire configurations, and setup.sh has been run, the proxy is ready to use.

Run the following command to start running the proxy

ubuntu@jarm:~/jarm_randomizer$ pipenv run python3 ./main.py

[x] Selected configs: TLS -> 5, Cipher -> ECDHE-RSA-CHACHA20-POLY1305, JARM -> 3fd3fd0003fd3fd0003fd3fd3fd3fd02098c5f1b1aef82f7daaf9fed36c4e8
[x] Server running on https://0.0.0.0:8443 forever...

Testing the proxy

If we run the following command, we should recieve a valid proxied response

ubuntu@jarm:~$ curl -k https://127.0.0.1:8443/http://google.com

In the above example add -k if the certificate was self signed.

The proxy_handler.py file contains logic to handle the specific proxy request. If other proxy specific changes are required, change this script to match.

Future Improvements

We have ongoing research to identify areas of improvment around JARM randomizer including:

  • Scale to generate larger list of signatures
  • Ability to mimic a targeted server’s JARM
  • Dig deeper into the extensions
  • Stick sessions to not rotate configuration based on IP address

For the latest research around JARM Randomizer, check out our Blog

Feedback

Any and all feedback around JARM Randomizer are welcome:

About

This tool was open sourced as part of JARM Randomizer: Evading JARM Fingerprinting for HiTB Amsterdam 2021.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published