Browse code

credit card detection fixes

git-svn: trunk@4150

Tomasz Kojm authored on 2008/08/29 19:32:33
Showing 7 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Aug 29 12:29:32 CEST 2008 (tk)
2
+----------------------------------
3
+  * libclamav/dlp.c: credit card detection fixes
4
+  * clamd, clamscan: minCC and minSSN counts now set by default to 3
5
+
1 6
 Fri Aug 29 02:46:19 CEST 2008 (acab)
2 7
 ------------------------------------
3 8
   * clamav-milter: Add option "--no-check-cf" to bypass sendmail.cf sanity
... ...
@@ -582,12 +582,12 @@ int scanmanager(const struct optstruct *opt)
582 582
 	if(opt_check(opt, "structured-ssn-count"))
583 583
 	    limits.min_ssn_count = atoi(opt_arg(opt, "structured-ssn-count"));
584 584
 	else
585
-	    limits.min_ssn_count = 1;
585
+	    limits.min_ssn_count = 3;
586 586
 
587 587
 	if(opt_check(opt, "structured-cc-count"))
588 588
 	    limits.min_cc_count = atoi(opt_arg(opt, "structured-cc-count"));
589 589
 	else
590
-	    limits.min_cc_count = 1;
590
+	    limits.min_cc_count = 3;
591 591
 
592 592
     } else
593 593
 	options &= ~CL_SCAN_STRUCTURED;
... ...
@@ -296,12 +296,12 @@ Default: no
296 296
 \fBStructuredMinCreditCardCount NUMBER\fR
297 297
 This option sets the lowest number of Credit Card numbers found in a file to generate a detect.
298 298
 .br 
299
-Default: 1
299
+Default: 3
300 300
 .TP
301 301
 \fBStructuredMinSSNCount NUMBER\fR
302 302
 This option sets the lowest number of Social Security Numbers found in a file to generate a detect.
303 303
 .br 
304
-Default: 1
304
+Default: 3
305 305
 .TP
306 306
 \fBStructuredSSNFormatNormal BOOL\fR
307 307
 With this option enabled the DLP module will search for valid SSNs formatted as xxx-yy-zzzz.
... ...
@@ -85,10 +85,10 @@ Enable the DLP (Data Loss Prevention) module which provides detection of SSN and
85 85
 X=0: search for valid SSNs formatted as xxx-yy-zzzz (normal); X=1: search for valid SSNs formatted as xxxyyzzzz (stripped); X=2: default: search for both formats.
86 86
 .TP 
87 87
 \fB\-\-structured\-ssn\-count=#n\fR
88
-This option sets the lowest number of Social Security Numbers found in a file to generate a detect (default: 1).
88
+This option sets the lowest number of Social Security Numbers found in a file to generate a detect (default: 3).
89 89
 .TP 
90 90
 \fB\-\-structured\-cc\-count=#n\fR
91
-This option sets the lowest number of Credit Card numbers found in a file to generate a detect (default: 1).
91
+This option sets the lowest number of Credit Card numbers found in a file to generate a detect (default: 3).
92 92
 .TP 
93 93
 \fB\-\-no\-mail\fR
94 94
 Disable scanning of mail files.
... ...
@@ -298,12 +298,12 @@ LocalSocket /tmp/clamd.socket
298 298
 
299 299
 # This option sets the lowest number of Credit Card numbers found in a file
300 300
 # to generate a detect.
301
-# Default: 1
301
+# Default: 3
302 302
 #StructuredMinCreditCardCount 5
303 303
 
304 304
 # This option sets the lowest number of Social Security Numbers found
305 305
 # in a file to generate a detect.
306
-# Default: 1
306
+# Default: 3
307 307
 #StructuredMinSSNCount 5
308 308
 
309 309
 # With this option enabled the DLP module will search for valid
... ...
@@ -30,6 +30,7 @@
30 30
 #include <stdarg.h>
31 31
 #include <stdlib.h>
32 32
 #include "dlp.h"
33
+#include "others.h"
33 34
 
34 35
 /* detection mode macros for the contains_* functions */
35 36
 #define DETECT_MODE_DETECT  0
