示例#1
0
    def walk(self, query=".1.3.6.1.2.1.2.2.1.2"):
        """
		Methode pour parcourir la MIB.
		"""
        if not query.startswith("."):
            query = "." + query
        snmp = self.version
        result = []
        monOid = asn1.OBJECTID()
        monOid.encode(query)

        req = v2c.GETNEXTREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [monOid.encode()]

        rsp = v2c.RESPONSE()
        current_oid = monOid

        while 1:

            try:
                (answer, src) = self.handle.send_and_receive(req.encode())
            except role.NoResponse, e:
                raise TimeOutException(e)
            except role.NetworkError, n:
                raise NetworkError(n)
示例#2
0
    def getValue(self, query):
        req = v2c.GETREQUEST()
        rsp = v2c.RESPONSE()
        req['encoded_oids'] = [asn1.OBJECTID().encode(query)]
        req['community'] = self.community
        (answer, src) = self.handle.send_and_receive(req.encode())
        rsp.decode(answer)
        if req != rsp:
            raise 'Unmatched response: %s vs %s' % (str(req), str(rsp))

        oids = map(lambda x: x[0],
                   map(asn1.OBJECTID().decode, rsp['encoded_oids']))
        vals = map(lambda x: x[0](), map(asn1.decode, rsp['encoded_vals']))

        if rsp['error_status']:
            raise 'SNMP error #' + str(rsp['error_status']) + ' for OID #' \
                  + str(rsp['error_index'])
        #for (oid, val) in map(None, oids, vals):
        #    print oid + ' ---> ' + str(val)
        return vals[0]
示例#3
0
    def get(self, query="1.3.6.1.2.1.1.1.0"):
        """
        Does snmpget query on the host.
        query: OID to use in the query

        returns the result as a string.
        """

        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        try:
            snmp = eval('v' + self.version)
        except (NameError, AttributeError):
            raise UnsupportedSnmpVersionError(self.version)

        objectid = asn1.OBJECTID()
        oid = objectid.encode(query)

        # Create SNMP GET request
        req = snmp.GETREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [oid]

        # Create SNMP response message framework
        rsp = snmp.RESPONSE()

        # Encode SNMP request message and try to send it to SNMP agent and
        # receive a response
        try:
            (answer, _src) = self.handle.send_and_receive(req.encode(),
                                                          dst=(self.host,
                                                               self.port))
        except role.NoResponse as err:
            raise TimeOutException(err)
        except role.NetworkError as err:
            raise NetworkError(err)

        # Decode raw response/answer
        rsp.decode(answer)

        # Check for errors in the response
        self._error_check(rsp)

        # Fetch the value from the response
        rsp_value = asn1.decode(rsp['encoded_vals'][0])[0]

        # Return the value as a proper Python type:
        return rsp_value()
示例#4
0
    def bulkwalk(self, query="1.3.6.1.2.1.1.1.0", strip_prefix=False):
        """
        Performs an SNMP walk on the host, using GETBULK requests.
        Will raise an UnsupportedSnmpVersionError if the current
        version is anything other than 2c.
        
          query: OID to use in the query

          strip_prefix: If True, strips the query OID prefix from the
                        response OIDs.

        returns an array containing key-value-pairs, where the
        returned OID is the key.
        """
        if str(self.version) != "2c":
            raise UnsupportedSnmpVersionError(
                "Cannot use BULKGET in SNMP version " + self.version)

        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        snmp = v2c

        result = []
        root_oid = asn1.OBJECTID()
        root_oid.encode(query)

        # Create SNMP GETNEXT request
        req = snmp.GETBULKREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [root_oid.encode()]
        req['max_repetitions'] = 256

        # Create a response message framework
        rsp = snmp.RESPONSE()

        current_oid = root_oid
        # Traverse agent MIB
        while 1:
            # Encode SNMP request message and try to send it to SNMP agent and
            # receive a response
            try:
                (answer, src) = self.handle.send_and_receive(req.encode(),
                                                             dst=(self.host,
                                                                  self.port))
            except role.NoResponse, e:
                raise TimeOutException(e)
            except role.NetworkError, n:
                raise NetworkError(n)
