... | ... |
@@ -154,6 +154,7 @@ static const char *ftypes_int[] = { |
154 | 154 |
"0:0:c771:CPIO OLD BINARY LE:CL_TYPE_ANY:CL_TYPE_CPIO_OLD:45", |
155 | 155 |
"0:0:435753:SWF (compressed):CL_TYPE_ANY:CL_TYPE_SWF:61", |
156 | 156 |
"0:0:465753:SWF (uncompressed):CL_TYPE_ANY:CL_TYPE_SWF:61", |
157 |
+ "0:0:ffd9ffd8:JPEG (bad header):CL_TYPE_ANY:CL_TYPE_GRAPHICS:61", |
|
157 | 158 |
NULL |
158 | 159 |
}; |
159 | 160 |
|
... | ... |
@@ -53,10 +53,16 @@ int cli_parsejpeg(cli_ctx *ctx) |
53 | 53 |
|
54 | 54 |
cli_dbgmsg("in cli_parsejpeg()\n"); |
55 | 55 |
|
56 |
- if(fmap_readn(map, buff, offset, 3) != 3 || memcmp(buff, "\xff\xd8\xff",3)) |
|
56 |
+ if(fmap_readn(map, buff, offset, 4) != 4) |
|
57 |
+ return CL_SUCCESS; /* Ignore */ |
|
58 |
+ |
|
59 |
+ if(!memcmp(buff, "\xff\xd8\xff", 3)) |
|
60 |
+ offset = 2; |
|
61 |
+ else if(!memcmp(buff, "\xff\xd9\xff\xd8", 4)) |
|
62 |
+ offset = 4; |
|
63 |
+ else |
|
57 | 64 |
return CL_SUCCESS; /* Not a JPEG file */ |
58 | 65 |
|
59 |
- offset = 2; |
|
60 | 66 |
while(1) { |
61 | 67 |
segment++; |
62 | 68 |
prev_marker = 0; |
... | ... |
@@ -48,6 +48,7 @@ |
48 | 48 |
#include "cltypes.h" |
49 | 49 |
#include "swf.h" |
50 | 50 |
#include "clamav.h" |
51 |
+#include "scanners.h" |
|
51 | 52 |
|
52 | 53 |
#define EC16(v) le16_to_host(v) |
53 | 54 |
#define EC32(v) le32_to_host(v) |
... | ... |
@@ -221,9 +222,9 @@ static const char *tagname(tag_id id) |
221 | 221 |
return NULL; |
222 | 222 |
} |
223 | 223 |
|
224 |
-static int dumpscan(fmap_t *map, unsigned int offset, unsigned int size, const char *obj, cli_ctx *ctx) |
|
224 |
+static int dumpscan(fmap_t *map, unsigned int offset, unsigned int size, const char *obj, int version, cli_ctx *ctx) |
|
225 | 225 |
{ |
226 |
- int newfd, ret; |
|
226 |
+ int newfd, ret = CL_CLEAN; |
|
227 | 227 |
unsigned int bread, sum = 0; |
228 | 228 |
char buff[FILEBUFF]; |
229 | 229 |
char *name; |
... | ... |
@@ -238,21 +239,54 @@ static int dumpscan(fmap_t *map, unsigned int offset, unsigned int size, const c |
238 | 238 |
} |
239 | 239 |
|
240 | 240 |
while((bread = fmap_readn(map, buff, offset, sizeof(buff))) > 0) { |
241 |
+ if(!sum && ctx->img_validate) { |
|
242 |
+ if(!memcmp(buff, "\xff\xd8", 2)) { |
|
243 |
+ cli_dbgmsg("SWF: JPEG image data\n"); |
|
244 |
+ } else if(!memcmp(buff, "\xff\xd9\xff\xd8", 4)) { |
|
245 |
+ cli_dbgmsg("SWF: JPEG image data (erroneous header)\n"); |
|
246 |
+ if(version >= 8) { |
|
247 |
+ *ctx->virname = "Heuristics.SWF.SuspectImage.A"; |
|
248 |
+ ret = CL_VIRUS; |
|
249 |
+ } |
|
250 |
+ } else if(!memcmp(buff, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8)) { |
|
251 |
+ cli_dbgmsg("SWF: PNG image data\n"); |
|
252 |
+ if(version < 8) { |
|
253 |
+ *ctx->virname = "Heuristics.SWF.SuspectImage.B"; |
|
254 |
+ ret = CL_VIRUS; |
|
255 |
+ } |
|
256 |
+ } else if(!memcmp(buff, "\x47\x49\x46\x38\x39\x61", 6)) { |
|
257 |
+ cli_dbgmsg("SWF: GIF89a image data\n"); |
|
258 |
+ if(version < 8) { |
|
259 |
+ *ctx->virname = "Heuristics.SWF.SuspectImage.C"; |
|
260 |
+ ret = CL_VIRUS; |
|
261 |
+ } |
|
262 |
+ } else { |
|
263 |
+ cli_warnmsg("SWF: Unknown image data\n"); |
|
264 |
+ *ctx->virname = "Heuristics.SWF.SuspectImage.C"; |
|
265 |
+ ret = CL_VIRUS; |
|
266 |
+ } |
|
267 |
+ if(ret == CL_VIRUS) { |
|
268 |
+ close(newfd); |
|
269 |
+ cli_unlink(name); |
|
270 |
+ free(name); |
|
271 |
+ return ret; |
|
272 |
+ } |
|
273 |
+ } |
|
241 | 274 |
if(sum + bread >= size) { |
242 | 275 |
if(cli_writen(newfd, buff, size - sum) == -1) { |
243 | 276 |
cli_errmsg("dumpscan: Can't write to %s\n", name); |
277 |
+ close(newfd); |
|
244 | 278 |
cli_unlink(name); |
245 | 279 |
free(name); |
246 |
- close(newfd); |
|
247 | 280 |
return CL_EWRITE; |
248 | 281 |
} |
249 | 282 |
break; |
250 | 283 |
} else { |
251 | 284 |
if(cli_writen(newfd, buff, bread) == -1) { |
252 | 285 |
cli_errmsg("cli_dumpscan: Can't write to %s\n", name); |
286 |
+ close(newfd); |
|
253 | 287 |
cli_unlink(name); |
254 | 288 |
free(name); |
255 |
- close(newfd); |
|
256 | 289 |
return CL_EWRITE; |
257 | 290 |
} |
258 | 291 |
} |
... | ... |
@@ -273,7 +307,7 @@ static int dumpscan(fmap_t *map, unsigned int offset, unsigned int size, const c |
273 | 273 |
} |
274 | 274 |
free(name); |
275 | 275 |
if(ctx->img_validate && ret == CL_EPARSE) { |
276 |
- *ctx->virname = "Heuristics.SWF.SuspectImage"; |
|
276 |
+ *ctx->virname = "Heuristics.SWF.SuspectImage.D"; |
|
277 | 277 |
return CL_VIRUS; |
278 | 278 |
} |
279 | 279 |
return ret; |
... | ... |
@@ -282,12 +316,11 @@ static int dumpscan(fmap_t *map, unsigned int offset, unsigned int size, const c |
282 | 282 |
int cli_scanswf(cli_ctx *ctx) |
283 | 283 |
{ |
284 | 284 |
struct swf_file_hdr file_hdr; |
285 |
- int compressed = 0; |
|
286 | 285 |
fmap_t *map = *ctx->fmap; |
287 | 286 |
unsigned int bitpos, bitbuf, getbits_n, nbits, getword_1, getword_2, getdword_1, getdword_2; |
288 | 287 |
const char *pt; |
289 | 288 |
char get_c; |
290 |
- unsigned int val, fps, foo, offset = 0, tag_hdr, tag_type, tag_len; |
|
289 |
+ unsigned int val, foo, offset = 0, tag_hdr, tag_type, tag_len; |
|
291 | 290 |
unsigned long int bits; |
292 | 291 |
|
293 | 292 |
|
... | ... |
@@ -352,7 +385,7 @@ int cli_scanswf(cli_ctx *ctx) |
352 | 352 |
|
353 | 353 |
case TAG_METADATA: |
354 | 354 |
if(tag_len) { |
355 |
- if(dumpscan(map, offset, tag_len, "Metadata", ctx) == CL_VIRUS) |
|
355 |
+ if(dumpscan(map, offset, tag_len, "Metadata", file_hdr.version, ctx) == CL_VIRUS) |
|
356 | 356 |
return CL_VIRUS; |
357 | 357 |
} |
358 | 358 |
offset += tag_len; |
... | ... |
@@ -382,7 +415,7 @@ int cli_scanswf(cli_ctx *ctx) |
382 | 382 |
GETDWORD(val); /* AlphaDataOffset */ |
383 | 383 |
if(val) { |
384 | 384 |
ctx->img_validate = 1; |
385 |
- if(dumpscan(map, offset, val, "Image", ctx) == CL_VIRUS) |
|
385 |
+ if(dumpscan(map, offset, val, "Image", file_hdr.version, ctx) == CL_VIRUS) |
|
386 | 386 |
return CL_VIRUS; |
387 | 387 |
ctx->img_validate = 0; |
388 | 388 |
} |
... | ... |
@@ -393,7 +426,7 @@ int cli_scanswf(cli_ctx *ctx) |
393 | 393 |
GETWORD(foo); /* CharacterID */ |
394 | 394 |
GETDWORD(foo); /* Reserved */ |
395 | 395 |
if(tag_len > 6) { |
396 |
- if(dumpscan(map, offset, tag_len - 6, "Binary", ctx) == CL_VIRUS) |
|
396 |
+ if(dumpscan(map, offset, tag_len - 6, "Binary", file_hdr.version, ctx) == CL_VIRUS) |
|
397 | 397 |
return CL_VIRUS; |
398 | 398 |
} |
399 | 399 |
offset += tag_len - 6; |