Browse code

sigtool: Add print-certs command to allow dumping certs without a scan

David Raynor authored on 2013/03/08 09:37:37
Showing 4 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Mar 7 19:38:34 EDT 2013 (dar)
2
+------------------------------------
3
+ * sigtool: Add print-certs command to allow dumping certs without a scan
4
+
1 5
 Thu Feb 28 13:55:04 EDT 2013 (dar)
2 6
 ------------------------------------
3 7
  * libclamav/pe_icons.c: introduce LOGPARSEICONDETAILS define to reduce parseicon logging in default build
... ...
@@ -141,6 +141,7 @@ CLAMAV_PRIVATE {
141 141
     cli_initroots;
142 142
     cli_scanbuff;
143 143
     cli_fmap_scandesc;
144
+    cli_checkfp_pe;
144 145
     html_screnc_decode;
145 146
     mpool_create;
146 147
     mpool_calloc;
... ...
@@ -153,6 +154,9 @@ CLAMAV_PRIVATE {
153 153
     cli_ftw;
154 154
     cli_unlink;
155 155
     cli_writen;
156
+    SHA1Init;
157
+    SHA1Update;
158
+    SHA1Final;
156 159
     sha256_init;
157 160
     sha256_update;
158 161
     sha256_final;
... ...
@@ -105,6 +105,7 @@ const struct clam_option __clam_options[] = {
105 105
     { NULL, "sha1", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
106 106
     { NULL, "sha256", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
107 107
     { NULL, "mdb", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
108
+    { NULL, "print-certs", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
108 109
     { NULL, "html-normalise", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
109 110
     { NULL, "utf16-decode", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
110 111
     { NULL, "build", 'b', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
... ...
@@ -59,6 +59,7 @@
59 59
 #include "shared/optparser.h"
60 60
 #include "shared/misc.h"
61 61
 #include "shared/cdiff.h"
62
+#include "libclamav/sha1.h"
62 63
 #include "libclamav/sha256.h"
63 64
 #include "shared/tar.h"
64 65
 
... ...
@@ -72,9 +73,14 @@
72 72
 #include "libclamav/fmap.h"
73 73
 #include "libclamav/readdb.h"
74 74
 #include "libclamav/others.h"
75
+#include "libclamav/pe.h"
75 76
 
76 77
 #define MAX_DEL_LOOKAHEAD   5000
77 78
 
79
+//struct s_info info;
80
+short recursion = 0, bell = 0;
81
+short printinfected = 0, printclean = 1;
82
+
78 83
 static const struct dblist_s {
79 84
     const char *ext;
80 85
     unsigned int count;
... ...
@@ -2779,6 +2785,123 @@ static int makediff(const struct optstruct *opts)
2779 2779
     return 0;
2780 2780
 }
2781 2781
 
2782
+static int dumpcerts(const struct optstruct *opts)
2783
+{
2784
+    char * filename = NULL;
2785
+    STATBUF sb;
2786
+    const char * fmptr;
2787
+    SHA1Context sha1;
2788
+    struct cl_engine *engine;
2789
+    cli_ctx ctx;
2790
+    int fd, ret;
2791
+    uint8_t shash1[SHA1_HASH_SIZE];
2792
+
2793
+    logg_file = NULL;
2794
+
2795
+    filename = optget(opts, "print-certs")->strarg;
2796
+    if(!filename) {
2797
+	mprintf("!dumpcerts: No filename!\n");
2798
+        return -1;
2799
+    }
2800
+
2801
+    /* build engine */
2802
+    if(!(engine = cl_engine_new())) {
2803
+	mprintf("!dumpcerts: Can't create new engine\n");
2804
+	return -1;
2805
+    }
2806
+    cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
2807
+
2808
+    if(cli_initroots(engine, 0) != CL_SUCCESS) {
2809
+	mprintf("!dumpcerts: cli_initroots() failed\n");
2810
+	cl_engine_free(engine);
2811
+	return -1;
2812
+    }
2813
+
2814
+    if(cli_parse_add(engine->root[0], "test", "deadbeef", 0, 0, "*", 0, NULL, 0) != CL_SUCCESS) {
2815
+	mprintf("!dumpcerts: Can't parse signature\n");
2816
+	cl_engine_free(engine);
2817
+	return -1;
2818
+    }
2819
+
2820
+    if(cl_engine_compile(engine) != CL_SUCCESS) {
2821
+	mprintf("!dumpcerts: Can't compile engine\n");
2822
+	cl_engine_free(engine);
2823
+	return -1;
2824
+    }
2825
+
2826
+    engine->dconf->pe |= PE_CONF_DUMPCERT;
2827
+    cl_debug();
2828
+
2829
+    /* prepare context */
2830
+    memset(&ctx, '\0', sizeof(cli_ctx));
2831
+    ctx.engine = engine;
2832
+    ctx.options = CL_SCAN_STDOPT;
2833
+    ctx.container_type = CL_TYPE_ANY;
2834
+    ctx.dconf = (struct cli_dconf *) engine->dconf;
2835
+    ctx.fmap = calloc(sizeof(fmap_t *), 1);
2836
+    if(!ctx.fmap) {
2837
+	cl_engine_free(engine);
2838
+	return -1;
2839
+    }
2840
+
2841
+    /* Prepare file */
2842
+    fd = open(filename, O_RDONLY);
2843
+    if(fd < 0) {
2844
+	mprintf("!dumpcerts: Can't open file %s!\n", filename);
2845
+        cl_engine_free(engine);
2846
+        return -1;
2847
+    }
2848
+
2849
+    lseek(fd, 0, SEEK_SET);
2850
+    FSTAT(fd, &sb);
2851
+    if(!(*ctx.fmap = fmap(fd, 0, sb.st_size))) {
2852
+	free(ctx.fmap);
2853
+	close(fd);
2854
+	cl_engine_free(engine);
2855
+	return -1;
2856
+    }
2857
+
2858
+    fmptr = fmap_need_off_once(*ctx.fmap, 0, sb.st_size);
2859
+    if(!fmptr) {
2860
+        mprintf("!dumpcerts: fmap_need_off_once failed!\n");
2861
+        free(ctx.fmap);
2862
+        close(fd);
2863
+        cl_engine_free(engine);
2864
+	return -1;
2865
+    }
2866
+
2867
+    /* Generate SHA1 */
2868
+    SHA1Init(&sha1);
2869
+    SHA1Update(&sha1, fmptr, sb.st_size);
2870
+    SHA1Final(&sha1, shash1);
2871
+
2872
+    ret = cli_checkfp_pe(&ctx, shash1);
2873
+    
2874
+    switch(ret) {
2875
+        case CL_CLEAN:
2876
+            mprintf("*dumpcerts: CL_CLEAN after cli_checkfp_pe()!\n");
2877
+            break;
2878
+        case CL_VIRUS:
2879
+            mprintf("*dumpcerts: CL_VIRUS after cli_checkfp_pe()!\n");
2880
+            break;
2881
+        case CL_BREAK:
2882
+            mprintf("*dumpcerts: CL_BREAK after cli_checkfp_pe()!\n");
2883
+            break;
2884
+        case CL_EFORMAT:
2885
+            mprintf("!dumpcerts: Not a valid PE file!\n");
2886
+            break;
2887
+        default:
2888
+            mprintf("!dumpcerts: Other error %d inside cli_checkfp_pe.\n", ret);
2889
+            break;
2890
+    }
2891
+
2892
+    /* Cleanup */
2893
+    free(ctx.fmap);
2894
+    close(fd);
2895
+    cl_engine_free(engine);
2896
+    return 0;
2897
+}
2898
+
2782 2899
 static void help(void)
2783 2900
 {
2784 2901
     mprintf("\n");
... ...
@@ -2806,6 +2929,7 @@ static void help(void)
2806 2806
     mprintf("    --build=NAME [cvd] -b NAME             build a CVD file\n");
2807 2807
     mprintf("    --no-cdiff                             Don't generate .cdiff file\n");
2808 2808
     mprintf("    --unsigned                             Create unsigned database file (.cud)\n");
2809
+    mprintf("    --print-certs=FILE                     Print Authenticode details from a PE\n");
2809 2810
     mprintf("    --server=ADDR                          ClamAV Signing Service address\n");
2810 2811
     mprintf("    --datadir=DIR				Use DIR as default database directory\n");
2811 2812
     mprintf("    --unpack=FILE          -u FILE         Unpack a CVD/CLD file\n");
... ...
@@ -2903,6 +3027,8 @@ int main(int argc, char **argv)
2903 2903
 	ret = makediff(opts);
2904 2904
     else if(optget(opts, "compare")->enabled)
2905 2905
 	ret = compareone(opts);
2906
+    else if(optget(opts, "print-certs")->enabled)
2907
+	ret = dumpcerts(opts);
2906 2908
     else if(optget(opts, "run-cdiff")->enabled)
2907 2909
 	ret = rundiff(opts);
2908 2910
     else if(optget(opts, "verify-cdiff")->enabled) {