Python Scripting Engine - The Art Of Browser Automation with Python

alt text

The Python Scripting Engine has following options -

Python Scripting Engine:
  --python PYTHON       Executes provided python code.
  --python-after PYTHON_AFTER
                        Executes provided python code after single fuzzing attempt of form.
  --python-file PYTHON_FILE
                        Reads and Executes provided python code from file.
  --python-request PYTHON_REQUEST
                        Python code which will modify the HTTP Request.
  --python-request-file PYTHON_REQUEST_FILE
                        File containing python code to manipulate HTTP Request.
  --python-response PYTHON_RESPONSE
                        Python code to manipulate HTTP Response.
  --python-response-file PYTHON_RESPONSE_FILE
                        File containing python code to manipulate HTTP response.

The Python Scripting Engine allows users to custom python code before/after fuzzing the form and control the browser object. It provides the driver to automate and interact with the running browser using python.

Owning the browser using --python, --python-after, --python-file options

The --python options takes python from pentester and executes it. The --python-after is same just executes python after --button is pressed. The --python-file is same as --python option just takes .js files to execute.

This provides insane amount of flexibility, extendibility and modification. You can interact with the browser using driver object provided by Python Scripting Engine.

This allows users to do whatever they want to do, just the barrier is imagination.

Few things which you can do with this are -

- Create python code to crack the captchas
- Fuzz multi pages forms
- Automate browser further using the browser object provided by Python Scripting Engine, which is not possible via javascript option
- Tackle the complex navigation by automating the browser

For Example, following is the code we used to fuzz the two page application. First page requires users to enter the mobile number and other page verifies that number. Now I want to fuzz the second web page so I wrote the following python code to automate the first page, and then fuzz the second page using BrowserBruter :

python3 BrowserBruter.py --elements text-center --button font-semibold --payloads usernames.txt --target https://localhost.com/ --attack 1 --python "e1 = driver.find_element(By.CSS_SELECTOR, 'input.w-full.text-center'); e1.send_keys('0987654321'); driver.find_element(By.CSS_SELECTOR, 'button.btn-primary.mt-6.w-full.font-semibold').click(); sleep(0.5)"

Here,

  • --elements text-center is the text field which takes the otp on second page
  • --button font-semibold is the button to be pressed on the second page
  • --payloads usernames.txt is file containing payloads
  • --target https://localhost.com/ is the target application
  • --attack 1 specifies that this is sniper attack
  • --python "e1 = driver.find_element(By.CSS_SELECTOR, 'input.w-full.text-center'); e1.send_keys('0987654321'); driver.find_element(By.CSS_SELECTOR, 'button.btn-primary.mt-6.w-full.font-semibold').click(); sleep(0.5)" is the python code to automate the first page of the flow.

This was an actual real world application we fuzzed using the BrowserBruter and automated the two page registration flow using Python Scripting Engine as shown below -

alt text

Note: the details like target and scope are confidential that's why they are hidden in above image.

Owning HTTP traffic with --python-request, --python-request-file, --python-response, --python-response-file

The Python Scripting Engine can help you to control the HTTP traffic as well.

The --python-request option is used to take Python code which will be executed to control the HTTP request. For Example, consider the below code:

python3 BrowserBruter.py --elements username,password --payloads sqli.txt --target http://localhost/login3.php --button "button.btn.btn-default" --attack 1 --fill username,password --python-request "request.headers['python-added'] = 'added-by-python'"

Here,

  • --elements username,password are list of elements to be fuzzed
  • --payloads sqli.txt are list of payloads
  • --target http://localhost/login3.php is the URL of target
  • --button "button.btn.btn-default" is the button to press
  • --attack 1 is the sniper attack mode
  • --fill username,password indicate the username,password field to be filled
  • --python-request "request.headers['python-added'] = 'added-by-python'" the python code to modify the HTTP request

The --python-request-file is the same as --python-request options just takes python code in file.

The --python-response option is used to take Python code which will be executed to control the HTTP response. For Example, consider the below code:

python3 BrowserBruter.py --elements username,password --payloads sqli.txt --target http://localhost/login3.php --button "button.btn.btn-default" --attack 1 --fill username,password --python-response "response.headers['python-added'] = 'added-by-python'"

Here,

  • --elements username,password are list of elements to be fuzzed
  • --payloads sqli.txt are list of payloads
  • --target http://localhost/login3.php is the URL of target
  • --button "button.btn.btn-default" is the button to press
  • --attack 1 is the sniper attack mode
  • --fill username,password indicate the username,password field to be filled
  • --python-response "response.headers['python-added'] = 'added-by-python'" the python code to modify the HTTP request

The --python-response-file is the same as --python-response options just takes python code in file.

So this is how you can utilize the Python Scripting Engine do whatever you want to do. These are by far the most powerful options available in Browser Bruter.


Integrating Machine Learning into Browser Bruter to crack the captchas

Yes, The Python Scripting Engine is just so flexible, it literally allows to integrate the Machine Learning Models into Browser Bruter for better.

For Example, below is the sample web page for login, but it has captcha image as can be shown below -

alt text

Note: Above lab can be found inside res/samples/captcha/ directory and can be run using python3 captcha.py

Now, After training a Machine Learning model to crack the above captcha, I have saved it as can be shown below.

alt text

Now, I have written following python code which will utilize the Machine Learning to crack captcha:

import os
import random
import cv2
import string
from PIL import Image, ImageDraw, ImageFont
from captcha.image import ImageCaptcha
import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.utils import to_categorical
import requests

# Function to preprocess and predict text from a sample captcha
def predict_captcha(model, sample_captcha_path, label_to_int):
    # Load and preprocess the sample PNG captcha
    sample_captcha = cv2.imread(sample_captcha_path, cv2.IMREAD_GRAYSCALE)
    #sample_captcha = cv2.cvtColor(sample_captcha_image, cv2.COLOR_BGR2GRAY)
    sample_captcha = cv2.resize(sample_captcha, (28 * 4, 28))

    # Chop the sample captcha into four characters
    character_width = 28
    characters = [sample_captcha[:, i:i + character_width] for i in range(0, sample_captcha.shape[1], character_width)]

    # Preprocess each character and make predictions
    predicted_text = ""
    for char_image in characters:
        char_image = char_image.reshape((1, 28, 28, 1)).astype("float32") / 255.0
        predictions = model.predict(char_image)
        predicted_label_idx = np.argmax(predictions)
        predicted_label = list(label_to_int.keys())[list(label_to_int.values()).index(predicted_label_idx)]
        predicted_text += predicted_label

    return predicted_text

# Map labels to integers
label_to_int = {char: idx for idx, char in enumerate(string.ascii_letters + string.digits)}
num_classes = len(label_to_int)

# Load the saved model
model = tf.keras.models.load_model("res/samples/captcha_model.keras") # Change this to the correct path of the model (better provide full path)
# Re-compile the model to ensure metrics are set
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])

image_element = driver.find_element(By.ID, "captcha_image")
img_url = image_element.get_attribute('src')

response = requests.get(img_url)
with open('image.png', 'wb') as file:
    file.write(response.content)

# Example usage of the prediction function
predicted_text = predict_captcha(model, 'image.png', label_to_int)
print("Predicted Text:", predicted_text)

image_input_element = driver.find_element(By.ID, "captcha_input")

image_input_element.clear()
image_input_element.send_keys(predicted_text)

Now we can provide above code to Browser Bruter using below command:

python3 BrowserBruter.py --elements username,password --payloads sqli.txt --target http://localhost:5000/ --button submit --attack 1 --fill username,password --python-file res/samples/bb-predict.py --debug

And we have successfully leverage the potential of machine learning in to Browser Bruter.

This is a small Proof of Concept for the functionality of the Python Scripting Engine, the possibilities is countless.


Hope on to the next section to learn about options that alter the working of Browser.

results matching ""

    No results matching ""