... ...
@@ -115,34 +116,36 @@ static int ssn_max_group[MAX_AREA+1] = { 0,
115 115
 
116 116
 int dlp_is_valid_cc(const unsigned char *buffer, int length)
117 117
 {
118
-    int even = 0;
118
+    int even = 1;
119 119
     int sum = 0;
120 120
     int i = 0;
121 121
     int val = 0;
122 122
     int digits = 0;
123
-    char prefix[4];
123
+    char cc_digits[20];
124 124
     
125 125
     if(buffer == NULL || length < 13)
126 126
         return 0;
127
-
128 127
     /* if the first digit is greater than 6 it isn't one of the major
129 128
      * credit cards
130 129
      * reference => http://www.beachnet.com/~hstiles/cardtype.html
131 130
      */
132
-    if(buffer[0] > '6' || buffer[0] == 0)
131
+    if(!isdigit(buffer[0]) || buffer[0] > '6')
133 132
         return 0;
134 133
         
135 134
     if(length > 19)
136 135
         length = 19;
137 136
 
138
-    for(i = length - 1; i > -1; i--)
137
+    for(i = 0; i < length; i++)
139 138
     {
140 139
         if(isdigit(buffer[i]) == 0)
141
-            continue;
142
-
143
-	if(digits < 4)
144
-	    prefix[digits] = buffer[i];
140
+	{
141
+	    if(isspace(buffer[i]))
142
+		continue;
143
+	    else
144
+		break;
145
+	}
145 146
 
147
+	cc_digits[digits] = buffer[i];
146 148
 	digits++;
147 149
         val = buffer[i] - '0';
148 150
         
... ...
@@ -154,57 +157,70 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
154 154
         even = !even;
155 155
         sum += val;
156 156
     }
157
+    cc_digits[digits] = 0;
157 158
 
158 159
     if((sum % 10 != 0) || (digits < 13))
159 160
 	return 0;
160 161
 
161 162
     if(digits == 13) /* VISA */
162 163
     {
163
-	if(prefix[0] == '4')
164
+	if(cc_digits[0] == '4') {
165
+	    cli_dbgmsg("dlp_is_valid_cc: VISA [1] (%s)\n", cc_digits);
164 166
 	    return 1;
167
+	}
165 168
     }
166 169
     else if(digits == 14) /* Diners Club */
167 170
     {
168
-	if(prefix[0] == '3' && (prefix[1] == '6' || prefix[1] == '8'))
171
+	if(cc_digits[0] == '3' && (cc_digits[1] == '6' || cc_digits[1] == '8'))
169 172
 	{
173
+	    cli_dbgmsg("dlp_is_valid_cc: Diners Club [1] (%s)\n", cc_digits);
170 174
 	    return 1;
171 175
 	}
172
-	else if(prefix[0] == '3' && prefix[1] == '0')
176
+	else if(cc_digits[0] == '3' && cc_digits[1] == '0')
173 177
 	{
174
-	    val = prefix[2] - '0';
175
-	    if(val >= 0 && val <= 5)
178
+	    val = cc_digits[2] - '0';
179
+	    if(val >= 0 && val <= 5) {
180
+		cli_dbgmsg("dlp_is_valid_cc: Diners Club [2] (%s)\n", cc_digits);
176 181
 		return 1;
182
+	    }
177 183
 	}
178 184
     }
179 185
     else if(digits == 15)
180 186
     {
181
-	if(prefix[0] == '3' && (prefix[1] == '4' || prefix[1] == '7')) /*AMEX*/
187
+	if(cc_digits[0] == '3' && (cc_digits[1] == '4' || cc_digits[1] == '7')) /*AMEX*/
182 188
 	{
189
+	    cli_dbgmsg("dlp_is_valid_cc: AMEX (%s)\n", cc_digits);
183 190
 	    return 1;
184 191
 	}
185
-	else if(!strncmp(prefix, "2131", 4) || !strncmp(prefix, "1800", 4))
192
+	else if(!strncmp(cc_digits, "2131", 4) || !strncmp(cc_digits, "1800", 4))
186 193
 	{ /* JCB  */
194
+	    cli_dbgmsg("dlp_is_valid_cc: JCB [1] (%s)\n", cc_digits);
187 195
 	    return 1;
188 196
 	}
189 197
     }
190 198
     else if(digits == 16)
191 199
     {
192
-	if(prefix[0] == '3') /* JCB */
200
+	if(cc_digits[0] == '3') /* JCB */
193 201
 	{
202
+	    cli_dbgmsg("dlp_is_valid_cc: JCB [2] (%s)\n", cc_digits);
194 203
 	    return 1;
195 204
 	}
196
-	else if(prefix[0] == '4') /* VISA */
205
+	else if(cc_digits[0] == '4') /* VISA */
197 206
 	{
207
+	    cli_dbgmsg("dlp_is_valid_cc: VISA [2] (%s)\n", cc_digits);
198 208
 	    return 1;
199 209
 	}
200
-	else if(prefix[0] == '5') /* MASTERCARD */
210
+	else if(cc_digits[0] == '5') /* MASTERCARD */
201 211
 	{
202
-	    val = prefix[1] - '0';
203
-	    if(val >= 1 && val <= 5)
212
+	    val = cc_digits[1] - '0';
213
+	    if(val >= 1 && val <= 5) {
214
+		cli_dbgmsg("dlp_is_valid_cc: MASTERCARD (%s)\n", cc_digits);
204 215
 		return 1;
216
+	    }
205 217
 	}
206
-	else if(!strncmp(prefix, "6011", 4)) /* Discover */
218
+	else if(!strncmp(cc_digits, "6011", 4)) /* Discover */
207 219
 	{
220
+	    cli_dbgmsg("dlp_is_valid_cc: Discover (%s)\n", cc_digits);
208 221
 	    return 1;
209 222
 	} 
210 223
     }
... ...
@@ -59,8 +59,8 @@ struct cfgoption cfg_options[] = {
59 59
     {"ExcludePUA", OPT_QUOTESTR, -1, NULL, 1, OPT_CLAMD},
60 60
     {"IncludePUA", OPT_QUOTESTR, -1, NULL, 1, OPT_CLAMD},
61 61
     {"StructuredDataDetection", OPT_BOOL, 0, NULL, 0, OPT_CLAMD},
62
-    {"StructuredMinCreditCardCount", OPT_NUM, 1, NULL, 0, OPT_CLAMD},
63
-    {"StructuredMinSSNCount", OPT_NUM, 1, NULL, 0, OPT_CLAMD},
62
+    {"StructuredMinCreditCardCount", OPT_NUM, 3, NULL, 0, OPT_CLAMD},
63
+    {"StructuredMinSSNCount", OPT_NUM, 3, NULL, 0, OPT_CLAMD},
64 64
     {"StructuredSSNFormatNormal", OPT_BOOL, 1, NULL, 0, OPT_CLAMD},
65 65
     {"StructuredSSNFormatStripped", OPT_BOOL, 1, NULL, 0, OPT_CLAMD},
66 66
     {"AlgorithmicDetection", OPT_BOOL, 1, NULL, 0, OPT_CLAMD},