00001 /** \file rlp.h 00002 00003 \brief Routines for parsing, writing and accessing rules. 00004 00005 ******************************************************************************/ 00006 00007 #ifndef _RLP 00008 #define _RLP 00009 00010 #include "nm.h" 00011 #include "pkt.h" 00012 #include "q.h" 00013 00014 #ifdef __cplusplus 00015 extern "C" { 00016 #endif 00017 00018 00019 /** 00020 * \brief Macros to help parse formulas 00021 * 00022 */ 00023 00024 #define RLP_SKIP_SPACE(s) while ( isspace(*s) ) s++; 00025 #define RLP_SKIP_TEXT(s) while ( !isspace(*s) ) s++; 00026 00027 #define RLP_STRNCPY_TERMINATE( dest, src, N ) strncpy( dest, src, N ); dest[N] = '\0'; 00028 00029 #define RLP_EXTRACT_FIELD( dest, tmpPtr, linePtr, tmpbuf ) \ 00030 tmpPtr = strpbrk( linePtr, " \t" ); \ 00031 RLP_STRNCPY_TERMINATE( tmpbuf, linePtr, tmpPtr - linePtr ); \ 00032 dest = strdup( tmpbuf ); \ 00033 RLP_SKIP_TEXT( linePtr ); SKIP_SPACE( linePtr ); 00034 00035 00036 /** 00037 * \brief Types of operators allowed in formulas. 00038 * 00039 * The types of nodes in a formula parse tree. ID 00040 * is for leaf nodes, all others are internal nodes. 00041 * 00042 */ 00043 00044 typedef enum 00045 { 00046 Rlp_List_c, 00047 Rlp_Undef_c, 00048 Rlp_Ack_c, /* <ack> {int, only 0 and 101058054 appear in the ruleset} */ 00049 Rlp_Byte_Jump_c, /* <bytes_to_convert>, <offset>, relative (use offset relative to 00050 last pattern match), align (round up the number of converted bytes 00051 to the next 32-bit boundary) {4 fields used in ruleset} */ 00052 Rlp_Byte_Test_c, /* <bytes_to_convert>, <operator>, <value>, <offset>, string, dec, 00053 relative, little {several others, but only these occur in practise */ 00054 Rlp_Content_c, /* [!] "<content string>" */ 00055 Rlp_Depth_c, /* <depth> {int, few occur in ruleset} */ 00056 Rlp_Distance_c, /* <byte count> {int, very few in ruleset } */ 00057 Rlp_Dsize_c, /* [<>]<number>[<><number>] {used to see payload size, none are checks 00058 on > and <} */ 00059 Rlp_Flags_c, /* [!:*:+]<FSRPAU120>[, <FSPRAU120>] {in ruleset, !, *, never occur, and + 00060 only occurs in A+, S+, and U+ } */ 00061 Rlp_Fragbits_c, /* [+-*]<[MDR]> {in ruleset, only M M+ MD and R appear} */ 00062 Rlp_Icmp_Id_c, /* <number> {int, few values appear in ruleset} */ 00063 Rlp_Icmp_Seq_c, /* <number> {int, only one (0) appears in ruleset} */ 00064 Rlp_Icode_c, /* [<>]<number>[<><number>] {only individual numbers appears in practise, 00065 each of 0-15} */ 00066 Rlp_Id_c, /* <number> {checks ip id field for specific value, 13170 242 3868 39426 413 00067 666 678 is the complete set} */ 00068 Rlp_Ip_Proto_c, /* [!><] <name or number> {only occurances are !1 !2 !47 !50 00069 !51 !6 !89 2} */ 00070 Rlp_IpOpts_c, /* <rr|eol|nop|ts|sec|lsrr|ssrr|satid|any> {ruleset has rr, lsrr, ssrr, lsrre - 00071 last must be a typo? } */ 00072 Rlp_Itype_c, /* [<>]<number>[<><number>] {looks for specific icmp message, 0-19, 30-40 00073 appear as singletons in ruleset} */ 00074 Rlp_Nocase_c, /* {no options} */ 00075 Rlp_Offset_c, /* <number> {used to tell where to start looking for pattern} */ 00076 Rlp_Pcre_c, /* <regexp> regexp in pcre format */ 00077 Rlp_Rpc_c, /* <app number>, [<vers number>|*], [<procedure number>|*> {SUN specific rpc 00078 services, only rpc:100009,*,* rpc:100083,*,* rpc:391029,*,* in ruleset} */ 00079 Rlp_Sameip_c, /* {no options, simply checks is srcip = dest ip} */ 00080 Rlp_Seq_c, /* <number> {int, check for tcp sequence number (0 101058054 1958810375 3868 00081 6060842 674711609 1675) are the ones appearing in the ruleset} */ 00082 Rlp_Ttl_c, /* [[<number>-]><=]<number> {ruleset only checks ttl:0 ttl:1 ttl:>220 } */ 00083 Rlp_Uricontent_c, /* [!] "<content string>" */ 00084 Rlp_Within_c, /* <number> {don't go more than X bytes past last match for current match} */ 00085 Rlp_Interface_c, 00086 Rlp_Sample_c, 00087 Rlp_Tcp_c, 00088 Rlp_Udp_c, 00089 Rlp_Icmp_c, 00090 Rlp_Ip_c, 00091 Rlp_Num_c, 00092 Rlp_Text_c, 00093 Rlp_IpBlock_c, 00094 Rlp_PortUnion_c, 00095 Rlp_IpUnion_c, 00096 Rlp_Negation_c, 00097 Rlp_PortRange_c, 00098 Rlp_IpEntry_c, 00099 Rlp_Alert_c, 00100 Rlp_Define_c, 00101 Rlp_ClassOfService_c, 00102 Rlp_Any_c, 00103 Rlp_Generic_c 00104 } Rlp_OperatorEnum_t; 00105 00106 00107 /** 00108 * \brief Node structure - basically a cons list 00109 * 00110 * An Rlp formula is just a node struct. 00111 */ 00112 00113 struct Rlp_Node_t 00114 { 00115 Rlp_OperatorEnum_t type; 00116 struct Rlp_Node_t *lchild; 00117 struct Rlp_Node_t *rchild; 00118 }; 00119 00120 typedef struct Rlp_Node_t Rlp_Formula_t; 00121 00122 00123 typedef util_attrib_val_t Rlp_RuleComponent_t; 00124 00125 00126 /** 00127 * \brief Struct to represent a single int entry 00128 * 00129 * Struct to represent a single int entry 00130 * 00131 */ 00132 00133 00134 struct RlpIntAttribute_t 00135 { 00136 int intEntry; 00137 }; 00138 00139 typedef struct RlpIntAttribute_t Rlp_IntAttribute_t; 00140 00141 00142 /** 00143 * \brief Sampling threshold. 00144 * 00145 */ 00146 00147 struct Rlp_SampleAttribute_t 00148 { 00149 double threshold; 00150 }; 00151 00152 typedef struct Rlp_SampleAttribute_t Rlp_SampleAttribute_t; 00153 00154 /** 00155 * \brief Interface to check against. 00156 * 00157 */ 00158 00159 struct Rlp_IfAttribute_t 00160 { 00161 char *ifName; 00162 Pkt_LibPcap_t *interface; 00163 }; 00164 00165 typedef struct Rlp_IfAttribute_t Rlp_IfAttribute_t; 00166 00167 00168 /** 00169 * \brief TCP ack value to check against. 00170 * 00171 * TCP ack value to check against. Single number. 00172 * 00173 * Implementation [2 mins - scanf call 00174 * 00175 */ 00176 00177 00178 struct Rlp_AckAttribute_t 00179 { 00180 u_int32_t ackValue; 00181 }; 00182 00183 typedef struct Rlp_AckAttribute_t Rlp_AckAttribute_t; 00184 00185 /** \brief Byte jump operation. 00186 00187 Byte jump operation. Grab some number of bytes, 00188 convert them to their numeric representation, 00189 jump the doe_ptr up that many bytes. 00190 00191 All Examples: 00192 <pre> 00193 byte_jump:4,12,relative,align 00194 byte_jump:4,20,relative,align 00195 byte_jump:4,4,relative,align 00196 </pre> 00197 00198 Format 00199 00200 <pre> 00201 byte_jump: <bytes_to_convert>, <offset> 00202 [, [relative],[big],[little],[string],[hex],[dec],[oct],[align]] 00203 </pre> 00204 00205 * Implementation: two scanfs for the num bytes and offset, then scanf strings setting 00206 * the relative, big, little, string, etc. - 5 mins 00207 * 00208 */ 00209 00210 00211 struct Rlp_ByteJumpAttribute_t 00212 { 00213 int bytesToConvert; 00214 int offset; 00215 bool relative; 00216 bool useLittleEndian; // default is big endian 00217 bool isString; // data is stored in string packet format 00218 bool isHex; // converted string data is represented in hex 00219 bool isDec; // converted string data is represented in decimal 00220 bool isOct; // converted string data is represented in oct 00221 bool doAlign; // convert the number of converted bytes upto the next 32-bit bndry 00222 }; 00223 00224 typedef struct Rlp_ByteJumpAttribute_t Rlp_ByteJumpAttribute_t; 00225 00226 00227 /** \brief Byte test operation. 00228 00229 Byte test operation. Test a byte field against 00230 a specific value (with operator). 00231 00232 All Examples: 00233 <pre> 00234 byte_test:1,>,6,2 00235 byte_test:1,>,7,1 00236 byte_test:2,>,1024,0,relative,little 00237 byte_test:4,>,100,20,relative 00238 byte_test:4,>,1000,28,relative 00239 byte_test:4,>,1024,20,relative 00240 byte_test:4,>,128,20,relative 00241 byte_test:4,>,128,8,relative 00242 byte_test:4,>,512,16,relative 00243 byte_test:4,>,512,240,relative 00244 byte_test:5,>,256,0,string,dec,relative 00245 </pre> 00246 00247 Format 00248 00249 <pre> 00250 byte_test: <bytes_to_convert>, <operator>, <value>, <offset> \ 00251 [, [relative],[big],[little],[string],[hex],[dec],[oct] 00252 </pre> 00253 00254 */ 00255 00256 00257 struct Rlp_ByteTestAttribute_t 00258 { 00259 int bytesToConvert; 00260 char check; // can be one of '<' , '>' , '=' , '!' 00261 int value; // value to test the converted value against 00262 int offset; // number of bytes into the payload to being processing 00263 bool relative; // use an offset relative to the last pattern match 00264 bool useLittleEndian; // default is big endian 00265 bool isString; // data is stored in string packet format 00266 bool isHex; // converted string data is represented in hex 00267 bool isDec; // converted string data is represented in decimal 00268 bool isOct; // converted string data is represented in oct 00269 }; 00270 00271 typedef struct Rlp_ByteTestAttribute_t Rlp_ByteTestAttribute_t; 00272 00273 00274 /** 00275 * \brief Content to test for. 00276 * 00277 This test is case sensitive. 00278 00279 The option data for the content keyword is somewhat complex; it can contain mixed 00280 text and binary data. 00281 00282 The binary data is generally enclosed within the pipe (|) 00283 character and represented as bytecode. Bytecode represents binary data as 00284 hexadecimal numbers and is a good shorthand method for describing complex 00285 binary data. 00286 00287 Multiple content rules can be specified in one rule. This allows rules to 00288 be tailored for less false positives. 00289 00290 The following characters must be escaped inside a content rule: : ; \ " 00291 00292 If the rule is preceded by a !, the alert will be triggered on 00293 packets that do not contain this content. 00294 00295 This is useful when writing rules that want to alert on packets 00296 that do not match a certain pattern 00297 00298 Examples: 00299 00300 <pre> 00301 alert tcp any any -> 192.168.1.0/24 143 (content:"|90C8 C0FF FFFF|/bin/sh"; msg:"IMAP buffer overflow!";) # illustrates mixed bytecode and test 00302 00303 alert tcp any any -> 192.168.1.0/24 21 (content: !"GET"; depth: 3; nocase; dsize: >100; msg: "Long Non-Get FTP command!";) # illustrates negation 00304 </pre> 00305 00306 Implementation need to split the byte code non bytecode - keep a array 00307 of individual strings. then de-escape the escaped chars, 00308 stitch together on the regular strings, convert the 00309 bytecodes, join together. 00310 00311 How is escaped 0 dealt with? it must be byte code, since otherwise 00312 the original string would be broken. 30mins 00313 */ 00314 00315 00316 00317 struct Rlp_ContentAttribute_t 00318 { 00319 util_byte_array_t *byteArray; 00320 bool negated; 00321 }; 00322 00323 typedef struct Rlp_ContentAttribute_t Rlp_ContentAttribute_t; 00324 00325 00326 /** 00327 * \brief Sets maximum search depth for the content pattern match 00328 * to search from beginning of region. 00329 * 00330 * Sets maximum search depth for the content pattern match 00331 * to search from beginning of region. 00332 * 00333 * Example: alert tcp any any -> 192.168.1.0/24 80 (content: "cgi-bin/phf"; offset: 3; depth: 22; msg: "CGI-PHF access";) 00334 * 00335 * Implementation [ 2mins - just a scanf 00336 * 00337 */ 00338 00339 00340 struct Rlp_DepthAttribute_t 00341 { 00342 int depth; 00343 }; 00344 00345 typedef struct Rlp_DepthAttribute_t Rlp_DepthAttribute_t; 00346 00347 00348 /** 00349 * \brief Look for at least N bytes between pattern matches using content. 00350 * 00351 * Look for at least N bytes between pattern matches using content. 00352 * 00353 * The rule listed below maps to a regular expression of ABCDE.{1}EFGH 00354 * 00355 <pre> 00356 alert tcp any any -> any any (content: "2 Patterns"; content: "ABCDE"; content: "EFGH"; distance: 1;) 00357 </pre> 00358 00359 * Implementation: 2mins - just a scanf 00360 * 00361 */ 00362 00363 00364 struct Rlp_DistanceAttribute_t 00365 { 00366 int byteCount; 00367 }; 00368 00369 typedef struct Rlp_DistanceAttribute_t Rlp_DistanceAttribute_t; 00370 00371 00372 /** 00373 * \brief The dsize option is used to test the packet payload size. 00374 * It may be set to any value, plus use the greater than/less than signs to 00375 * indicate ranges and limits. 00376 * 00377 * For example, if you know that a certain 00378 * service has a buffer of a certain size, you can set this option to watch 00379 * for attempted buffer overflows. It has the added advantage of being a much 00380 * faster way to test for a buffer overflow than a payload content check. 00381 * This can also be used to check a range of values. For example, dsize: 00382 * 400<>500 will return all the packets from 400 to 500 bytes in their 00383 * payload section. 00384 * 00385 * These checks always will return false on a stream 00386 * rebuilt packet. 00387 * 00388 * Format dsize: \[<>\]<number>\[<><number>]\ 00389 * (The > and < operators are optional) 00390 * 00391 * In all the rules I saw, the size checks were equal, <, or >: 00392 * 00393 * Some examples: 00394 * 00395 <pre> 00396 dsize: 0 00397 dsize: 20 00398 dsize: < 25 00399 dsize: <5 00400 dsize: >1 00401 dsize: >1000 00402 dsize: >800 00403 dsize:0 00404 dsize:1 00405 dsize:10 00406 dsize:>1023 00407 dsize:>1092 00408 </pre> 00409 * 00410 * Implementation [ 5 mins - just a test if numeric, scanf once or twice 00411 * 00412 */ 00413 00414 00415 struct Rlp_DsizeAttribute_t 00416 { 00417 bool greaterThan; 00418 bool lessThan; 00419 int dsize; 00420 }; 00421 00422 typedef struct Rlp_DsizeAttribute_t Rlp_DsizeAttribute_t; 00423 00424 00425 /** 00426 * \brief Possible ack flag values. 00427 * 00428 * Possible ack flag values. A flag check may be 00429 * 0, 1, or don't care. 00430 * 00431 */ 00432 00433 00434 typedef enum 00435 { 00436 zero_c, 00437 one_c, 00438 X_c 00439 } Rlp_FlagType_t; 00440 00441 00442 00443 /** 00444 * \brief Test the TCP flags for a match 00445 * 00446 * Test the TCP flags for a match. 00447 * 00448 * There are actually 9 flags variables 00449 <pre> 00450 F FIN (LSB in TCP Flags byte) 00451 S SYN 00452 R RST 00453 P PSH 00454 A ACK 00455 U URG 00456 2 Reserved bit 2 00457 1 Reserved bit 1 (MSB in TCP Flags byte) 00458 0 No TCP Flags Set 00459 </pre> 00460 * 00461 * There are also logical operators that can be used to specify matching 00462 * criteria for the indicated flags: 00463 * 00464 * + ALL flag, match on all specified flags plus any others 00465 * * ANY flag, match on any of the specified flags 00466 * ! NOT flag, match if the specified flags aren't set in the packet 00467 * 00468 * The reserved bits can be used to detect unusual behavior, such as IP stack 00469 * fingerprinting attempts or other suspicious activity. 00470 * 00471 * A SYN-FIN scan detection rule: 00472 * 00473 * alert any any -> 192.168.1.0/24 any (flags: SF,12; msg: "Possible SYN FIN 00474 * scan";) 00475 * 00476 * To handle writing rules for session initiation packets such as ECN 00477 * where a SYN packet is sent with the previously reserved bits 12 set, 00478 * an option mask may be specified. A rule could check for a 00479 * flags value of S,12 if one wishes to find syn packets 00480 * regardless of the values of the reserved bits. 00481 * 00482 * Format flags: <flag values>[,mask value]; 00483 * 00484 * This is the entire list: 00485 00486 <pre> 00487 flags:0 00488 flags:A 00489 flags:A+ 00490 flags:F 00491 flags:FPU 00492 flags:PA 00493 flags:PA12 00494 flags:S 00495 flags:S+ 00496 flags:SF12 00497 flags:SFU12 00498 flags:SA 00499 flags:SF 00500 flags:SFP 00501 flags:SFPU 00502 flags:SRAFPU 00503 flags:U+ 00504 </pre> 00505 00506 */ 00507 00508 00509 struct Rlp_FlagsAttribute_t 00510 { 00511 Rlp_FlagType_t F; 00512 Rlp_FlagType_t S; 00513 Rlp_FlagType_t R; 00514 Rlp_FlagType_t P; 00515 Rlp_FlagType_t A; 00516 Rlp_FlagType_t U; 00517 Rlp_FlagType_t r_2; 00518 Rlp_FlagType_t r_1; 00519 Rlp_FlagType_t noFlagsSet; 00520 }; 00521 00522 typedef struct Rlp_FlagsAttribute_t Rlp_FlagsAttribute_t; 00523 00524 00525 /** 00526 * \brief This rule inspects the fragment and reserved bits in the IP 00527 * header. 00528 * 00529 * There are three bits that can be checked, the Reserved Bit (RB), 00530 * More Fragments (MF) bit, and the Don't Fragment (DF) bit. 00531 * 00532 * This rule inspects the fragment and reserved bits in the IP 00533 * header. There are three bits that can be checked, the Reserved Bit (RB), 00534 * More Fragments (MF) bit, and the Don't Fragment (DF) bit. 00535 * 00536 * These bits can be checked in a variety of combinations. Use the following values to indicate specific bits: 00537 * 00538 - R: Reserved Bit 00539 - D: DF bit 00540 - M: MF bit 00541 00542 You can also use modifiers to indicate logical match criteria for the 00543 specified bits: 00544 00545 <pre> 00546 + ALL flag, match on specified bits plus any others 00547 - ANY flag, match if any of the specified bits are set 00548 ! NOT flag, match if the specified bits are not set 00549 00550 alert tcp !$HOME_NET any -> $HOME_NET any (fragbits: R+; msg: "Reserved bit set!";) 00551 </pre> 00552 00553 */ 00554 00555 00556 struct Rlp_FragbitsAttribute_t 00557 { 00558 Rlp_FlagType_t RB; 00559 Rlp_FlagType_t MF; 00560 Rlp_FlagType_t DF; 00561 }; 00562 00563 typedef struct Rlp_FragbitsAttribute_t Rlp_FragbitsAttribute_t; 00564 00565 00566 /** 00567 * \brief The icmp_id option examines an ICMP ECHO packet's ICMP ID 00568 * number for a specific value. 00569 * 00570 * This is useful because some covert channel programs use static ICMP 00571 * fields when they communicate. This particular plugin was developed to 00572 * enable the stacheldraht detection rules written by Max Vision, 00573 * but it is certainly useful for detection of a number of potential 00574 * attacks. 00575 * 00576 * The icmp_id option examines an ICMP ECHO packet's ICMP ID 00577 * number for a specific value. 00578 * 00579 * This is useful because some covert channel programs use static ICMP 00580 * fields when they communicate. This particular plugin was developed to 00581 * enable the stacheldraht detection rules written by Max Vision, 00582 * but it is certainly useful for detection of a number of potential 00583 * attacks. 00584 * 00585 * All uses: 00586 <pre> 00587 00588 icmp_id:0 00589 icmp_id:1000 00590 icmp_id:456 00591 icmp_id:51201 00592 icmp_id:666 00593 icmp_id:667 00594 icmp_id:668 00595 icmp_id:669 00596 icmp_id:123 00597 icmp_id:6666 00598 icmp_id:6667 00599 icmp_id:9015 00600 </pre> 00601 00602 */ 00603 00604 00605 struct Rlp_IcmpIdAttribute_t 00606 { 00607 int icmpId; 00608 }; 00609 00610 typedef struct Rlp_IcmpIdAttribute_t Rlp_IcmpIdAttribute_t; 00611 00612 /** 00613 * \brief The icmp_id option examines an ICMP ECHO packet's ICMP 00614 * sequence field for a specific value. 00615 * 00616 * This is useful because some covertchannel programs use 00617 * static ICMP fields when they communicate. This particular 00618 * plugin was developed to enable the stacheldraht detection 00619 * rules written by Max Vision, but it is certainly useful for detection 00620 * of a number of potential attacks. (And yes, I know the info for this field 00621 * is almost identical to the icmp_id description, it's practically the same 00622 * damn thing!) 00623 * 00624 * The icmp_id option examines an ICMP ECHO packet's ICMP 00625 * sequence field for a specific value. 00626 * 00627 * This is useful because some covertchannel programs use 00628 * static ICMP fields when they communicate. This particular 00629 * plugin was developed to enable the stacheldraht detection 00630 * rules written by Max Vision, but it is certainly useful for detection 00631 * of a number of potential attacks. (And yes, I know the info for this field 00632 * is almost identical to the icmp_id description, it's practically the same 00633 * damn thing!) 00634 * 00635 * All uses: 00636 * icmp_seq: 0 00637 * icmp_seq:0 00638 * 00639 */ 00640 00641 00642 00643 struct Rlp_IcmpSeqAttribute_t 00644 { 00645 int seqValue; 00646 }; 00647 00648 typedef struct Rlp_IcmpSeqAttribute_t Rlp_IcmpSeqAttribute_t; 00649 00650 00651 /** 00652 * \brief itype rule, just set a numeric value in here and 00653 * Detect any traffic using that ICMP code value. 00654 * 00655 * Out of range values can also be set to detect suspicious traffic. 00656 * 00657 * full set of values checked: 00658 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 30 31 32 33 34 35 36 39 40 00659 * 00660 */ 00661 00662 00663 struct Rlp_IcodeAttribute_t 00664 { 00665 int icode; 00666 }; 00667 00668 typedef struct Rlp_IcodeAttribute_t Rlp_IcodeAttribute_t; 00669 00670 00671 /** \brief Differnet types of ip options */ 00672 00673 typedef enum 00674 { 00675 Rlp_unassigned_c, 00676 Rlp_rr_c, 00677 Rlp_eol_c, 00678 Rlp_nop_c, 00679 Rlp_ts_c, 00680 Rlp_sec_c, 00681 Rlp_lsrr_c, 00682 Rlp_lsrre_c, 00683 Rlp_ssrr_c, 00684 Rlp_satid_c 00685 } Rlp_IpOpts_t; 00686 00687 00688 /** 00689 * \brief Ip options 00690 * 00691 * If IP options are present in a packet, this option will 00692 * search for a specific option in use, such as source routing. 00693 * 00694 * If IP options are present in a packet, this 00695 * option will search for a specific option in use, such as source routing. 00696 * 00697 * Valid arguments to this option are: 00698 * 00699 * rr - Record route 00700 * eol - End of list 00701 * nop - No op 00702 * ts - Time Stamp 00703 * sec - IP security option 00704 * lsrr - Loose source routing 00705 * ssrr - Strict source routing 00706 * satid - Stream identifier 00707 * 00708 * The most frequently watched for IP options are strict and loose source 00709 * routing which aren't used in any widespread internet applications. Only a 00710 * single option may be specified per rule. 00711 * 00712 * all uses of ipopt: 00713 * 00714 * ipopts: rr 00715 * ipopts: ssrr 00716 * ipopts:lsrr 00717 * ipopts:lsrre 00718 * 00719 */ 00720 00721 00722 struct Rlp_IpOptsAttribute_t 00723 { 00724 Rlp_IpOpts_t ipOpt; 00725 }; 00726 00727 00728 /** \brief Struct for IP options checking */ 00729 00730 typedef struct Rlp_IpOptsAttribute_t Rlp_IpOptsAttribute_t; 00731 00732 00733 /** 00734 * \brief Check the ip proto field. 00735 */ 00736 00737 00738 struct Rlp_IpProtoAttribute_t 00739 { 00740 bool lessThan; 00741 bool greaterThan; 00742 bool negated; 00743 int value; 00744 }; 00745 00746 typedef struct Rlp_IpProtoAttribute_t Rlp_IpProtoAttribute_t; 00747 00748 00749 /** 00750 * \brief This option keyword is used to test for an exact 00751 * match in the IP header fragment ID field. 00752 * 00753 * This option keyword is used to test for an exact 00754 * match in the IP header fragment ID field. 00755 * 00756 * Some hacking tools (and other programs) set this field 00757 * specifically for various purposes, for example 00758 * the value 31337 is very popular with some hackers. This can be turned 00759 * against them by putting a simple rule in place to test for this and some 00760 * other hacker numbers. 00761 * 00762 * full range of checks: 00763 * 00764 * id: 39426 00765 * id: 413 00766 * id: 666 00767 * id: 678 00768 * id:13170 00769 * id:242 00770 * id:3868 00771 * 00772 * Checks for id are syntactically identical to 00773 * ip_proto checks, so we can reuse the same structure. 00774 */ 00775 00776 typedef Rlp_IpProtoAttribute_t Rlp_IdAttribute_t; 00777 00778 00779 /** 00780 * \brief This rule tests the value of the ICMP type field. It is set 00781 * using the numeric value of this field. 00782 * 00783 * This rule tests the value of the ICMP type field. It is set 00784 * using the numeric value of this field. 00785 * 00786 * It should be noted that the values can be set out of range to detect invalid 00787 * ICMP type values that are sometimes used in denial of service and flooding 00788 * attacks. 00789 * 00790 * All uses: 00791 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 30 31 32 33 34 35 36 39 40 00792 * 00793 */ 00794 00795 struct Rlp_ItypeAttribute_t 00796 { 00797 int itype; 00798 }; 00799 00800 typedef struct Rlp_ItypeAttribute_t Rlp_ItypeAttribute_t; 00801 00802 00803 /** 00804 * \brief The nocase option is used to deactivate case sensitivity in 00805 * a content rule. 00806 * 00807 * The nocase option is used to deactivate case sensitivity in 00808 * a content rule. 00809 * 00810 * It is specified alone within a rule and any ASCII 00811 * characters that are compared to the packet payload are treated as though 00812 * they are either upper of lower case. 00813 * 00814 * alert tcp any any -> 192.168.1.0/24 21 (content:"USER root"; nocase; 00815 * msg: "FTP root user access attempt";) 00816 * 00817 * Using a struct is unnecc, since the parse tree will contain the nocase 00818 * node; will remove this at some point. 00819 * 00820 */ 00821 00822 00823 struct Rlp_NocaseAttribute_t 00824 { 00825 bool nocase; 00826 }; 00827 00828 typedef struct Rlp_NocaseAttribute_t Rlp_NocaseAttribute_t; 00829 00830 00831 /** 00832 * \brief The offset rule option is used as a modifier to rules using 00833 * the content option keyword. 00834 00835 * This keyword modifies the starting search 00836 * position for the pattern match function from the beginning of the packet 00837 * payload. 00838 * 00839 * The offset rule option is used as a modifier to rules using 00840 * the content option keyword. This keyword modifies the starting search 00841 * position for the pattern match function from the beginning of the packet 00842 * payload. 00843 * 00844 * It is very useful for things like CGI scan detection rules where 00845 * the content search string is never found in the first four bytes of the 00846 * payload. Care should be taken against setting the offset value too tightly 00847 * and potentially missing an attack! 00848 * 00849 * This rule option keyword cannot be used without also specifying a content rule 00850 * option. 00851 * 00852 * Example: 00853 * 00854 * alert tcp any any -> 192.168.1.0/24 80 (content: "cgi-bin/phf"; offset: 3; depth: 22; msg: "CGI-PHF access";) 00855 * 00856 */ 00857 00858 00859 struct Rlp_OffsetAttribute_t 00860 { 00861 int offset; 00862 }; 00863 00864 typedef struct Rlp_OffsetAttribute_t Rlp_OffsetAttribute_t; 00865 00866 00867 /** 00868 * \brief This option looks at 00869 * RPC requests and automatically decodes the application, procedure, and 00870 * program version, indicating success when all three variables are matched. 00871 * 00872 * This option looks at 00873 * RPC requests and automatically decodes the application, procedure, and 00874 * program version, indicating success when all three variables are matched. 00875 * 00876 * The format of the option call is application, procedure, version. 00877 * 00878 * Wildcards are valid for both the procedure and version numbers and are 00879 * indicated with a *. 00880 * 00881 * Format: rpc: <number, [number|*], [number|*]> 00882 * 00883 * Example: 00884 * 00885 * alert tcp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3; msg:"RPC getport (TCP)";) 00886 * 00887 * alert udp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3; msg:"RPC getport (UDP)";) a 00888 * 00889 * alert udp any any -> 192.168.1.0/24 111 (rpc: 100083,*,*; msg:"RPC ttdb";) 00890 * 00891 * alert udp any any -> 192.168.1.0/24 111 (rpc: 100232,10,*; msg:"RPC sadmin";) 00892 * 00893 */ 00894 00895 00896 struct Rlp_RpcAttribute_t 00897 { 00898 int application; 00899 bool anyProcedure; 00900 int procedure; 00901 bool anyVersion; 00902 int version; 00903 }; 00904 00905 typedef struct Rlp_RpcAttribute_t Rlp_RpcAttribute_t; 00906 00907 00908 00909 /** 00910 * \brief Check if source and dest ip are the same. 00911 * 00912 * Check if source and dest ip are the same. 00913 * 00914 * Takes no optins - should be removed as this information is implicit in the 00915 * parse tree. 00916 * 00917 */ 00918 00919 00920 struct Rlp_SameIpAttribute_t 00921 { 00922 bool sameIp; 00923 }; 00924 00925 typedef struct Rlp_SameIpAttribute_t Rlp_SameIpAttribute_t; 00926 00927 00928 /** 00929 * \brief This rule option refers to the TCP sequence number. 00930 * 00931 * This rule option refers to the TCP sequence number. 00932 * 00933 * Essentially, it detects if the packet has a static sequence number set, 00934 * and is therefore pretty much unused. It was included for the sake of 00935 * completeness. 00936 * 00937 * The above comment notwithstanding, the check is used in a number of places: 00938 * 00939 * seq: 101058054 00940 * seq: 3868 00941 * seq: 6060842 00942 * seq: 674711609 00943 * seq:0 00944 * seq:1958810375 00945 * 00946 */ 00947 00948 00949 00950 struct Rlp_SeqAttribute_t 00951 { 00952 u_int32_t seqValue; 00953 }; 00954 00955 typedef struct Rlp_SeqAttribute_t Rlp_SeqAttribute_t; 00956 00957 00958 /** 00959 * \brief This rule option is used to set a 00960 * specific time-to-live value to test against. 00961 * 00962 * This rule option is used to set a 00963 * specific time-to-live value to test against. 00964 * 00965 * The test it performs is only 00966 * successful on an exact match. This option keyword was intended for use in 00967 * the detection of traceroute attempts. 00968 * 00969 * Uses: 00970 * 00971 * ttl: >220 00972 * ttl:0 00973 * ttl:1 00974 * 00975 */ 00976 00977 00978 struct Rlp_TtlAttribute_t 00979 { 00980 bool greaterThan; 00981 bool lessThan; 00982 int ttl; 00983 }; 00984 00985 typedef struct Rlp_TtlAttribute_t Rlp_TtlAttribute_t; 00986 00987 00988 /** 00989 * \brief This rule allows searches to be matched 00990 * against only the URI portion of a request. 00991 * 00992 * This rule allows searches to be matched 00993 * against only the URI portion of a request. 00994 * 00995 * This allows rules to search only the request portion of an attack 00996 * without false alerts from server data files. For a description of 00997 * the parameters to this function, see the content rule options. 00998 * 00999 */ 01000 01001 typedef Rlp_ContentAttribute_t Rlp_UriContentAttribute_t; 01002 01003 01004 /** 01005 * \brief The within keyword is a content modifier that makes sure 01006 * that at least N bytes are between pattern matches. 01007 * 01008 * The within keyword is a content modifier that makes sure 01009 * that atleast N bytes are between pattern matches. 01010 * 01011 * It's designed to be used in conjunction with the distance rule option. 01012 * The rule listed below contrains the 01013 * search to not go past 10 bytes past the ABCDE match. 01014 * 01015 * alert tcp any any -> any any (content: "2 Patterns"; content: 01016 * "ABCDE"; content: "EFGH"; within: 10;) 01017 * 01018 * The within tells the matching to look for an EFGH starting no more than 01019 * 10 bytes after the first char of the ABCDE. 01020 * 01021 * With nested withins e.g., foo W bar W xyz, the semantics is that 01022 * on a foo, if a bar is matched then the overall match holds just in case 01023 * the xyz matches on the FIRST matched bar; if it doesn't then we don;t go further 01024 * till the within range. 01025 * 01026 */ 01027 01028 01029 01030 struct Rlp_WithinAttribute_t 01031 { 01032 int within; 01033 }; 01034 01035 typedef struct Rlp_WithinAttribute_t Rlp_WithinAttribute_t; 01036 01037 /** 01038 * \brief Possible types of L7 checks. 01039 * 01040 * Possible types of L7 checks. 01041 * 01042 */ 01043 01044 01045 typedef enum 01046 { 01047 Rlp_L7UndefCheck_c, 01048 Rlp_L7ContentCheck_c, 01049 Rlp_L7UriContentCheck_c, 01050 Rlp_L7ByteJumpCheck_c, 01051 Rlp_L7ByteTestCheck_c, 01052 Rlp_L7PcreCheck_c 01053 } Rlp_L7CheckType_t; 01054 01055 01056 /** 01057 * \brief Struct for checking a content type rule 01058 * 01059 * Struct for checking a content type rule 01060 * 01061 */ 01062 01063 01064 struct Rlp_ContentCheckAttribute_t 01065 { 01066 bool nocase; 01067 int depth; 01068 int offset; 01069 int distance; 01070 int within; 01071 util_byte_array_t *content; 01072 bool negated; 01073 }; 01074 01075 typedef struct Rlp_ContentCheckAttribute_t Rlp_ContentCheck_t; 01076 01077 /** 01078 * \brief Struct for checking a byte test type rule. 01079 * 01080 * Struct for checking a byte test type rule. It's the 01081 * same as the byte test attribute struct, since the 01082 * information is contained already in a parsed form. 01083 * 01084 */ 01085 01086 01087 typedef Rlp_ByteTestAttribute_t Rlp_ByteTestCheck_t; 01088 01089 /** 01090 * \brief Struct for checking a byte jump type rule. 01091 * 01092 * Struct for checking a byte jump type rule. It's the 01093 * same as the byte jump attribute struct, since the 01094 * information is contained already in a parsed form. 01095 * 01096 */ 01097 01098 01099 typedef Rlp_ByteJumpAttribute_t Rlp_ByteJumpCheck_t; 01100 01101 /** 01102 * \brief Struct for pcre checking 01103 * 01104 * 01105 */ 01106 01107 struct Rlp_PcreAttribute_t 01108 { 01109 char *reText; 01110 pcre *re; 01111 pcre_extra *pe; 01112 }; 01113 01114 typedef struct Rlp_PcreAttribute_t Rlp_PcreAttribute_t; 01115 01116 typedef Rlp_PcreAttribute_t Rlp_PcreCheck_t; 01117 01118 01119 /** 01120 * \brief A struct for holding the content tests on a formula 01121 * 01122 * A struct for holding the content tests on a formula. Poorly 01123 * named, since the byte jump is actually the amount to 01124 * advance the stream pointer by. 01125 * 01126 */ 01127 01128 01129 struct Rlp_L7Check_t 01130 { 01131 Rlp_L7CheckType_t type; 01132 union 01133 { 01134 Rlp_ContentCheck_t *contentCheck; 01135 Rlp_ByteTestCheck_t *byteTestCheck; 01136 Rlp_ByteJumpCheck_t *byteJumpCheck; 01137 Rlp_PcreCheck_t *pcreCheck; 01138 } entryData; 01139 }; 01140 01141 typedef struct Rlp_L7Check_t Rlp_L7Check_t; 01142 01143 /** 01144 * \brief A struct for holding the layer 4 check on a formula 01145 * 01146 * A struct for holding the layer 4 check on the formula. Poorly 01147 * named, since the optional content checks enclosed in parens 01148 * also check layer 3/4 information. 01149 * 01150 */ 01151 01152 01153 struct Rlp_L4Check_t 01154 { 01155 char *typeString; 01156 Rlp_OperatorEnum_t type; 01157 char *srcIpString; 01158 Rlp_Formula_t *srcIp; 01159 char *srcPortString; 01160 Rlp_Formula_t *srcPort; 01161 char *destIpString; 01162 Rlp_Formula_t *destIp; 01163 char *destPortString; 01164 Rlp_Formula_t *destPort; 01165 }; 01166 01167 typedef struct Rlp_L4Check_t Rlp_L4Check_t; 01168 01169 01170 // #endif // include the structs 01171 01172 01173 // #ifdef _INCLUDE_PROTOTYPES 01174 01175 01176 /** 01177 * \brief Enum for the different possible actions for a packet. 01178 * 01179 */ 01180 01181 typedef enum 01182 { 01183 Rlp_ActionUnassigned_c, 01184 // Rlp_ActionLog_c, 01185 // Rlp_ActionAlert_c, 01186 Rlp_ActionDrop_c, 01187 // Rlp_ActionEncrypt_c, 01188 // Rlp_ActionDecrypt_c, 01189 // Rlp_ActionCompress_c, 01190 // Rlp_ActionDecompress_c, 01191 Rlp_ActionRoute_c, 01192 Rlp_ActionQueue_c, 01193 // Rlp_ActionUserAction_c, 01194 Rlp_ActionUscript_c, 01195 Rlp_ActionUcode_c, 01196 } Rlp_ActionEnum_t; 01197 01198 01199 /** 01200 * \brief Struct encoding the action to be taken. 01201 * 01202 */ 01203 01204 struct Rlp_Action_t 01205 { 01206 Rlp_ActionEnum_t type; 01207 01208 char *dest; 01209 Pkt_LibNet_t *destLibnet; 01210 01211 // Cryp_Aes_t *aes; 01212 01213 char *queue; 01214 int classIndex; 01215 01216 char *uscript; 01217 01218 char *ucodeName; 01219 int (*ucodeFunction) ( void *, void *, void **, char * ); 01220 void *ucodeFunctionState; 01221 01222 // use same argument for script and function 01223 char *argument; 01224 }; 01225 01226 typedef struct Rlp_Action_t Rlp_Action_t; 01227 01228 01229 extern Rlp_Formula_t *car (Rlp_Formula_t *); 01230 extern Rlp_Formula_t *cdr (Rlp_Formula_t *); 01231 extern Rlp_Formula_t *cons (Rlp_Formula_t *, Rlp_Formula_t *); 01232 extern Rlp_Formula_t *new_node (Rlp_OperatorEnum_t, Rlp_Formula_t *, 01233 Rlp_Formula_t *); 01234 01235 /**AutomaticStart*************************************************************/ 01236 01237 /*---------------------------------------------------------------------------*/ 01238 /* Extern function prototypes */ 01239 /*---------------------------------------------------------------------------*/ 01240 01241 extern Rlp_Action_t *Rlp_AllocActionStruct (); 01242 extern Rlp_Action_t *Rlp_CreateActionFromRawText (char *rawFormula); 01243 extern void Rlp_ActionPrint (Rlp_Action_t * action); 01244 extern Rlp_L4Check_t *Rlp_AllocL4CheckStruct (); 01245 extern Rlp_L4Check_t *Rlp_CreateL4CheckFromRawFormula (char *rawFormula); 01246 extern Rlp_Formula_t *Rlp_ComputeIpFormulaFromString (char *ipString); 01247 extern u_int32_t Rlp_DotToInt (char *dotString); 01248 extern Rlp_Formula_t *Rlp_ComputePortFormulaFromString (char *portString); 01249 extern array_t *Rlp_BuildContentCheckArrayFromL7Formula (Rlp_Formula_t * 01250 aL7Formula); 01251 extern int Rlp_FreeL7CheckArray (array_t * L7CheckArray); 01252 extern Rlp_Formula_t *new_node (Rlp_OperatorEnum_t type, 01253 Rlp_Formula_t * lchild, 01254 Rlp_Formula_t * rchild); 01255 extern Rlp_Formula_t *make2eltlist (Rlp_Formula_t * a, Rlp_Formula_t * b); 01256 extern Rlp_Formula_t *car (Rlp_Formula_t * a); 01257 extern Rlp_Formula_t *cdr (Rlp_Formula_t * a); 01258 extern int node_print (Rlp_Formula_t * a); 01259 extern char *Rlp_ConvertParseTreeToText (Rlp_Formula_t * aFormula); 01260 extern int Rlp_PrintFormulaTree (Rlp_Formula_t * aFormula); 01261 extern void Rlp_FormulaFree (Rlp_Formula_t * aFormula); 01262 extern Rlp_Formula_t *Rlp_CreateParseTreeFromText (char *text); 01263 extern Rlp_Formula_t *Rlp_CreateParseTreeFromAttribValuePairArray (array_t * 01264 aRule); 01265 extern int Rlp_ParsedRulePrint (Rlp_Formula_t * aTree); 01266 extern util_byte_array_t *Rlp_ByteCodeToByteArray (char *byteCode); 01267 extern int Rlp_NodePrint (Rlp_Formula_t * entry); 01268 extern array_t *Rlp_TestReadL7FormulasFromFile (char *fileName); 01269 extern char *Rlp_GetL4ComponentFromRawRule (char *rawRule); 01270 extern char *Rlp_GetL7ComponentFromRawRule (char *rawRule); 01271 extern char *Rlp_GetActionComponentFromRawRule (char *rawRule); 01272 extern int Rlp_FreeArrayOfStrings (array_t * stringArray); 01273 extern st_table *Rlp_L7CheckGetContentChecks (array_t * L7CheckArray); 01274 extern void Rlp_TestParseContent (char *fileName); 01275 extern int Rlp_UpdateDefineTable (st_table * aTable, char *anEntry); 01276 extern array_t *Rlp_L7StringParse (char *l7Rule); 01277 01278 /**AutomaticEnd***************************************************************/ 01279 01280 #ifdef __cplusplus 01281 } 01282 #endif 01283 01284 01285 #endif /* _RLP */