示例#5
0
    def walk(self, query="1.3.6.1.2.1.1.1.0"):
        """
        Does snmpwalk on the host.
        query: OID to use in the query

        returns an array containing key-value-pairs, where the
        returned OID is the key.
        """
        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        try:
            snmp = eval('v' + self.version)
        except (NameError, AttributeError):
            raise UnsupportedSnmpVersionError(self.version)

        result = []
        root_oid = asn1.OBJECTID()
        root_oid.encode(query)

        # Create SNMP GETNEXT request
        req = snmp.GETNEXTREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [root_oid.encode()]

        # Create a response message framework
        rsp = snmp.RESPONSE()

        current_oid = root_oid
        # Traverse agent MIB
        while 1:
            # Encode SNMP request message and try to send it to SNMP agent and
            # receive a response
            try:
                (answer, src) = self.handle.send_and_receive(req.encode(),
                                                             dst=(self.host,
                                                                  self.port))
            except role.NoResponse, e:
                raise TimeOutException(e)
            except role.NetworkError, n:
                raise NetworkError(n)
示例#6
0
    def get(self, query="1.3.6.1.2.1.1.1.0"):
        """
        Does snmpget query on the host.
        query: OID to use in the query

        returns the result as a string.
        """

        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        try:
            snmp = eval('v' + self.version)
        except (NameError, AttributeError):
            raise UnsupportedSnmpVersionError(self.version)

        objectid = asn1.OBJECTID()
        oid = objectid.encode(query)

        # Create SNMP GET request
        req = snmp.GETREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [oid]

        # Create SNMP response message framework
        rsp = snmp.RESPONSE()

        # Encode SNMP request message and try to send it to SNMP agent and
        # receive a response
        try:
            (answer, src) = self.handle.send_and_receive(req.encode(),
                                                         dst=(self.host,
                                                              self.port))
        except role.NoResponse, e:
            raise TimeOutException(e)
示例#7
0
    def bulkwalk(self, query="1.3.6.1.2.1.1.1.0", strip_prefix=False):
        """
        Performs an SNMP walk on the host, using GETBULK requests.
        Will raise an UnsupportedSnmpVersionError if the current
        version is anything other than 2c.

          query: OID to use in the query

          strip_prefix: If True, strips the query OID prefix from the
                        response OIDs.

        returns an array containing key-value-pairs, where the
        returned OID is the key.
        """
        if str(self.version) != "2c":
            raise UnsupportedSnmpVersionError(
                "Cannot use BULKGET in SNMP version " + self.version)

        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        snmp = v2c

        result = []
        root_oid = asn1.OBJECTID()
        root_oid.encode(query)

        # Create SNMP GETNEXT request
        req = snmp.GETBULKREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [root_oid.encode()]
        req['max_repetitions'] = 256

        # Create a response message framework
        rsp = snmp.RESPONSE()

        current_oid = root_oid
        # Traverse agent MIB
        while 1:
            # Encode SNMP request message and try to send it to SNMP agent and
            # receive a response
            try:
                (answer, _src) = self.handle.send_and_receive(req.encode(),
                                                              dst=(self.host,
                                                                   self.port))
            except role.NoResponse as err:
                raise TimeOutException(err)
            except role.NetworkError as err:
                raise NetworkError(err)

            # Decode raw response/answer
            rsp.decode(answer)

            # Check for errors in the response
            try:
                self._error_check(rsp)
            except EndOfMibViewError:
                # Since we are retrieving multiple values, this SNMP
                # exception must be handled in the loop below instead
                pass

            last_response_oid = None
            for encoded_oid, encoded_val in \
                    zip(rsp['encoded_oids'], rsp['encoded_vals']):
                rsp_oid = asn1.decode(encoded_oid)[0]
                rsp_value = asn1.decode(encoded_val)[0]

                # Check for reasons to stop walking
                if isinstance(rsp_value, asn1.endOfMibView):
                    # Nothing more to see here, move along
                    return result
                if not root_oid.isaprefix(rsp_oid()):
                    # If the current value came from outside the tree we
                    # are traversing, get the hell out of here, we're done
                    # walking the subtree.
                    return result
                elif rsp_oid == current_oid:
                    # If the GETNEXT response contains the same object
                    # ID as the request, something has gone wrong, and
                    # we didn't see it further up.  Just return
                    # whatever results we got.
                    return result
                else:
                    oid = rsp_oid()
                    if strip_prefix:
                        oid = oid[len(query) + 1:]
                    result.append((oid, rsp_value()))
                    last_response_oid = rsp_oid

            # Update request ID
            req['request_id'] += 1

            # Load the next request with the last OID received in the
            # last response
            req['encoded_oids'] = rsp['encoded_oids'][-1:]
            current_oid = last_response_oid
