... | ... |
@@ -1334,11 +1334,11 @@ static int cli_scanscrenc(cli_ctx *ctx) |
1334 | 1334 |
return ret; |
1335 | 1335 |
} |
1336 | 1336 |
|
1337 |
-static int cli_scanriff(int desc, cli_ctx *ctx) |
|
1337 |
+static int cli_scanriff(cli_ctx *ctx) |
|
1338 | 1338 |
{ |
1339 | 1339 |
int ret = CL_CLEAN; |
1340 | 1340 |
|
1341 |
- if(cli_check_riff_exploit(desc) == 2) { |
|
1341 |
+ if(cli_check_riff_exploit(ctx) == 2) { |
|
1342 | 1342 |
ret = CL_VIRUS; |
1343 | 1343 |
*ctx->virname = "Heuristics.Exploit.W32.MS05-002"; |
1344 | 1344 |
} |
... | ... |
@@ -2343,7 +2343,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2343 | 2343 |
|
2344 | 2344 |
case CL_TYPE_RIFF: |
2345 | 2345 |
if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_RIFF)) |
2346 |
- ret = cli_scanriff(desc, ctx); |
|
2346 |
+ ret = cli_scanriff(ctx); |
|
2347 | 2347 |
break; |
2348 | 2348 |
|
2349 | 2349 |
case CL_TYPE_GRAPHICS: |
... | ... |
@@ -2393,6 +2393,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2393 | 2393 |
break; |
2394 | 2394 |
|
2395 | 2395 |
case CL_TYPE_BINARY_DATA: |
2396 |
+ case CL_TYPE_TEXT_UTF16BE: |
|
2396 | 2397 |
if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_MYDOOMLOG)) |
2397 | 2398 |
ret = cli_check_mydoom_log(ctx); |
2398 | 2399 |
break; |
... | ... |
@@ -47,7 +47,8 @@ |
47 | 47 |
|
48 | 48 |
int cli_check_mydoom_log(cli_ctx *ctx) |
49 | 49 |
{ |
50 |
- uint32_t *record, check, key; |
|
50 |
+ const uint32_t *record; |
|
51 |
+ uint32_t check, key; |
|
51 | 52 |
fmap_t *map = *ctx->fmap; |
52 | 53 |
unsigned int blocks = map->len / (8*4); |
53 | 54 |
|
... | ... |
@@ -258,103 +259,85 @@ static uint32_t riff_endian_convert_32(uint32_t value, int big_endian) |
258 | 258 |
return le32_to_host(value); |
259 | 259 |
} |
260 | 260 |
|
261 |
-static int riff_read_chunk(int fd, int big_endian, int rec_level) |
|
261 |
+static int riff_read_chunk(fmap_t *map, off_t *offset, int big_endian, int rec_level) |
|
262 | 262 |
{ |
263 |
- uint32_t chunk_id; |
|
263 |
+ const uint32_t *buf; |
|
264 | 264 |
uint32_t chunk_size; |
265 |
- int length; |
|
266 |
- uint32_t list_type; |
|
267 |
- off_t offset, cur_offset; |
|
265 |
+ off_t cur_offset = *offset; |
|
268 | 266 |
|
269 | 267 |
if (rec_level > 1000) { |
270 | 268 |
cli_dbgmsg("riff_read_chunk: recursion level exceeded\n"); |
271 | 269 |
return 0; |
272 | 270 |
} |
273 |
- |
|
274 |
- length = sizeof(uint32_t); |
|
275 |
- if (cli_readn(fd, &chunk_id, length) != length) { |
|
276 |
- return 0; |
|
277 |
- } |
|
278 |
- if (cli_readn(fd, &chunk_size, length) != length) { |
|
279 |
- return 0; |
|
280 |
- } |
|
281 |
- chunk_size = riff_endian_convert_32(chunk_size, big_endian); |
|
282 | 271 |
|
283 |
- if(!memcmp(&chunk_id, "anih", 4) && chunk_size != 36) |
|
272 |
+ if(!(buf = fmap_need_off_once(map, cur_offset, 4*2))) |
|
273 |
+ return 0; |
|
274 |
+ cur_offset += 4*2; |
|
275 |
+ chunk_size = riff_endian_convert_32(buf[1], big_endian); |
|
276 |
+ |
|
277 |
+ if(!memcmp(buf, "anih", 4) && chunk_size != 36) |
|
284 | 278 |
return 2; |
285 | 279 |
|
286 |
- if (memcmp(&chunk_id, "RIFF", 4) == 0) { |
|
280 |
+ if (memcmp(buf, "RIFF", 4) == 0) { |
|
287 | 281 |
return 0; |
288 |
- } else if (memcmp(&chunk_id, "RIFX", 4) == 0) { |
|
282 |
+ } else if (memcmp(buf, "RIFX", 4) == 0) { |
|
289 | 283 |
return 0; |
290 | 284 |
} |
291 | 285 |
|
292 |
- if ((memcmp(&chunk_id, "LIST", 4) == 0) || |
|
293 |
- (memcmp(&chunk_id, "PROP", 4) == 0) || |
|
294 |
- (memcmp(&chunk_id, "FORM", 4) == 0) || |
|
295 |
- (memcmp(&chunk_id, "CAT ", 4) == 0)) { |
|
296 |
- if (cli_readn(fd, &list_type, sizeof(list_type)) != sizeof(list_type)) { |
|
286 |
+ if ((memcmp(buf, "LIST", 4) == 0) || |
|
287 |
+ (memcmp(buf, "PROP", 4) == 0) || |
|
288 |
+ (memcmp(buf, "FORM", 4) == 0) || |
|
289 |
+ (memcmp(buf, "CAT ", 4) == 0)) { |
|
290 |
+ if (!fmap_need_ptr_once(map, buf+2, 4)) { |
|
297 | 291 |
cli_dbgmsg("riff_read_chunk: read list type failed\n"); |
298 | 292 |
return 0; |
299 | 293 |
} |
300 |
- return riff_read_chunk(fd, big_endian, ++rec_level); |
|
294 |
+ *offset = cur_offset+4; |
|
295 |
+ return riff_read_chunk(map, offset, big_endian, ++rec_level); |
|
301 | 296 |
} |
302 | 297 |
|
303 |
- cur_offset = lseek(fd, 0, SEEK_CUR); |
|
304 |
- offset = cur_offset + chunk_size; |
|
305 |
- /* Check for odd alignment */ |
|
306 |
- if ((offset & 0x01) == 1) { |
|
307 |
- offset++; |
|
308 |
- } |
|
309 |
- if (offset < cur_offset) { |
|
298 |
+ *offset = cur_offset + chunk_size + (chunk_size&1); |
|
299 |
+ if (*offset < cur_offset) { |
|
310 | 300 |
return 0; |
311 | 301 |
} |
302 |
+ /* FIXME: WTF!? |
|
312 | 303 |
if (lseek(fd, offset, SEEK_SET) != offset) { |
313 | 304 |
return 2; |
314 | 305 |
} |
306 |
+ */ |
|
315 | 307 |
return 1; |
316 | 308 |
} |
317 | 309 |
|
318 |
-int cli_check_riff_exploit(int fd) |
|
310 |
+int cli_check_riff_exploit(cli_ctx *ctx) |
|
319 | 311 |
{ |
320 |
- uint32_t chunk_id; |
|
321 |
- uint32_t chunk_size; |
|
322 |
- uint32_t form_type; |
|
323 |
- int length, big_endian, retval; |
|
312 |
+ const uint32_t *buf; |
|
313 |
+ int big_endian, retval; |
|
324 | 314 |
off_t offset; |
315 |
+ fmap_t *map = *ctx->fmap; |
|
325 | 316 |
|
326 | 317 |
cli_dbgmsg("in cli_check_riff_exploit()\n"); |
327 | 318 |
|
328 |
- length = sizeof(uint32_t); |
|
329 |
- if (cli_readn(fd, &chunk_id, length) != length) { |
|
330 |
- return 0; |
|
331 |
- } |
|
332 |
- if (cli_readn(fd, &chunk_size, length) != length) { |
|
333 |
- return 0; |
|
334 |
- } |
|
335 |
- if (cli_readn(fd, &form_type, length) != length) { |
|
336 |
- return 0; |
|
337 |
- } |
|
338 |
- |
|
339 |
- if (memcmp(&chunk_id, "RIFF", 4) == 0) { |
|
319 |
+ if(!(buf = fmap_need_off_once(map, 0, 4*3))) |
|
320 |
+ return 0; |
|
321 |
+ |
|
322 |
+ if (memcmp(buf, "RIFF", 4) == 0) { |
|
340 | 323 |
big_endian = FALSE; |
341 |
- } else if (memcmp(&chunk_id, "RIFX", 4) == 0) { |
|
324 |
+ } else if (memcmp(buf, "RIFX", 4) == 0) { |
|
342 | 325 |
big_endian = TRUE; |
343 | 326 |
} else { |
344 | 327 |
/* Not a RIFF file */ |
345 | 328 |
return 0; |
346 | 329 |
} |
347 | 330 |
|
348 |
- if (memcmp(&form_type, "ACON", 4) != 0) { |
|
331 |
+ if (memcmp(&buf[2], "ACON", 4) != 0) { |
|
349 | 332 |
/* Only scan MS animated icon files */ |
350 | 333 |
/* There is a *lot* of broken software out there that produces bad RIFF files */ |
351 | 334 |
return 0; |
352 | 335 |
} |
353 | 336 |
|
354 |
- chunk_size = riff_endian_convert_32(chunk_size, big_endian); |
|
355 |
- |
|
337 |
+ offset = 4*3; |
|
356 | 338 |
do { |
357 |
- retval = riff_read_chunk(fd, big_endian, 1); |
|
339 |
+ retval = riff_read_chunk(map, &offset, big_endian, 1); |
|
358 | 340 |
} while (retval == 1); |
359 | 341 |
|
360 | 342 |
return retval; |
... | ... |
@@ -35,7 +35,7 @@ struct swizz_stats { |
35 | 35 |
|
36 | 36 |
int cli_check_mydoom_log(cli_ctx *ctx); |
37 | 37 |
int cli_check_jpeg_exploit(int fd, cli_ctx *ctx); |
38 |
-int cli_check_riff_exploit(int fd); |
|
38 |
+int cli_check_riff_exploit(cli_ctx *ctx); |
|
39 | 39 |
void cli_detect_swizz_str(const unsigned char *str, uint32_t len, struct swizz_stats *stats, int blob); |
40 | 40 |
int cli_detect_swizz(struct swizz_stats *stats); |
41 | 41 |
|