Browse code

hwp3.x: add support for maximum recursive calls to hwp3 parsing

Kevin Lin authored on 2016/01/20 04:25:55
Showing 12 changed files
... ...
@@ -884,6 +884,16 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
884 884
     val = cl_engine_get_num(engine, CL_ENGINE_MAX_ICONSPE, NULL);
885 885
     logg("Limits: MaxIconsPE limit set to %llu.\n", val);
886 886
 
887
+    if((opt = optget(opts, "MaxRecHWP3"))->active) {
888
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECHWP3, opt->numarg))) {
889
+            logg("!cli_engine_set_num(MaxRecHWP3) failed: %s\n", cl_strerror(ret));
890
+            cl_engine_free(engine);
891
+            return 1;
892
+        }
893
+    }
894
+    val = cl_engine_get_num(engine, CL_ENGINE_MAX_RECHWP3, NULL);
895
+    logg("Limits: MaxRecHWP3 limit set to %llu.\n", val);
896
+
887 897
     if((opt = optget(opts, "PCREMatchLimit"))->active) {
888 898
         if((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MATCH_LIMIT, opt->numarg))) {
889 899
             logg("!cli_engine_set_num(PCREMatchLimit) failed: %s\n", cl_strerror(ret));
... ...
@@ -280,6 +280,7 @@ void help(void)
280 280
     mprintf("    --max-ziptypercg=#n                  Maximum size zip to type reanalyze\n");
281 281
     mprintf("    --max-partitions=#n                  Maximum number of partitions in disk image to be scanned\n");
282 282
     mprintf("    --max-iconspe=#n                     Maximum number of icons in PE file to be scanned\n");
283
+    mprintf("    --max-rechwp3=#n                     Maximum recursive calls to HWP3 parsing function\n");
283 284
 #if HAVE_PCRE
284 285
     mprintf("    --pcre-match-limit=#n                Maximum calls to the PCRE match function.\n");
285 286
     mprintf("    --pcre-recmatch-limit=#n             Maximum recursive calls to the PCRE match function.\n");
... ...
@@ -986,6 +986,15 @@ int scanmanager(const struct optstruct *opts)
986 986
         }
987 987
     }
988 988
 
