00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #ifdef HAVE_CONFIG_H
00075 #include "config.h"
00076 #endif
00077
00078 #include <sys/types.h>
00079 #include <stdlib.h>
00080 #include <ctype.h>
00081 #ifdef HAVE_STRINGS_H
00082 #include <strings.h>
00083 #endif
00084 #include <errno.h>
00085
00086 #include "bounds.h"
00087 #include "byte_extract.h"
00088 #include "rules.h"
00089 #include "decode.h"
00090 #include "plugbase.h"
00091 #include "parser.h"
00092 #include "debug.h"
00093 #include "util.h"
00094 #include "plugin_enum.h"
00095 #include "mstring.h"
00096
00097 #define BT_LESS_THAN 1
00098 #define BT_EQUALS 2
00099 #define BT_GREATER_THAN 3
00100 #define BT_AND 4
00101 #define BT_OR 5
00102
00103 #define BIG 0
00104 #define LITTLE 1
00105 #define PARSELEN 10
00106 #define TEXTLEN (PARSELEN + 2)
00107
00108 extern u_int8_t *doe_ptr;
00109
00110 typedef struct _ByteTestData
00111 {
00112 u_int32_t bytes_to_compare;
00113 u_int32_t cmp_value;
00114 u_int32_t operator;
00115 int32_t offset;
00116 u_int8_t not_flag;
00117 u_int8_t relative_flag;
00118 u_int8_t data_string_convert_flag;
00119 u_int8_t endianess;
00120 u_int32_t base;
00121 } ByteTestData;
00122
00123 extern u_int8_t DecodeBuffer[DECODE_BLEN];
00124
00125 void ByteTestInit(char *, OptTreeNode *, int);
00126 void ByteTestParse(char *, ByteTestData *, OptTreeNode *);
00127 int ByteTest(Packet *, struct _OptTreeNode *, OptFpList *);
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 void SetupByteTest(void)
00141 {
00142
00143 RegisterPlugin("byte_test", ByteTestInit);
00144
00145 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: ByteTest Setup\n"););
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void ByteTestInit(char *data, OptTreeNode *otn, int protocol)
00165 {
00166 ByteTestData *idx;
00167 OptFpList *fpl;
00168
00169
00170
00171 idx = (ByteTestData *) calloc(sizeof(ByteTestData), sizeof(char));
00172
00173 if(idx == NULL)
00174 {
00175 FatalError("%s(%d): Unable to allocate byte_test data node\n",
00176 file_name, file_line);
00177 }
00178
00179
00180
00181 ByteTestParse(data, idx, otn);
00182
00183 fpl = AddOptFuncToList(ByteTest, otn);
00184
00185
00186
00187
00188 fpl->context = (void *) idx;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 void ByteTestParse(char *data, ByteTestData *idx, OptTreeNode *otn)
00208 {
00209 char **toks;
00210 char *endp;
00211 int num_toks;
00212 char *cptr;
00213 int i =0;
00214
00215 toks = mSplit(data, ",", 12, &num_toks, 0);
00216
00217 if(num_toks < 4)
00218 FatalError("ERROR %s (%d): Bad arguments to byte_test: %s\n", file_name,
00219 file_line, data);
00220
00221
00222 idx->bytes_to_compare = strtol(toks[0], &endp, 10);
00223
00224 if(toks[0] == endp)
00225 {
00226 FatalError("%s(%d): Unable to parse as byte value %s\n",
00227 file_name, file_line, toks[0]);
00228 }
00229
00230 if(idx->bytes_to_compare > PARSELEN || idx->bytes_to_compare == 0)
00231 {
00232 FatalError("%s(%d): byte_test can't process more than "
00233 "10 bytes!\n", file_name, file_line);
00234 }
00235
00236 cptr = toks[1];
00237
00238 while(isspace((int)*cptr)) {cptr++;}
00239
00240 if(*cptr == '!')
00241 {
00242 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00243 "enabling not flag\n"););
00244 idx->not_flag = 1;
00245 cptr++;
00246 }
00247
00248 if (idx->not_flag && strlen(cptr) == 0)
00249 {
00250 idx->operator = BT_EQUALS;
00251 }
00252 else
00253 {
00254
00255 switch(*cptr)
00256 {
00257 case '<': idx->operator = BT_LESS_THAN;
00258 break;
00259
00260 case '=': idx->operator = BT_EQUALS;
00261 break;
00262
00263 case '>': idx->operator = BT_GREATER_THAN;
00264 break;
00265
00266 case '&': idx->operator = BT_AND;
00267 break;
00268
00269 case '^': idx->operator = BT_OR;
00270 break;
00271
00272 default: FatalError("ERROR %s(%d): byte_test unknown "
00273 "operator ('%c, %s')\n", file_name, file_line,
00274 *cptr, toks[1]);
00275 }
00276 }
00277
00278 errno = 0;
00279
00280
00281 idx->cmp_value = strtoul(toks[2], &endp, 0);
00282
00283 if(toks[2] == endp)
00284 {
00285 FatalError("%s(%d): Unable to parse as comparison value %s\n",
00286 file_name, file_line, toks[2]);
00287 }
00288
00289 if(errno == ERANGE)
00290 {
00291 printf("Bad range: %s\n", toks[2]);
00292 }
00293
00294
00295 idx->offset = strtol(toks[3], &endp, 10);
00296
00297
00298 if(toks[3] == endp)
00299 {
00300 FatalError("%s(%d): Unable to parse as offset value %s\n",
00301 file_name, file_line, toks[3]);
00302 }
00303
00304
00305 i = 4;
00306
00307
00308 if(num_toks > 4)
00309 {
00310 while(i < num_toks)
00311 {
00312 cptr = toks[i];
00313
00314 while(isspace((int)*cptr)) {cptr++;}
00315
00316 if(!strcasecmp(cptr, "relative"))
00317 {
00318
00319 idx->relative_flag = 1;
00320 }
00321 else if(!strcasecmp(cptr, "string"))
00322 {
00323
00324
00325
00326 idx->data_string_convert_flag = 1;
00327 }
00328 else if(!strcasecmp(cptr, "little"))
00329 {
00330 idx->endianess = LITTLE;
00331 }
00332 else if(!strcasecmp(cptr, "big"))
00333 {
00334
00335 idx->endianess = BIG;
00336 }
00337 else if(!strcasecmp(cptr, "hex"))
00338 {
00339 idx->base = 16;
00340 }
00341 else if(!strcasecmp(cptr, "dec"))
00342 {
00343 idx->base = 10;
00344 }
00345 else if(!strcasecmp(cptr, "oct"))
00346 {
00347 idx->base = 8;
00348 }
00349 else
00350 {
00351 FatalError("%s(%d): unknown modifier \"%s\"\n",
00352 file_name, file_line, cptr);
00353 }
00354
00355 i++;
00356 }
00357 }
00358
00359
00360 if(!idx->data_string_convert_flag && idx->base)
00361 {
00362 FatalError("%s(%d): hex, dec and oct modifiers must be used in conjunction \n"
00363 " with the 'string' modifier\n", file_name,file_line);
00364 }
00365
00366 mSplitFree(&toks, num_toks);
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 int ByteTest(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list)
00386 {
00387 ByteTestData *btd;
00388 u_int32_t value = 0;
00389 int success = 0;
00390 int use_alt_buffer = p->packet_flags & PKT_ALT_DECODE;
00391 int dsize;
00392 char *base_ptr, *end_ptr, *start_ptr;
00393
00394 if(use_alt_buffer)
00395 {
00396 dsize = p->alt_dsize;
00397 start_ptr = (char *)DecodeBuffer;
00398 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00399 "Using Alternative Decode buffer!\n"););
00400 }
00401 else
00402 {
00403 dsize = p->dsize;
00404 start_ptr = (char *) p->data;
00405 }
00406
00407 base_ptr = start_ptr;
00408 end_ptr = start_ptr + dsize;
00409
00410 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00411 "[*] byte test firing...\npayload starts at %p\n", start_ptr););
00412
00413 if(doe_ptr)
00414 {
00415
00416 if(!inBounds(start_ptr, end_ptr, doe_ptr))
00417 {
00418 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00419 "[*] byte test bounds check failed..\n"););
00420 return 0;
00421 }
00422 }
00423
00424 btd = (ByteTestData *) fp_list->context;
00425
00426 if(btd->relative_flag && doe_ptr)
00427 {
00428 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00429 "Checking relative offset!\n"););
00430 base_ptr = doe_ptr + btd->offset;
00431 }
00432 else
00433 {
00434 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00435 "checking absolute offset %d\n", btd->offset););
00436 base_ptr = start_ptr + btd->offset;
00437 }
00438
00439
00440
00441
00442
00443
00444 if(!btd->data_string_convert_flag)
00445 {
00446 if(byte_extract(btd->endianess, btd->bytes_to_compare,
00447 base_ptr, start_ptr, end_ptr, &value))
00448 {
00449 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00450 "Byte Extraction Failed\n"););
00451
00452 return 0;
00453 }
00454 }
00455 else
00456 {
00457 if(string_extract(btd->bytes_to_compare, btd->base,
00458 base_ptr, start_ptr, end_ptr, &value))
00459 {
00460 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00461 "String Extraction Failed\n"););
00462
00463 return 0;
00464 }
00465
00466 }
00467
00468 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00469 "Grabbed %d bytes at offset %d, value = 0x%08X(%d)\n",
00470 btd->bytes_to_compare, btd->offset, value, value); );
00471
00472 switch(btd->operator)
00473 {
00474 case BT_LESS_THAN: if(value < btd->cmp_value)
00475 success = 1;
00476 break;
00477
00478 case BT_EQUALS: if(value == btd->cmp_value)
00479 success = 1;
00480 break;
00481
00482 case BT_GREATER_THAN: if(value > btd->cmp_value)
00483 success = 1;
00484 break;
00485
00486 case BT_AND: if ((value & btd->cmp_value) > 0)
00487 success = 1;
00488 break;
00489
00490 case BT_OR: if ((value ^ btd->cmp_value) > 0)
00491 success = 1;
00492 break;
00493 }
00494
00495 if (btd->not_flag)
00496 {
00497 DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
00498 "checking for not success...flag\n"););
00499 if (!success)
00500 {
00501 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00502 }
00503 }
00504 else if (success)
00505 {
00506 return fp_list->next->OptTestFunc(p, otn, fp_list->next);
00507 }
00508
00509
00510 return 0;
00511 }