示例#8
0
    def walk(self, query="1.3.6.1.2.1.1.1.0"):
        """
        Does snmpwalk on the host.
        query: OID to use in the query

        returns an array containing key-value-pairs, where the
        returned OID is the key.
        """
        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        try:
            snmp = eval('v' + self.version)
        except (NameError, AttributeError):
            raise UnsupportedSnmpVersionError(self.version)

        result = []
        root_oid = asn1.OBJECTID()
        root_oid.encode(query)

        # Create SNMP GETNEXT request
        req = snmp.GETNEXTREQUEST()
        req['community'] = self.community
        req['encoded_oids'] = [root_oid.encode()]

        # Create a response message framework
        rsp = snmp.RESPONSE()

        current_oid = root_oid
        # Traverse agent MIB
        while 1:
            # Encode SNMP request message and try to send it to SNMP agent and
            # receive a response
            try:
                (answer, _src) = self.handle.send_and_receive(req.encode(),
                                                              dst=(self.host,
                                                                   self.port))
            except role.NoResponse as err:
                raise TimeOutException(err)
            except role.NetworkError as err:
                raise NetworkError(err)

            # Decode raw response/answer
            rsp.decode(answer)

            # Check for errors in the response
            try:
                self._error_check(rsp)
            except EndOfMibViewError:
                # We just fell off the face of the earth (or walked outside the
                # agent's MIB view).  Return whatever results we got.
                return result

            # Fetch the (first) Object ID and value pair from the response,
            # (there shouldn't be more than one pair)
            rsp_oid = asn1.decode(rsp['encoded_oids'][0])[0]
            rsp_value = asn1.decode(rsp['encoded_vals'][0])[0]

            # Check for reasons to stop walking
            if not root_oid.isaprefix(rsp_oid()):
                # If the current GETNEXT response came from outside the
                # tree we are traversing, get the hell out of here, we're
                # done walking the subtree.
                return result
            elif rsp_oid == current_oid:
                # If the GETNEXT response contains the same object ID as the
                # request, something has gone wrong, and we didn't see it
                # further up.  Just return whatever results we got.
                return result
            else:
                result.append((rsp_oid(), rsp_value()))

            # Update request ID
            req['request_id'] += 1

            # Load the next request with the OID received in the last response
            req['encoded_oids'] = rsp['encoded_oids']
            current_oid = rsp_oid
示例#9
0
    def set(self, query, type, value):
        """
        Does snmpset query on the host.
        query: oid to use in snmpset
        type: type of value to set. This may be
        i: INTEGER
        u: unsigned INTEGER
        t: TIMETICKS
        a: IPADDRESS
        o: OBJID
        s: OCTETSTRING
        U: COUNTER64 (version 2 and above)
        x: OCTETSTRING
        value: the value to set. Must ofcourse match type: i = 2, s = 'string'

        Heavily influenced by:
        http://pysnmp.sourceforge.net/examples/2.x/snmpset.html
        """

        if not query.startswith("."):
            query = "." + query

        # Choose protocol version specific module
        try:
            snmp = eval('v' + self.version)
        except (NameError, AttributeError):
            raise UnsupportedSnmpVersionError(self.version)

        # Translate type to fit asn1 library
        if type == 'i':
            type = 'INTEGER'
        if type == 'u':
            type = 'UNSIGNED32'
        if type == 't':
            type = 'TIMETICKS'
        if type == 'a':
            type = 'IPADDRESS'
        if type == 'o':
            type = 'OBJECTID'
        if type == 's':
            type = 'OCTETSTRING'
        if type == 'U':
            type = 'COUNTER64'
        if type == 'x':
            type = 'OCTETSTRING'

        # Make request and responsehandler
        req = snmp.SETREQUEST()
        req['community'] = self.community
        rsp = snmp.GETRESPONSE()

        # Encode oids and values
        encoded_oids = []
        encoded_vals = []

        encoded_oids.append(asn1.OBJECTID().encode(query))
        encoded_vals.append(eval('asn1.' + type + '()').encode(value))

        # Try to send query and get response
        try:
            (answer, _src) = self.handle.send_and_receive(
                req.encode(encoded_oids=encoded_oids,
                           encoded_vals=encoded_vals),
                dst=(self.host, self.port))

            # Decode response (an octet-string) into an snmp-message
            rsp.decode(answer)

            if rsp['error_status']:
                raise AgentError(str(snmp.SNMPError(rsp['error_status'])))

        except (role.NoResponse, role.NetworkError) as err:
            raise NetworkError(err)
