Skip to main content
This guide explains how to intercept bet365’s obfuscated JavaScript files, deobfuscate them on-the-fly, and inject the deobfuscated code back into the browser.

Overview

The interception workflow uses mitmproxy as a man-in-the-middle proxy to:
  1. Intercept HTTP responses from bet365’s /Api/1/Blob endpoint
  2. Extract obfuscated JavaScript files from the response
  3. Run deobfuscation transforms using jscodeshift
  4. Inject the deobfuscated code back into the browser
This tool is for educational and research purposes only. Use responsibly and in accordance with bet365’s terms of service.

Starting the Proxy

1

Launch mitmproxy

Start the proxy server with the JavaScript interceptor script:
./mitmproxy.sh
This runs:
mitmproxy -s mitmproxy/src/python/main/download-payload.py
The proxy will start listening on http://localhost:8080 by default.
Keep this terminal window open - you’ll see live logs of intercepted requests here.
2

Launch Chrome with proxy settings

Open a new terminal and start Chrome configured to use the proxy.For macOS:
open -a "Google Chrome" --args \
  --proxy-server=http://localhost:8080 \
  --enable-logging \
  --v=1 \
  --user-data-dir=$(pwd)/chrome-profile
For Linux:
google-chrome \
  --proxy-server=http://localhost:8080 \
  --enable-logging \
  --v=1 \
  --user-data-dir=$(pwd)/chrome-profile &
For Windows:
& "C:\Program Files\Google\Chrome\Application\chrome.exe" `
  --proxy-server=http://localhost:8080 `
  --enable-logging `
  --v=1 `
  --user-data-dir=$pwd\chrome-profile
The --user-data-dir flag creates an isolated Chrome profile in ./chrome-profile/. This keeps your personal browsing data separate.
3

Navigate to bet365

In the proxy-configured Chrome window, navigate to https://www.bet365.com.Watch the mitmproxy terminal - you should see:
INFO Intercepting response: https://www.bet365.com/Api/1/Blob

How the Interception Works

The download-payload.py script (loaded by mitmproxy) performs the following:

1. Request Filtering

The script filters for specific endpoints:
self.filter = flowfilter.parse("~u '/Api/1/Blob'")
Only responses matching this URL pattern are intercepted.

2. Response Parsing

bet365 returns multiple files in a single response, delimited by \x03\x06\x05:
file_delimiter = b'\x03'b'\x06'b'\x05'
split_content_bytes = flow.response.content.split(self.file_delimiter)
Each file is prefixed with a byte indicating its type:
  • 4 = JavaScript file
  • 5 = CSS file

3. Obfuscation Detection

The script checks if a JavaScript file contains obfuscated code:
obfuscated_start_string = "(function(){ var _0x123a="
is_obfuscated_content = content_start_string.startswith(self.obfuscated_start_string)

4. On-the-Fly Deobfuscation

When obfuscated code is detected:
if self.refactor_script_on_fly:
    refactor_file = Path(self.javascript_base_path + "/refactor-obfuscated-code-jscodeshift.js")
    subprocess.run([self.node_executable_file, refactor_file, received_file_name, deobfuscated_file_name])
This calls the jscodeshift transformation pipeline to deobfuscate the code.

5. Code Injection

The final step combines:
  • pre-transform-code.js - Debugging helpers and logging functions
  • Deobfuscated JavaScript - The transformed code
  • post-transform-code.js - Additional runtime patches
complete_file_content_string = (
    pre_transform_code_content_string + 
    deobfuscated_file_content_minified_string + 
    post_transform_code_content_string
)
This combined code is then injected back into the response sent to the browser.

Output Files

All intercepted files are saved to the output/ directory with timestamps:
output/
├── 1234567890.123-received-0.js    # Original obfuscated code
├── 1234567890.123-deobfuscated-0.js # Intermediate deobfuscated output
├── 1234567890.123-sent-0.js         # Final code sent to browser
└── ...
The -received- files show what bet365 actually sent, while -sent- files show what was injected into your browser. Compare them to understand the transformations.

Saving Obfuscated Code for Analysis

To save a copy of the obfuscated code for later analysis:
python mitmproxy/src/python/save_obfuscated_code.py
This script:
  1. Searches the output/ directory for JavaScript files starting with (function(){
  2. Copies the first match to mitmproxy/src/javascript/obfuscated/
  3. Creates a symlink at mitmproxy/src/javascript/obfuscated-new-raw.js
bet365 frequently rotates their obfuscated code. The project maintains a collection of historical versions in mitmproxy/src/javascript/obfuscated/ for comparison and testing.

Debugging Console Output

The --enable-logging --v=1 flags enable Chrome’s debug logging:
tail -f ./chrome-profile/chrome_debug.log | sed -En "s/.*inside.*\\]: (.*)\", source:  \(3\)/\1/p"
This filters the log to show only JSON output from the injected debugging code (from pre-transform-code.js).

Configuration Options

You can modify the behavior by editing download-payload.py:
VariableDefaultDescription
refactor_script_on_flyTrueDeobfuscate code in real-time vs. using pre-deobfuscated file
output_all_filesTrueSave all intercepted files (CSS, non-obfuscated JS) to output/

Recommendations

1

Use an isolated Chrome profile

Always use --user-data-dir to create a separate profile for proxy testing. This prevents interference with your normal browsing.
2

Install Clear Cache extension

bet365 heavily caches JavaScript. Install a “Clear Cache” extension and bind it to a keyboard shortcut for quick cache clearing between tests.
3

Monitor the output directory

Keep an eye on output/ to ensure files are being intercepted correctly:
watch -n 1 ls -lht output/ | head -20

Troubleshooting

No Files Intercepted

Symptoms: mitmproxy is running but no files appear in output/ Solutions:
  • Verify Chrome is using the proxy: Visit http://mitm.it in the proxied browser
  • Check if bet365 is using a different endpoint (URL patterns may have changed)
  • Clear Chrome cache and reload bet365

SSL Certificate Errors

Symptoms: Chrome shows SSL warnings for bet365 Solutions:
  1. Visit http://mitm.it in the proxied browser
  2. Download and install the mitmproxy CA certificate for your OS
  3. Restart Chrome

Obfuscation Pattern Changed

Symptoms: Files are intercepted but not deobfuscated Solutions:
  • Check if the obfuscation detection string has changed
  • Update obfuscated_start_string in download-payload.py
  • See Deobfuscation Workflow for analyzing new obfuscation patterns

Next Steps

Now that you can intercept requests:

Build docs developers (and LLMs) love