Created
August 26, 2025 08:39
-
-
Save ankurpandeyvns/2c13f45310003a513e1b839b529535c1 to your computer and use it in GitHub Desktop.
Enable Root Access in Jio Router
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
| import requests | |
| from bs4 import BeautifulSoup | |
| import urllib3 | |
| import sys | |
| import json | |
| import os | |
| # --- Configuration --- | |
| BASE_URL = "http://192.168.0.51" | |
| USERNAME = "superadmin" | |
| PASSWORD = "87jMB=DU" | |
| # IMPORTANT: Provide the full path to the file you want to upload | |
| RESTORE_FILE_PATH = "file.enc" | |
| # Common headers to mimic a browser, used for all requests | |
| COMMON_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.7', | |
| 'Accept-Language': 'en-IN,en-US;q=0.9,en;q=0.8', | |
| 'Cache-Control': 'no-cache', | |
| 'Connection': 'keep-alive', | |
| 'DNT': '1', | |
| 'Origin': BASE_URL, | |
| 'Pragma': 'no-cache', | |
| 'Upgrade-Insecure-Requests': '1', | |
| 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0', | |
| } | |
| # Suppress only the InsecureRequestWarning from urllib3 | |
| urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | |
| # Create a session object to persist cookies across requests | |
| session = requests.Session() | |
| session.verify = False | |
| def handle_forced_login(response): | |
| """ | |
| Checks if the login response is the 'forced login' page and handles it. | |
| This function mimics the JavaScript logic on the page. | |
| """ | |
| print("Detected active session. Attempting to continue...") | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| token_input = soup.find('form', {'name': 'tf1_forcedLoginForm'}).find('input', {'name': 'token'}) | |
| if not token_input: | |
| print("❌ Could not find the token for forced login.") | |
| return False | |
| forced_login_token = token_input['value'] | |
| print(f"✅ Forced login token scraped: {forced_login_token[:20]}...") | |
| continue_url = f"{BASE_URL}/platform.cgi" | |
| continue_headers = { | |
| **COMMON_HEADERS, | |
| 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | |
| 'Referer': f'{BASE_URL}/platform.cgi', | |
| 'X-Requested-With': 'XMLHttpRequest', | |
| } | |
| continue_payload = { | |
| 'button.continue.index': 'Continue', | |
| 'thispage': 'index.html', | |
| 'tf1_hTmp1': '1', | |
| 'tf1_hTmp2': '1', | |
| 'loginSession.username': USERNAME, | |
| 'token': forced_login_token | |
| } | |
| try: | |
| continue_response = session.post(continue_url, headers=continue_headers, data=continue_payload) | |
| continue_response.raise_for_status() | |
| if "DASHBOARD" in continue_response.text.upper(): | |
| print("✅ Forced login successfully bypassed. Session is now active.") | |
| return True | |
| else: | |
| print("❌ Bypassing forced login failed. Unexpected response.") | |
| return False | |
| except requests.exceptions.RequestException as e: | |
| print(f"An error occurred while continuing the session: {e}") | |
| return False | |
| def login(): | |
| """Performs the initial login and handles any forced login redirection.""" | |
| login_url = f"{BASE_URL}/platform.cgi" | |
| login_headers = { | |
| **COMMON_HEADERS, | |
| 'Content-Type': 'application/x-www-form-urlencoded', | |
| 'Referer': f'{BASE_URL}/platform.cgi?page=index.html', | |
| } | |
| login_payload = { | |
| 'thispage': 'index.html', | |
| 'users.username': USERNAME, | |
| 'users.password': PASSWORD, | |
| 'button.login.users.dashboard': 'Login' | |
| } | |
| try: | |
| print("1. Attempting to log in...") | |
| response = session.post(login_url, headers=login_headers, data=login_payload) | |
| response.raise_for_status() | |
| if '<div class="forcedLogin"' in response.text: | |
| return handle_forced_login(response) | |
| elif "logout" in response.text.lower(): | |
| print("✅ Login successful! Session cookie obtained.") | |
| return True | |
| else: | |
| print("❌ Login failed. The response was not the expected dashboard page.") | |
| return False | |
| except requests.exceptions.RequestException as e: | |
| print(f"An error occurred during login: {e}") | |
| return False | |
| def get_restore_token(): | |
| """Navigates to the factory default page and scrapes the hidden token.""" | |
| token_page_url = f"{BASE_URL}/platform.cgi?page=factoryDefault.html" | |
| try: | |
| print("\n2. Navigating to factory reset page to get the token...") | |
| get_headers = { | |
| **COMMON_HEADERS, | |
| 'Referer': f'{BASE_URL}/platform.cgi?page=dashboard.html', | |
| } | |
| response = session.get(token_page_url, headers=get_headers) | |
| response.raise_for_status() | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| token_input = soup.find('input', {'name': 'token'}) | |
| if token_input and token_input.get('value'): | |
| token = token_input['value'] | |
| print(f"✅ Token successfully scraped: {token[:20]}...") | |
| return token | |
| else: | |
| print("❌ Could not find the token on the page.") | |
| return None | |
| except requests.exceptions.RequestException as e: | |
| print(f"An error occurred while getting the token: {e}") | |
| return None | |
| def perform_restore(token): | |
| """Submits the final restore form with the scraped token and the file content.""" | |
| restore_url = f"{BASE_URL}/platform.cgi" | |
| if not os.path.exists(RESTORE_FILE_PATH): | |
| print(f"❌ Error: The file at '{RESTORE_FILE_PATH}' does not exist.") | |
| return | |
| # Use a 'with' statement to ensure the file is closed automatically | |
| with open(RESTORE_FILE_PATH, 'rb') as f: | |
| print(f"\n3. Reading file '{os.path.basename(RESTORE_FILE_PATH)}' from disk...") | |
| restore_headers = { | |
| **COMMON_HEADERS, | |
| # The Content-Type header with the boundary is handled automatically by requests. | |
| 'Referer': f'{BASE_URL}/platform.cgi?page=factoryDefault.html', | |
| } | |
| # Provide the file object to the files dictionary | |
| restore_payload = { | |
| 'token': (None, token), | |
| 'thispage': (None, 'factoryDefault.html'), | |
| 'file.restore': (os.path.basename(RESTORE_FILE_PATH), f, 'application/octet-stream'), | |
| 'button.restore.statusPage': (None, 'Restore'), | |
| } | |
| try: | |
| print("Submitting restore form with file...") | |
| response = session.post(restore_url, headers=restore_headers, files=restore_payload) | |
| response.raise_for_status() | |
| print("✅ Restore form submitted successfully!") | |
| print(f"Final Status Code: {response.status_code}") | |
| except requests.exceptions.RequestException as e: | |
| print(f"❌ An error occurred during restore: {e}") | |
| if __name__ == "__main__": | |
| if login(): | |
| restore_token = get_restore_token() | |
| if restore_token: | |
| perform_restore(restore_token) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment