Vulnerability Development mailing list archives

Re: Quick SNMP Payload Structure Question


From: BORBELY Zoltan <bozo () andrews hu>
Date: Thu, 28 Feb 2002 12:28:10 +0100

Hello,

On Wed, Feb 27, 2002 at 07:51:44PM -0800, rpc wrote:
Here is what I've discovered about SNMP packets so far.
For example, a request header might look like this:
"\x30\x82\x01\x23\x02\x01\x00\x04\x82\x01\x00"community"morestuffmorestuffmorestuff

Where 'morestuff' is the actual encoded snmp request and, in this case, community is 256 bytes long.
A description of the header byte for byte:

0x30: ASN_SEQUENCE | ASN_CONSTRUCTOR
0x82: ASN_LONG_LEN  | 2 (2 bytes of data i think)
0x01,0x23 = 0x123 = packet size

No, this is not the packet size. This is the size of the SEQUENCE payload. The
packet size in this case is: 1 (0x30) + 3 (0x82, 0x01, 0x23) + 0x123.

[...]
Note that ASN_LONG_LEN is only necessary if the community string is > 0xff
bytes. If it's not, the sequence is "\x04",lenbyte,community. If this is
the case, note the header will be 2 bytes shorter.

No, this format is required if the community string is larger or equal to
128 bytes.

asn1.c, asn1.h, snmp_api.c and snmp_auth.c from snmplib are invaluable for
hacking with ASN data.

You can download good docs from the net. Here's a very useful link:

    http://www.oss.com/asn1

Read some documentation about ASN.1 and BER encoding. Here's a quick start:

The BER encoding is a TLV (type, length, value) encoding, but it isn't so
simple. There are two encoding form:

* definitive form: <identifier octets> <length octets> <content octets>
* indefinite form: <identifier octets> <0x80> <content octets> <end of content octets>

I haven't read the SNMP RFCs, but RFC frequently requires the definitive form.

Format of the identifier octet(s):

The structure of the first byte is the following: class (2 bits), primitive /
constructed flag (1 bit), tag number (5 bit). Class specifies the meaning of
the tag value: 0 0 - universal, 0 1 - application specific, 1 0 - context
specific, 1 1 - private. The primitive/constructed flag specifies it's a
primitive type (e.g. INTEGER, OCTET STRING) or constructed (e.g. SEQUENCE).
If the tag number below 31 the identifier octets only 1 byte long, otherwise
another identifier bytes follows (IMHO this format isn't used in the SNMP
protocol).

The length octets are placed after the identifier octets. The format is the
following:

0x00 - 0x7f: length of the content octets (definitive form)
0x80: indefinitie form
0x81 - 0xff: the real length stored in the following n bytes (definitive form)

        length          encoding
        0x00            0x00
        0x01            0x01
        0x7f            0x7f
        0x80            0x81 0x80
        0x123           0x82 0x01 0x23
        0xffffffff      0x84 0xff 0xff 0xff 0xff

Content octets specifies the data according class/tag.

Look into the first example again: <0x30><0x82 0x01 0x23>

0x30: universal class, constructed, tag 16 (sequence)
0x82: length of the contents stored in the following two bytes
0x01 0x23: length of the contents octets is 0x123 bytes long.

Bye,
Bozo


Current thread: