[Snort-devel] Parsing curiosity between standard byte_test and DCE byte_test

Joshua Kinard kumba at ...2185...
Mon May 20 15:20:35 EDT 2013


Snort-devel,

Looking at the parsing code for the normal byte_test keyword and the DCERPC2
overridden one, there appears to be an undocumented issue with the operator
field.

Here's the switch statement that parses the operator for the standard byte_test:
        /* set the operator */
        switch(*cptr)
        {
            case '<': idx->operator = BT_LESS_THAN;
                      cptr++;
                      if (*cptr == '=')
                          idx->operator = BT_LESS_THAN_EQUAL;
                      else
                          cptr--;
                      break;

            case '=': idx->operator = BT_EQUALS;
                      break;

            case '>': idx->operator = BT_GREATER_THAN;
                      cptr++;
                      if (*cptr == '=')
                          idx->operator = BT_GREATER_THAN_EQUAL;
                      else
                          cptr--;
                      break;

            case '&': idx->operator = BT_AND;
                      break;

            case '^': idx->operator = BT_XOR;
                      break;

            default: FatalError("%s(%d): byte_test unknown "
                             "operator ('%c, %s')\n", file_name, file_line,
                             *cptr, toks[1]);
        }

As can be seen, when it hits either the '<' or '>' operators, it advances
the pointer by one to check if the next character is an '=' and sets
BT_LESS_THAN_EQUAL or BT_GREATER_THAN_EQUAL as appropriate.



Here's the parsing code for the DCERPC2-overridden byte_test:
            /* If two bytes first must be '!' */
            if (strlen(token) == 2)
            {
                if (*token != DCE2_RARG__NE)
                {
                    DCE2_Free((void *)bt_data, sizeof(DCE2_ByteTestData),
DCE2_MEM_TYPE__ROPTION);
                    DCE2_RoptError("\"%s\" rule option: Invalid argument: %s",
                            DCE2_ROPT__BYTE_TEST, token);
                }
                else
                {
                    bt_data->invert = 1;
                }

                token++;
            }

            switch (*token)
            {
                case DCE2_RARG__LT:
                    bt_data->operator = DCE2_BT_OP__LT;
                    break;
                case DCE2_RARG__EQ:
                    bt_data->operator = DCE2_BT_OP__EQ;
                    break;
                case DCE2_RARG__GT:
                    bt_data->operator = DCE2_BT_OP__GT;
                    break;
                case DCE2_RARG__AND:
                    bt_data->operator = DCE2_BT_OP__AND;
                    break;
                case DCE2_RARG__XOR:
                    bt_data->operator = DCE2_BT_OP__XOR;
                    break;
                default:
                    DCE2_Free((void *)bt_data, sizeof(DCE2_ByteTestData),
DCE2_MEM_TYPE__ROPTION);
                    DCE2_RoptError("\"%s\" rule option: Invalid argument: %s",
                            DCE2_ROPT__BYTE_TEST, token);
                    break;
            }

We can see at the top that it first checks the string length of the token,
and states that if it is two characters, the first char must be '!' for
negation.  It then goes on to check the actual operators, but it only
accounts for '<', '=', '>', '&', and '^'.  It does NOT account for '<=' or
'>=' like the standard byte_test does.

However if you write out a rule with a keyword like this:
byte_test:2,!<=,42,0,dce;, it will not throw out a parsing error.

The documentation doesn't actually mention that the standard byte_test
accepts '<=' and '>=' as operators, so no one has probably ever stumbled
onto this corner case.


What's the dev team's take?  Should both byte_test forms support '<=' and
'>=' or should neither?  Either approach is an easy fix.

Also, minor note, but the manual states that byte_extract takes a 'dce'
operand, when the parsing code doesn't even check for it.  Traces exist for
it to be added eventually (I assume), but the DCERPC2 preprocessor has no
code in place to override byte_extract.

Cheers!,

-- 
Joshua Kinard
Gentoo/MIPS
kumba at ...2185...
4096R/D25D95E3 2011-03-28

"The past tempts us, the present confuses us, the future frightens us.  And
our lives slip away, moment by moment, lost in that vast, terrible in-between."

--Emperor Turhan, Centauri Republic

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: OpenPGP digital signature
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20130520/84aa71a2/attachment.sig>


More information about the Snort-devel mailing list