示例#10
0
    def showOid(self, head_oids):
        # Create SNMP manager object
        client = role.manager((self.target, self.port))

        # Pass it a few options
        client.timeout = self.timeout
        client.retries = self.retries

        # Create a SNMP request&response objects from protocol version
        # specific module.
        try:
            req = v1.GETREQUEST()
            nextReq = v1.GETNEXTREQUEST()
            rsp = v1.GETRESPONSE()

        except (NameError, AttributeError):
            print sys.exc_info()[1]
            return False

        # Store tables headers
        #head_oids = ["1.3.6.1."]

        try:
            # BER encode initial SNMP Object IDs to query
            encoded_oids = map(asn1.OBJECTID().encode, head_oids)
        except:
            print "Error.", sys.exc_info()[1]
            return

        # Traverse agent MIB
        while 1:
            # Encode SNMP request message and try to send it to SNMP agent
            # and receive a response
            (answer, src) = client.send_and_receive(\
                            req.encode(community=self.community, encoded_oids=encoded_oids))

            # Attempt to decode SNMP response
            rsp.decode(answer)

            # Make sure response matches request (request IDs, communities, etc)
            if req != rsp:
                raise Exception('Unmatched response: %s vs %s' %
                                (str(req), str(rsp)))

            # Decode BER encoded Object IDs.
            oids = map(lambda x: x[0], map(asn1.OBJECTID().decode, \
                                           rsp['encoded_oids']))

            # Decode BER encoded values associated with Object IDs.
            vals = map(lambda x: x[0](), map(asn1.decode, rsp['encoded_vals']))

            # Check for remote SNMP agent failure
            if rsp['error_status']:
                # SNMP agent reports 'no such name' when walk is over
                if rsp['error_status'] == 2:
                    # Switch over to GETNEXT req on error
                    # XXX what if one of multiple vars fails?
                    if not (req is nextReq):
                        req = nextReq
                        continue
                    # One of the tables exceeded
                    for l in oids, vals, head_oids:
                        del l[rsp['error_index'] - 1]
                else:
                    raise Exception('SNMP error #' + str(rsp['error_status']) + ' for OID #' \
                          + str(rsp['error_index']))

            # Exclude completed OIDs
            while 1:
                for idx in range(len(head_oids)):
                    if not asn1.OBJECTID(head_oids[idx]).isaprefix(oids[idx]):
                        # One of the tables exceeded
                        for l in oids, vals, head_oids:
                            del l[idx]
                        break
                else:
                    break

            if not head_oids:
                return False

            # Print out results
            for (oid, val) in map(None, oids, vals):
                if str(val) != "":
                    print oidToHuman(oid) + ' = ' + str(val)

            # BER encode next SNMP Object IDs to query
            encoded_oids = map(asn1.OBJECTID().encode, oids)

            # Update request object
            req['request_id'] = req['request_id'] + 1

            # Switch over GETNEXT PDU for if not done
            if not (req is nextReq):
                req = nextReq

        return True
