next up previous contents
Next: Sensitive Data Preprocessor Up: DCE/RPC 2 Preprocessor Previous: Events   Contents

Rule Options

New rule options are supported by enabling the dcerpc2 preprocessor:

    dce_iface
    dce_opnum
    dce_stub_data

New modifiers to existing byte_test and byte_jump rule options:

    byte_test:dce
    byte_jump:dce

dce_iface

For DCE/RPC based rules it has been necessary to set flow-bits based on a client bind to a service to avoid false positives. It is necessary for a client to bind to a service before being able to make a call to it. When a client sends a bind request to the server, it can, however, specify one or more service interfaces to bind to. Each interface is represented by a UUID. Each interface UUID is paired with a unique index (or context id) that future requests can use to reference the service that the client is making a call to. The server will respond with the interface UUIDs it accepts as valid and will allow the client to make requests to those services. When a client makes a request, it will specify the context id so the server knows what service the client is making a request to. Instead of using flow-bits, a rule can simply ask the preprocessor, using this rule option, whether or not the client has bound to a specific interface UUID and whether or not this client request is making a request to it. This can eliminate false positives where more than one service is bound to successfully since the preprocessor can correlate the bind UUID to the context id used in the request. A DCE/RPC request can specify whether numbers are represented as big endian or little endian. The representation of the interface UUID is different depending on the endianness specified in the DCE/RPC previously requiring two rules - one for big endian and one for little endian. The preprocessor eliminates the need for two rules by normalizing the UUID. An interface contains a version. Some versions of an interface may not be vulnerable to a certain exploit. Also, a DCE/RPC request can be broken up into 1 or more fragments. Flags (and a field in the connectionless header) are set in the DCE/RPC header to indicate whether the fragment is the first, a middle or the last fragment. Many checks for data in the DCE/RPC request are only relevant if the DCE/RPC request is a first fragment (or full request), since subsequent fragments will contain data deeper into the DCE/RPC request. A rule which is looking for data, say 5 bytes into the request (maybe it's a length field), will be looking at the wrong data on a fragment other than the first, since the beginning of subsequent fragments are already offset some length from the beginning of the request. This can be a source of false positives in fragmented DCE/RPC traffic. By default it is reasonable to only evaluate if the request is a first fragment (or full request). However, if the any_frag option is used to specify evaluating on all fragments.

Syntax

    dce_iface:<uuid>[, <operator><version>][, any_frag];

    uuid       = hexlong '-' hexshort '-' hexshort '-' 2hexbyte '-' 6hexbyte
    hexlong    = 4hexbyte
    hexshort   = 2hexbyte
    hexbyte    = 2HEXDIGIT
    operator   = '<' | '>' | '=' | '!'
    version    = 0-65535
Examples
    dce_iface:4b324fc8-1670-01d3-1278-5a47bf6ee188;
    dce_iface:4b324fc8-1670-01d3-1278-5a47bf6ee188, <2;
    dce_iface:4b324fc8-1670-01d3-1278-5a47bf6ee188, any_frag;
    dce_iface:4b324fc8-1670-01d3-1278-5a47bf6ee188, =1, any_frag;

This option is used to specify an interface UUID. Optional arguments are an interface version and operator to specify that the version be less than ('<'), greater than ('>'), equal to ('=') or not equal to ('!') the version specified. Also, by default the rule will only be evaluated for a first fragment (or full request, i.e. not a fragment) since most rules are written to start at the beginning of a request. The any_frag argument says to evaluate for middle and last fragments as well. This option requires tracking client Bind and Alter Context requests as well as server Bind Ack and Alter Context responses for connection-oriented DCE/RPC in the preprocessor. For each Bind and Alter Context request, the client specifies a list of interface UUIDs along with a handle (or context id) for each interface UUID that will be used during the DCE/RPC session to reference the interface. The server response indicates which interfaces it will allow the client to make requests to - it either accepts or rejects the client's wish to bind to a certain interface. This tracking is required so that when a request is processed, the context id used in the request can be correlated with the interface UUID it is a handle for.

hexlong and hexshort will be specified and interpreted to be in big endian order (this is usually the default way an interface UUID will be seen and represented). As an example, the following Messenger interface UUID as taken off the wire from a little endian Bind request:

    |f8 91 7b 5a 00 ff d0 11 a9 b2 00 c0 4f b6 e6 fc|

must be written as:

    5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc

The same UUID taken off the wire from a big endian Bind request:

    |5a 7b 91 f8 ff 00 11 d0 a9 b2 00 c0 4f b6 e6 fc|

must be written the same way:

    5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc

This option matches if the specified interface UUID matches the interface UUID (as referred to by the context id) of the DCE/RPC request and if supplied, the version operation is true. This option will not match if the fragment is not a first fragment (or full request) unless the any_frag option is supplied in which case only the interface UUID and version need match. Note that a defragmented DCE/RPC request will be considered a full request.

Note:   Using this rule option will automatically insert fast pattern contents into the fast pattern matcher. For UDP rules, the interface UUID, in both big and little endian format will be inserted into the fast pattern matcher. For TCP rules, (1) if the rule option flow:to_server|from_client is used, $\vert$05 00 00$\vert$ will be inserted into the fast pattern matcher, (2) if the rule option flow:from_server|to_client is used, $\vert$05 00 02$\vert$ will be inserted into the fast pattern matcher and (3) if the flow isn't known, $\vert$05 00$\vert$ will be inserted into the fast pattern matcher. Note that if the rule already has content rule options in it, the best (meaning longest) pattern will be used. If a content in the rule uses the fast_pattern rule option, it will unequivocally be used over the above mentioned patterns.

dce_opnum

The opnum represents a specific function call to an interface. After is has been determined that a client has bound to a specific interface and is making a request to it (see above - dce_iface) usually we want to know what function call it is making to that service. It is likely that an exploit lies in the particular DCE/RPC function call.

Syntax

    dce_opnum:<opnum-list>;

    opnum-list   = opnum-item | opnum-item ',' opnum-list
    opnum-item   = opnum | opnum-range
    opnum-range  = opnum '-' opnum
    opnum        = 0-65535
Examples
    dce_opnum:15;
    dce_opnum:15-18;
    dce_opnum:15, 18-20;
    dce_opnum:15, 17, 20-22;

This option is used to specify an opnum (or operation number), opnum range or list containing either or both opnum and/or opnum-range. The opnum of a DCE/RPC request will be matched against the opnums specified with this option. This option matches if any one of the opnums specified match the opnum of the DCE/RPC request.

dce_stub_data

Since most netbios rules were doing protocol decoding only to get to the DCE/RPC stub data, i.e. the remote procedure call or function call data, this option will alleviate this need and place the cursor at the beginning of the DCE/RPC stub data. This reduces the number of rule option checks and the complexity of the rule.

This option takes no arguments.

Example

    dce_stub_data;

This option is used to place the cursor (used to walk the packet payload in rules processing) at the beginning of the DCE/RPC stub data, regardless of preceding rule options. There are no arguments to this option. This option matches if there is DCE/RPC stub data.

byte_test and byte_jump with dce
A DCE/RPC request can specify whether numbers are represented in big or little endian. These rule options will take as a new argument dce and will work basically the same as the normal byte_test/byte_jump, but since the DCE/RPC preprocessor will know the endianness of the request, it will be able to do the correct conversion.

byte_test

Syntax
    byte_test:<convert>, [!]<operator>, <value>, <offset> [, relative], dce;

    convert    = 1 | 2 | 4 (only with option "dce")
    operator   = '<' | '=' | '>' | '&' | '^'
    value      = 0 - 4294967295
    offset     = -65535 to 65535

Examples

    byte_test:4, >, 35000, 0, relative, dce;
    byte_test:2, !=, 2280, -10, relative, dce;

When using the dce argument to a byte_test, the following normal byte_test arguments will not be allowed: big, little, string, hex, dec and oct.

byte_jump

Syntax
    byte_jump:<convert>, <offset>[, relative][, multiplier <mult_value>] \
        [, align][, post_offet <adjustment_value>], dce;

    convert           = 1 | 2 | 4 (only with option "dce")
    offset            = -65535 to 65535
    mult_value        = 0 - 65535
    adjustment_value  = -65535 to 65535

Example

    byte_jump:4,-4,relative,align,multiplier 2,post_offset -4,dce;

When using the dce argument to a byte_jump, the following normal byte_jump arguments will not be allowed: big, little, string, hex, dec, oct and from_beginning.

Example of rule complexity reduction

The following two rules using the new rule options replace 64 (set and isset flowbit) rules that are necessary if the new rule options are not used:

    alert tcp $EXTERNAL_NET any -> $HOME_NET [135,139,445,593,1024:] \
        (msg:"dns R_Dnssrv funcs2 overflow attempt"; flow:established,to_server; \
        dce_iface:50abc2a4-574d-40b3-9d66-ee4fd5fba076; dce_opnum:0-11; dce_stub_data; \
        pcre:"/^.{12}(\x00\x00\x00\x00|.{12})/sR"; byte_jump:4,-4,relative,align,dce; \
        byte_test:4,>,256,4,relative,dce; reference:bugtraq,23470; reference:cve,2007-1748; \
        classtype:attempted-admin; sid:1000068;)

    alert udp $EXTERNAL_NET any -> $HOME_NET [135,1024:] \
        (msg:"dns R_Dnssrv funcs2 overflow attempt"; flow:established,to_server; \
        dce_iface:50abc2a4-574d-40b3-9d66-ee4fd5fba076; dce_opnum:0-11; dce_stub_data; \
        pcre:"/^.{12}(\x00\x00\x00\x00|.{12})/sR"; byte_jump:4,-4,relative,align,dce; \
        byte_test:4,>,256,4,relative,dce; reference:bugtraq,23470; reference:cve,2007-1748; \
        classtype:attempted-admin; sid:1000069;)


next up previous contents
Next: Sensitive Data Preprocessor Up: DCE/RPC 2 Preprocessor Previous: Events   Contents
Eugene Misnik 2013-05-08