/* detection functions */ int rule15149eval(void *p) { const uint8_t *cursor_normal = 0, *end_of_payload; SFSnortPacket *sp = (SFSnortPacket *) p; int retval; BER_ELEMENT element; if(sp == NULL) return RULE_NOMATCH; if(sp->payload == NULL) return RULE_NOMATCH; // flow:established, to_server; if (checkFlow(p, rule15149options[0]->option_u.flowFlags) <= 0 ) { return RULE_NOMATCH; } if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &cursor_normal, &end_of_payload) <= 0) return RULE_NOMATCH; // Universal Sequence if(ber_point_to_data(sp, &cursor_normal, 0x30) < 0) return RULE_NOMATCH; // message ID if(ber_skip_element(sp, &cursor_normal, 0x02) < 0) return RULE_NOMATCH; // find the bind request if(ber_point_to_data(sp, &cursor_normal, 0x60) < 0) return RULE_NOMATCH; /* bind requests are defined as: int version LDAPDN name auth authenticationChoice bug here is if the version element is specified as a cursor (0x30) vs. an int (0x02) */ retval = ber_get_element(sp, cursor_normal, &element); if(retval == -1) return RULE_NOMATCH; if(element.type == 0x30) return RULE_MATCH; return RULE_NOMATCH; }
/* detection functions */ int rule14646eval(void *p) { const uint8_t *cursor_normal = 0, *end_of_payload; SFSnortPacket *sp = (SFSnortPacket *) p; int retval; BER_ELEMENT element; if(sp == NULL) return RULE_NOMATCH; if(sp->payload == NULL) return RULE_NOMATCH; // flow:established, to_server; if(checkFlow(p, rule14646options[0]->option_u.flowFlags) <= 0 ) return RULE_NOMATCH; if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &cursor_normal, &end_of_payload) <= 0) return RULE_NOMATCH; // Universal Sequence if(ber_point_to_data(sp, &cursor_normal, 0x30) < 0) return RULE_NOMATCH; // message ID if(ber_skip_element(sp, &cursor_normal, 0x02) < 0) return RULE_NOMATCH; // search request if(ber_point_to_data(sp, &cursor_normal, 0x63) < 0) return RULE_NOMATCH; // Here's the meat retval = ber_get_element(sp, cursor_normal, &element); if(retval == -1) return RULE_NOMATCH; //DEBUG_WRAP(printf("found baseObject string. checking values type=0x%02x size=%d\n", element.type, element.data_len)); /* vuln is 0x43 + len(baseObject first part) + 3 * len(baseObject dc) > 0xFFA We simplify to data_len > 1200 since that's more than reasonable and shortest possible length to exploit is len(baseObject) == len(d) == 1363 */ if(element.type == 0x04 && ((element.data_len > 1200) || (retval == -2))) return RULE_MATCH; return RULE_NOMATCH; }
/* detection functions */ int rule16375eval(void *p) { const u_int8_t *cursor_normal = 0, *beg_of_payload, *end_of_payload; SFSnortPacket *sp = (SFSnortPacket *) p; BER_ELEMENT ber_element; const u_int8_t *end_of_string; u_int32_t namelen = 0; if(sp == NULL) return RULE_NOMATCH; if(sp->payload == NULL) return RULE_NOMATCH; // flow:established, to_server; if(checkFlow(p, rule16375options[0]->option_u.flowFlags) <= 0) return RULE_NOMATCH; // Initialize our pointer if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_payload, &end_of_payload) <= 0) return RULE_NOMATCH; // Universal Sequence if(ber_point_to_data(sp, &cursor_normal, 0x30) < 0) return RULE_NOMATCH; // Message ID if(ber_skip_element(sp, &cursor_normal, 0x02) < 0) return RULE_NOMATCH; // Search Request if(ber_point_to_data(sp, &cursor_normal, 0x66) < 0) return RULE_NOMATCH; // Object if(ber_get_element(sp, cursor_normal, &ber_element) < 0) return RULE_NOMATCH; // Make sure it's a string if(ber_element.type != 0x04) return RULE_NOMATCH; // Move the cursor to the start of the string data cursor_normal = ber_element.data.data_ptr; end_of_string = cursor_normal + ber_element.data_len; // Check for end of buffer if(end_of_string > end_of_payload) end_of_string = end_of_payload; // Now we have cursor_normal pointing to the start of the // string and end_of_string set appropriately. Now, // let's see how long the parameter names are. while(cursor_normal < end_of_string) { if(*cursor_normal != '=') namelen++; else { DEBUG_SO(printf("rule16375: namelen=%d\n", namelen)); if(namelen > 100) return RULE_MATCH; // Length is fine. Set back to zero. namelen = 0; // Now jump over the value while((cursor_normal < end_of_string) && (*cursor_normal != ',')) cursor_normal++; } cursor_normal++; } // If we were in the middle of an overly long parameter name // when we ran out of data, match. if(namelen > 100) return RULE_MATCH; return RULE_NOMATCH; }