示例#11
0
    def snmpenum(self, h_oids, title):
        try:
            from pysnmp import asn1, v1, v2c
            from pysnmp import role
        except:
            self.log("Error: you need pysnmp to use this exploit")
            return 1

        client = role.manager((self.host, 161))
        client.timeout = 1
        client.retries = 5
        t = 0

        req = eval('v' + self.snmpver).GETREQUEST()
        nextReq = eval('v' + self.snmpver).GETNEXTREQUEST()
        rsp = eval('v' + self.snmpver).GETRESPONSE()

        encoded_oids = map(asn1.OBJECTID().encode, h_oids)

        while 1:
            try:
                (answer, src) = client.send_and_receive(
                    req.encode(community=self.community,
                               encoded_oids=encoded_oids))
            except:
                self.log("%s : bad community ?" % self.community)
                return 1

            rsp.decode(answer)

            if req != rsp:
                raise 'Unmatched response: %s vs %s' % (str(req), str(rsp))

            oids = map(lambda x: x[0],
                       map(asn1.OBJECTID().decode, rsp['encoded_oids']))

            vals = map(lambda x: x[0](), map(asn1.decode, rsp['encoded_vals']))

            if rsp['error_status']:
                if rsp['error_status'] == 2:
                    if not (req is nextReq):
                        req = nextReq
                        continue
                    for l in oids, vals, h_oids:
                        del l[rsp['error_index'] - 1]
                else:
                    raise 'SNMP error #' + str(
                        rsp['error_status']) + ' for OID #' + str(
                            rsp['error_index'])

            while 1:
                for idx in range(len(h_oids)):
                    if not asn1.OBJECTID(h_oids[idx]).isaprefix(oids[idx]):
                        for l in oids, vals, h_oids:
                            del l[idx]
                        break
                else:
                    break

            if not h_oids:
                return 0

            if not t:
                self.log("[#] %s" % title)
                t += 1

            for (oid, val) in map(None, oids, vals):
                self.log(str(val))

            encoded_oids = map(asn1.OBJECTID().encode, oids)

            req['request_id'] = req['request_id'] + 1

            if not (req is nextReq):
                req = nextReq
        return 0
示例#12
0
            return ip
        return r[0]
    except:
        return ip


# Listen for SNMP messages from remote SNMP managers
while 1:
    # Receive a request message
    (question, src) = server.receive()

    # Decode request of any version
    (req, rest) = v2c.decode(question)

    # Decode BER encoded Object IDs.
    oids = map(lambda x: x[0], map(asn1.OBJECTID().decode, \
                                   req['encoded_oids']))

    # Decode BER encoded values associated with Object IDs.
    vals = map(lambda x: x[0](), map(asn1.decode, req['encoded_vals']))

    # Print it out
    print 'SNMP message from: ' + str(src)
    print 'Version: ' + str(req['version'] + 1) + ', type: ' + str(req['tag'])
    if req['version'] == 0:
        print 'Enterprise OID: ' + str(req['enterprise'])
        print 'Trap agent: ' + str(req['agent_addr'])
        for t in v1.GENERIC_TRAP_TYPES.keys():
            if req['generic_trap'] == v1.GENERIC_TRAP_TYPES[t]:
                print 'Generic trap: %s (%d)' % (t, req['generic_trap'])
                break
示例#13
0
    def listen(self, community, callback):
        """Listens for and dispatches incoming traps to callback."""
        # Listen for SNMP messages from remote SNMP managers
        while 1:
            # Receive a request message
            try:
                (question, src) = self._agent.receive()
            except select.error as why:
                # resume loop if a signal interrupted the receive operation
                if why.args[0] == 4:  # error 4 = system call interrupted
                    continue
                else:
                    raise why
            if question is None:
                continue

            logger.debug("Packet content: %r", question)
            try:
                # Decode request of any version
                (req, rest) = v2c.decode(question)

                # Decode BER encoded Object IDs.
                oids = map(lambda x: x[0],
                           map(asn1.OBJECTID().decode, req['encoded_oids']))

                # Decode BER encoded values associated with Object IDs.
                vals = map(lambda x: x[0](),
                           map(asn1.decode, req['encoded_vals']))

            except Exception as why:
                # We must not die because of any malformed packets; log
                # and ignore any exception
                logger.exception(
                    "Exception while decoding snmp trap packet "
                    "from %r, ignoring trap", src)
                continue

            agent = None
            type = None
            genericType = None

            varbinds = {}
            # Prepare variables for making of SNMPTrap-object
            if req['version'] == 0:
                agent = str(req['agent_addr'])
                type = str(req['tag'])
                uptime = str(req['time_stamp'])
                # Create snmpoid based on RFC2576
                snmpTrapOID, genericType = transform(req)
            else:
                uptime = vals.pop(0)
                oids.pop(0)
                snmpTrapOID = vals.pop(0)
                oids.pop(0)

            # Add varbinds to array
            for (oid, val) in map(None, oids, vals):
                varbinds[oid] = str(val)

            community = req['community']
            version = str(req['version'] + 1)
            src = src[0]

            # Create trap object, let callback decide what to do with it.
            trap = SNMPTrap(str(src), agent or str(src), type, genericType,
                            snmpTrapOID, uptime, community, version, varbinds)
            callback(trap)

        # Exit nicely
        sys.exit(0)