989
+    if((opt = optget(opts, "max-rechwp3"))->active) {
990
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECHWP3, opt->numarg))) {
991
+            logg("!cli_engine_set_num(CL_ENGINE_MAX_RECHWP3) failed: %s\n", cl_strerror(ret));
992
+
993
+            cl_engine_free(engine);
994
+            return 2;
995
+        }
996
+    }
997
+
989 998
     if ((opt = optget(opts, "timelimit"))->active) {
990 999
         if ((ret = cl_engine_set_num(engine, CL_ENGINE_TIME_LIMIT, opt->numarg))) {
991 1000
             logg("!cli_engine_set_num(CL_ENGINE_TIME_LIMIT) failed: %s\n", cl_strerror(ret));
... ...
@@ -577,6 +577,19 @@ WARNING: setting this limit too high may result in severe damage or impact perfo
577 577
 .br
578 578
 Default: 100
579 579
 .TP
580
+\fBMaxRecHWP3 NUMBER\fR
581
+This option sets the maximum recursive calls to HWP3 parsing function.
582
+.br
583
+HWP3 files using more than this limit will be terminated and alert the user.
584
+.br
585
+Scans will be unable to scan any HWP3 attachments if the recursive limit is reached.
586
+.br
587
+Negative values are not allowed.
588
+.br
589
+WARNING: setting this limit too high may result in severe damage or impact performance.
590
+.br
591
+Default: 16
592
+.TP
580 593
 \fBPCREMatchLimit NUMBER\fR
581 594
 This option sets the maximum calls to the PCRE match function during an instance of regex matching.
582 595
 .br
... ...
@@ -214,6 +214,9 @@ This option sets the maximum number of partitions of a raw disk image to be scan
214 214
 \fB\-\-max\-iconspe=#n\fR
215 215
 This option sets the maximum number of icons within a PE to be scanned. This must be a positive integer (default: 100).
216 216
 .TP
217
+\fB\-\-max\-rechwp3=#n\fR
218
+This option sets the maximum recursive calls to HWP3 parsing function (default: 16).
219
+.TP
217 220
 \fB\-\-pcre-match-limit=#n\fR
218 221
 Maximum calls to the PCRE match function (default: 10000).
219 222
 .TP
... ...
@@ -522,6 +522,14 @@ Example
522 522
 # Default: 100
523 523
 #MaxIconsPE 200
524 524
 
525
+# This option sets the maximum recursive calls for HWP3 parsing during scanning.
526
+# HWP3 files using more than this limit will be terminated and alert the user.
527
+# Scans will be unable to scan any HWP3 attachments if the recursive limit is reached.
528
+# Negative values are not allowed.
529
+# WARNING: setting this limit too high may result in severe damage or impact performance.
530
+# Default: 16
531
+#MaxRecHWP3 16
532
+
525 533
 # This option sets the maximum calls to the PCRE match function during an instance of regex matching.
526 534
 # Instances using more than this limit will be terminated and alert the user but the scan will continue.
527 535
 # For more information on match_limit, see the PCRE documentation.
... ...
@@ -236,6 +236,7 @@ enum cl_engine_field {
236 236
     CL_ENGINE_STATS_TIMEOUT,        /* uint32_t */
237 237
     CL_ENGINE_MAX_PARTITIONS,       /* uint32_t */
238 238
     CL_ENGINE_MAX_ICONSPE,          /* uint32_t */
239
+    CL_ENGINE_MAX_RECHWP3,          /* uint32_t */
239 240
     CL_ENGINE_TIME_LIMIT,           /* uint32_t */
240 241
     CL_ENGINE_PCRE_MATCH_LIMIT,     /* uint64_t */
241 242
     CL_ENGINE_PCRE_RECMATCH_LIMIT,  /* uint64_t */
... ...
@@ -44,6 +44,7 @@
44 44
 #define CLI_DEFAULT_MAXSCRIPTNORMALIZE  5242880
45 45
 #define CLI_DEFAULT_MAXZIPTYPERCG       1048576
46 46
 #define CLI_DEFAULT_MAXICONSPE          100
47
+#define CLI_DEFAULT_MAXRECHWP3          16
47 48
 
48 49
 #define CLI_DEFAULT_MAXPARTITIONS       50
49 50
 
... ...
@@ -464,8 +464,6 @@ struct hwp3_docsummary_entry {
464 464
 #define NUM_DOCSUMMARY_FIELDS sizeof(hwp3_docsummary_fields)/sizeof(struct hwp3_docsummary_entry)
465 465
 
466 466
 //Document Paragraph Information - (43 or 230 total bytes)
467
-#define HWP_MAX_PARAGRAPH_RECURSION 15
468
-
469 467
 #define HWP3_PARAINFO_SIZE_S  43
470 468
 #define HWP3_PARAINFO_SIZE_L  230
471 469
 #define HWP3_LINEINFO_SIZE    14
... ...
@@ -673,7 +671,7 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
673 673
     hwp3_debug("HWP3.x: recursion level: %d\n", level);
674 674
     hwp3_debug("HWP3.x: Paragraph[%d, %d] starts @ offset %llu\n", level, p, (long long unsigned)offset);
675 675
 
676
-    if (level >= HWP_MAX_PARAGRAPH_RECURSION)
676
+    if (level >= ctx->engine->maxrechwp3)
677 677
         return CL_EMAXREC;
678 678
 
679 679
     if (fmap_readn(map, &ppfs, offset+PI_PPFS, sizeof(ppfs)) != sizeof(ppfs))
... ...
@@ -444,6 +444,7 @@ struct cl_engine *cl_engine_new(void)
444 444
 
445 445
     /* Engine max settings */
446 446
     new->maxiconspe = CLI_DEFAULT_MAXICONSPE;
447
+    new->maxrechwp3 = CLI_DEFAULT_MAXRECHWP3;
447 448
 
448 449
     /* PCRE matching limitations */
449 450
 #if HAVE_PCRE
... ...
@@ -616,6 +617,9 @@ int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long
616 616
 	case CL_ENGINE_MAX_ICONSPE:
617 617
 	    engine->maxiconspe = (uint32_t)num;
618 618
 	    break;
619
+    case CL_ENGINE_MAX_RECHWP3:
620
+	    engine->maxrechwp3 = (uint32_t)num;
621
+	    break;
619 622
 	case CL_ENGINE_TIME_LIMIT:
620 623
             engine->time_limit = (uint32_t)num;
621 624
             break;
... ...
@@ -701,6 +705,8 @@ long long cl_engine_get_num(const struct cl_engine *engine, enum cl_engine_field
701 701
 	    return engine->maxpartitions;
702 702
 	case CL_ENGINE_MAX_ICONSPE:
703 703
 	    return engine->maxiconspe;
704
+    case CL_ENGINE_MAX_RECHWP3:
705
+	    return engine->maxrechwp3;
704 706
 	case CL_ENGINE_TIME_LIMIT:
705 707
             return engine->time_limit;
706 708
 	case CL_ENGINE_PCRE_MATCH_LIMIT:
... ...
@@ -820,6 +826,7 @@ struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engine)
820 820
     settings->maxpartitions = engine->maxpartitions;
821 821
 
822 822
     settings->maxiconspe = engine->maxiconspe;
823
+    settings->maxrechwp3 = engine->maxrechwp3;
823 824
 
824 825
     settings->pcre_match_limit = engine->pcre_match_limit;
825 826
     settings->pcre_recmatch_limit = engine->pcre_recmatch_limit;
... ...
@@ -892,6 +899,7 @@ int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings
892 892
     engine->maxpartitions = settings->maxpartitions;
893 893
 
894 894
     engine->maxiconspe = settings->maxiconspe;
895
+    engine->maxrechwp3 = settings->maxrechwp3;
895 896
 
896 897
     engine->pcre_match_limit = settings->pcre_match_limit;
897 898
     engine->pcre_recmatch_limit = settings->pcre_recmatch_limit;
... ...
@@ -370,6 +370,7 @@ struct cl_engine {
370 370
 
371 371
     /* Engine max settings */
372 372
     uint32_t maxiconspe; /* max number of icons to scan for PE */
373
+    uint32_t maxrechwp3; /* max recursive calls for HWP3 parsing */
373 374
 
374 375
     /* millisecond time limit for preclassification scanning */
375 376
     uint32_t time_limit;
... ...
@@ -442,6 +443,7 @@ struct cl_settings {
442 442
 
443 443
     /* Engine max settings */
444 444
     uint32_t maxiconspe; /* max number of icons to scan for PE */
445
+    uint32_t maxrechwp3; /* max recursive calls for HWP3 parsing */
445 446
 
446 447
     /* PCRE matching limitations */
447 448
     uint64_t pcre_match_limit;
... ...
@@ -382,6 +382,8 @@ const struct clam_option __clam_options[] = {
382 382
 
383 383
     { "MaxIconsPE", "max-iconspe", 0, CLOPT_TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXICONSPE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum number of icons within a PE to be scanned.\nPE files with more icons than this value will have up to the value number icons scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "100" },
384 384
 
385
+    { "MaxRecHWP3", "max-rechwp3", 0, CLOPT_TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXRECHWP3, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum recursive calls to HWP3 parsing function.\nHWP3 files using more than this limit will be terminated and alert the user.\nScans will be unable to scan any HWP3 attachments if the recursive limit is reached.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "16" },
386
+
385 387
     { "TimeLimit", "timelimit", 0, CLOPT_TYPE_NUMBER, MATCH_NUMBER, 0, NULL, 0, OPT_CLAMSCAN, "This clamscan option is currently for testing only. It sets the engine parameter CL_ENGINE_TIME_LIMIT. The value is in milliseconds.", "0" },
386 388
 
387 389
     { "PCREMatchLimit", "pcre-match-limit", 0, CLOPT_TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_PCRE_MATCH_LIMIT, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum calls to the PCRE match function during an instance of regex matching.\nInstances using more than this limit will be terminated and alert the user but the scan will continue.\nFor more information on match_limit, see the PCRE documentation.\nNegative values are not allowed.\nWARNING: setting this limit too high may severely impact performance.", "10000" },