From a5301aa549023f20f9fe15447a7273bd3a9a7e63 Mon Sep 17 00:00:00 2001 From: H-Ayman Date: Wed, 24 Apr 2024 09:55:32 +0100 Subject: [PATCH] commit1 --- logindetect.py | 103 ++++++++++++++++++++++++++++++++++++++++++ loginform.py | 4 +- loginsele.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++++ newlogin.py | 27 +++++++++++ 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 logindetect.py create mode 100644 loginsele.py create mode 100644 newlogin.py diff --git a/logindetect.py b/logindetect.py new file mode 100644 index 0000000..e1946e5 --- /dev/null +++ b/logindetect.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +import sys +import requests +from argparse import ArgumentParser +from collections import defaultdict +from bs4 import BeautifulSoup + + +def form_score(form): + score = 0 + inputs = form.find_all("input") + typecount = defaultdict(int) + for input_tag in inputs: + type_ = input_tag.get("type", "").lower() + typecount[type_] += 1 + + if len(inputs) in (2, 3): + score += 10 + + if typecount['text'] > 1: + score += 10 + if not typecount['text']: + score -= 10 + + if typecount['password'] == 1: + score += 10 + if not typecount['password']: + score -= 10 + + if typecount['checkbox'] > 1: + score -= 10 + if typecount['radio']: + score -= 10 + + return score + + +def pick_form(forms): + """Return the form most likely to be a login form""" + return sorted(forms, key=form_score, reverse=True)[0] + + +def pick_fields(form): + """Return the most likely field names for username and password""" + user_field = pass_field = None + inputs = form.find_all("input") + for input_tag in inputs: + type_ = input_tag.get("type", "").lower() + if type_ == 'text' and not user_field: + user_field = input_tag.get("name") + elif type_ == 'password' and not pass_field: + pass_field = input_tag.get("name") + + return user_field, pass_field + + +def detect_login_forms(url): + try: + response = requests.get(url) + response.raise_for_status() + soup = BeautifulSoup(response.text, 'html.parser') + forms = soup.find_all('form') + login_forms = [] + + for form in forms: + user_field, pass_field = pick_fields(form) + if user_field and pass_field: + action_url = form.get('action') or response.url + method = form.get('method', 'get') + login_forms.append({ + 'action': action_url, + 'method': method, + 'username_field': user_field, + 'password_field': pass_field + }) + except requests.RequestException as e: + print(f"Error occurred while fetching URL: {e}") + return [] + + return login_forms + + +def main(): + ap = ArgumentParser() + ap.add_argument('url', help='URL to detect login forms') + args = ap.parse_args() + + login_forms = detect_login_forms(args.url) + if login_forms: + print("Login forms detected:") + for idx, form in enumerate(login_forms, start=1): + print(f"Form {idx}:") + print(f"Action URL: {form['action']}") + print(f"Method: {form['method']}") + print(f"Username Field: {form['username_field']}") + print(f"Password Field: {form['password_field']}") + print() + else: + print("No login forms detected on the provided URL.") + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/loginform.py b/loginform.py index bb3fa24..80c2cc8 100644 --- a/loginform.py +++ b/loginform.py @@ -57,7 +57,9 @@ def _pick_fields(form): elif type_ == 'text' and userfield is None: userfield = x.name - return emailfield or userfield, passfield + + return emailfield or userfield, passfield + def submit_value(form): diff --git a/loginsele.py b/loginsele.py new file mode 100644 index 0000000..97542ff --- /dev/null +++ b/loginsele.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +import sys +from time import sleep +from argparse import ArgumentParser +from collections import defaultdict +from lxml import html +import requests +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.firefox.options import Options + + +__version__ = '1.2.0' + + +def _form_score(form): + score = 0 + # In case of user/pass or user/pass/remember-me + if len(form.inputs.keys()) in (2, 3): + score += 10 + + typecount = defaultdict(int) + for x in form.inputs: + type_ = x.type if isinstance(x, html.InputElement) else "other" + typecount[type_] += 1 + + if typecount['text'] > 1: + score += 10 + if not typecount['text']: + score -= 10 + + if typecount['password'] == 1: + score += 10 + if not typecount['password']: + score -= 10 + + if typecount['checkbox'] > 1: + score -= 10 + if typecount['radio']: + score -= 10 + + return score + + +def _pick_form(forms): + """Return the form most likely to be a login form""" + return sorted(forms, key=_form_score, reverse=True)[0] + + +def _pick_fields(form): + """Return the most likely field names for username and password""" + userfield = passfield = emailfield = None + for x in form.inputs: + if not isinstance(x, html.InputElement): + continue + + type_ = x.type + if type_ == 'password' and passfield is None: + passfield = x.name + elif type_ == 'email' and emailfield is None: + emailfield = x.name + elif type_ == 'text' and userfield is None: + userfield = x.name + + return emailfield or userfield, passfield + + +def submit_value(form): + """Returns the value for the submit input, if any""" + for x in form.inputs: + if not isinstance(x, html.InputElement): + continue + + if x.type == "submit" and x.name: + return [(x.name, x.value)] + else: + return [] + + +def fill_login_form(url, body, username, password): + doc = html.document_fromstring(body, base_url=url) + form = _pick_form(doc.xpath('//form')) + userfield, passfield = _pick_fields(form) + form.fields[userfield] = username + form.fields[passfield] = password + form_values = form.form_values() + submit_value(form) + return form_values, form.action or form.base_url, form.method + + +def main(): + ap = ArgumentParser() + ap.add_argument('-u', '--username', default='username') + ap.add_argument('-p', '--password', default='secret') + ap.add_argument('url') + args = ap.parse_args() + + try: + r = requests.get(args.url) + values, action, method = fill_login_form(args.url, r.text, args.username, args.password) + print(u'url: {0}\nmethod: {1}\npayload:'.format(action, method)) + for k, v in values: + print(u'- {0}: {1}'.format(k, v)) + + # Selenium setup to open the logged-in page + options = Options() + options.headless = True # Set to False if you want to see the browser + driver = webdriver.Firefox(options=options) + driver.get(action) + # You can add further actions here, such as clicking on links or buttons + # Example: + # driver.find_element_by_xpath("//a[contains(text(),'Dashboard')]").click() + sleep(30) + driver.quit() # Close the browser after use + except ImportError: + print('requests library is required to use loginform as a tool') + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/newlogin.py b/newlogin.py new file mode 100644 index 0000000..b9ec9ea --- /dev/null +++ b/newlogin.py @@ -0,0 +1,27 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from time import sleep + +options = webdriver.ChromeOptions() +options.add_experimental_option("detach", True) +driver=webdriver.Chrome(options=options) + +username= "test" +password= "test." +url="https://www.stealmylogin.com/demo.html" + +driver.get(url) +sleep(2) +print('1') +username_field=driver.find_element(By.NAME, "username").send_keys(username) +sleep(2) +print('2') + +password_field=driver.find_element(By.NAME, "password").send_keys(password) +sleep(2) +print('3') + +login_button=driver.find_element(By.XPATH, '/html/body/form/input[3]') +login_button.click() +sleep(5) +print('4')