新手求助:如何用Python/Wget实现带Challenge-Response的UPS登录?
Hey there! Let's figure out how to fix that "Challenge not found" error you're hitting when trying to log into your UPS device. The issue here is that your current wget command skips a critical step in the login flow: this UPS uses a Challenge-Response authentication system instead of accepting plaintext passwords directly.
Why Your Current Command Fails
Looking at the login page source, you can see a hidden Challenge field and a JavaScript function calcResponse() that does this:
str = document.login.Username.value + document.login.Password.value + document.login.Challenge.value;
document.login.Response.value = hex_md5(str);
In short: you can't just send Username and Password directly. You first need to grab the unique Challenge value from the login page, compute an MD5 hash of Username + Password + Challenge, then send that hash as the Response field instead of the plain password.
Solution 1: Python (Recommended for Flexibility)
Using Python's requests library makes this straightforward, since it handles sessions and cookie management automatically.
First, install required packages if you haven't:
pip install requests beautifulsoup4 # BeautifulSoup for cleaner page parsing
Then use this script:
import requests import hashlib from bs4 import BeautifulSoup # Configuration UPS_BASE_URL = "https://192.168.50.2" LOGIN_PATH = "/delta/login" USERNAME = "admin" PASSWORD = "admin" # Initialize session to persist cookies across requests session = requests.Session() session.verify = False # Disable SSL verification for self-signed UPS certificate try: # Step 1: Fetch login page to get Challenge value and session cookie login_page = session.get(UPS_BASE_URL) login_page.raise_for_status() # Catch any HTTP errors # Parse Challenge from the page using BeautifulSoup soup = BeautifulSoup(login_page.text, "html.parser") challenge_input = soup.find("input", {"name": "Challenge"}) if not challenge_input: print("Couldn't find the Challenge field on the login page") exit(1) challenge = challenge_input["value"] # Step 2: Calculate Response hash response_string = f"{USERNAME}{PASSWORD}{challenge}" response_hash = hashlib.md5(response_string.encode("utf-8")).hexdigest() # Step 3: Submit login request login_data = { "Username": USERNAME, "Response": response_hash # Note: We don't send Password or Challenge (JS clears them before submit) } login_response = session.post(f"{UPS_BASE_URL}{LOGIN_PATH}", data=login_data) login_response.raise_for_status() # Verify login success if "Challenge not found" not in login_response.text: print("✅ Login successful!") # Now you can use the session to fetch protected pages example_page = session.get(f"{UPS_BASE_URL}/home.asp") print("\nPreview of home page:") print(example_page.text[:500]) # Print first 500 characters for verification else: print("❌ Login failed - check credentials or Challenge extraction") except requests.exceptions.RequestException as e: print(f"Request error: {e}")
Solution 2: Wget + Shell Script
If you prefer using wget, you'll need a shell script to handle the Challenge extraction and MD5 calculation first (since wget can't run JavaScript):
#!/bin/bash # Configuration UPS_BASE_URL="https://192.168.50.2" LOGIN_ENDPOINT="${UPS_BASE_URL}/delta/login" USERNAME="admin" PASSWORD="admin" COOKIE_FILE="ups_cookies.txt" # Step 1: Fetch login page to get Challenge and save cookies echo "Fetching Challenge value..." CHALLENGE=$(curl --insecure --cookie-jar "$COOKIE_FILE" "$UPS_BASE_URL" | grep -oP 'name="Challenge" value="\K[^"]+') if [ -z "$CHALLENGE" ]; then echo "Error: Failed to extract Challenge from login page" rm -f "$COOKIE_FILE" exit 1 fi # Step 2: Calculate MD5 Response hash echo "Calculating Response hash..." RESPONSE=$(echo -n "${USERNAME}${PASSWORD}${CHALLENGE}" | md5sum | awk '{print $1}') # Step 3: Submit login with wget echo "Attempting login..." wget --no-check-certificate --load-cookies "$COOKIE_FILE" --post-data "Username=${USERNAME}&Response=${RESPONSE}" "$LOGIN_ENDPOINT" # Optional: Fetch a protected page after login # wget --no-check-certificate --load-cookies "$COOKIE_FILE" "${UPS_BASE_URL}/home.asp" # Cleanup (optional) # rm -f "$COOKIE_FILE"
Save this as ups_login.sh, make it executable with chmod +x ups_login.sh, then run it.
Key Notes
- Dynamic Challenge: The Challenge value changes every time you load the login page, so you can't reuse an old one—always fetch a fresh value before each login attempt.
- SSL Certificates: Since most UPS devices use self-signed SSL certificates, we disable verification with
--no-check-certificate(wget) orsession.verify=False(Python). - Session Persistence: Using a session (Python) or cookie file (wget/curl) is crucial to maintain your authenticated state after login.
内容的提问来源于stack exchange,提问作者fdavidcn

