Browse code

Merge fix from security/bb11155 branch

Shawn Webb authored on 2014/11/07 04:44:53
Showing 1 changed files
... ...
@@ -737,14 +737,14 @@ int cli_scanpe(cli_ctx *ctx)
737 737
 	char sname[9], epbuff[4096], *tempfile;
738 738
 	uint32_t epsize;
739 739
 	ssize_t bytes, at;
740
-	unsigned int i, found, upx_success = 0, min = 0, max = 0, err, overlays = 0;
740
+	unsigned int i, j, found, upx_success = 0, min = 0, max = 0, err, overlays = 0, rescan = 1;
741 741
 	unsigned int ssize = 0, dsize = 0, dll = 0, pe_plus = 0, corrupted_cur;
742 742
 	int (*upxfn)(const char *, uint32_t, char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL;
743 743
 	const char *src = NULL;
744 744
 	char *dest = NULL;
745 745
 	int ndesc, ret = CL_CLEAN, upack = 0, native=0;
746 746
 	size_t fsize;
747
-	uint32_t valign, falign, hdr_size, j;
747
+	uint32_t valign, falign, hdr_size;
748 748
 	struct cli_exe_section *exe_sections;
749 749
 	char timestr[32];
750 750
 	struct pe_image_data_dir *dirs;
... ...
@@ -1238,18 +1238,52 @@ int cli_scanpe(cli_ctx *ctx)
1238 1238
     cli_jsonint(pe_json, "NumberOfSections", nsections);
1239 1239
 #endif
1240 1240
 
1241
+    while (rescan==1) {
1242
+        rescan=0;
1243
+        for (i=0; i < nsections; i++) {
1244
+            exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
1245
+            exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
1246
+            exe_sections[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
1247
+            exe_sections[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
1248
+            exe_sections[i].chr = EC32(section_hdr[i].Characteristics);
1249
+            exe_sections[i].urva = EC32(section_hdr[i].VirtualAddress); /* Just in case */
1250
+            exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize);
1251
+            exe_sections[i].uraw = EC32(section_hdr[i].PointerToRawData);
1252
+            exe_sections[i].ursz = EC32(section_hdr[i].SizeOfRawData);
1253
+
1254
+            if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
1255
+                if (!CLI_ISCONTAINED(0, fsize, exe_sections[i].uraw, exe_sections[i].ursz)
1256
+                    || exe_sections[i].raw >= fsize) {
1257
+                    cli_dbgmsg("Broken PE file - Section %d starts or exists beyond the end of file (Offset@ %lu, Total filesize %lu)\n", i, (unsigned long)exe_sections[i].raw, (unsigned long)fsize);
1258
+                    if (nsections == 1) {
1259
+                        free(section_hdr);
1260
+                        free(exe_sections);
1261
+
1262
+                        if(DETECT_BROKEN_PE) {
1263
+                            cli_append_virus(ctx, "Heuristics.Broken.Executable");
1264
+                            return CL_VIRUS;
1265
+                        }
1266
+
1267
+                        return CL_CLEAN; /* no ninjas to see here! move along! */
1268
+                    }
1269
+
1270
+                    for (j=i; j < nsections-1; j++)
1271
+                        memcpy(&exe_sections[j], &exe_sections[j+1], sizeof(struct cli_exe_section));
1272
+
1273
+                    for (j=i; j < nsections-1; j++)
1274
+                        memcpy(&section_hdr[j], &section_hdr[j+1], sizeof(struct pe_image_section_hdr));
1275
+
1276
+                    nsections--;
1277
+                    rescan=1;
1278
+                    break;
1279
+                }
1280
+            }
1281
+        }
1282
+    }
1283
+
1241 1284
     for(i = 0; i < nsections; i++) {
1242
-	strncpy(sname, (char *) section_hdr[i].Name, 8);
1243
-	sname[8] = 0;
1244
-	exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
1245
-	exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
1246
-	exe_sections[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
1247
-	exe_sections[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
1248
-	exe_sections[i].chr = EC32(section_hdr[i].Characteristics);
1249
-	exe_sections[i].urva = EC32(section_hdr[i].VirtualAddress); /* Just in case */
1250
-	exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize);
1251
-	exe_sections[i].uraw = EC32(section_hdr[i].PointerToRawData);
1252
-	exe_sections[i].ursz = EC32(section_hdr[i].SizeOfRawData);
1285
+        strncpy(sname, (char *) section_hdr[i].Name, 8);
1286
+        sname[8] = 0;
1253 1287
 
1254 1288
 #if HAVE_JSON
1255 1289
         add_section_info(ctx, &exe_sections[i]);
... ...
@@ -1304,18 +1338,6 @@ int cli_scanpe(cli_ctx *ctx)
1304 1304
 	}
1305 1305
 
1306 1306
 	if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
1307
-	    if (exe_sections[i].raw >= fsize) { /* really broken */
1308
-	      cli_dbgmsg("Broken PE file - Section %d starts beyond the end of file (Offset@ %lu, Total filesize %lu)\n", i, (unsigned long)exe_sections[i].raw, (unsigned long)fsize);
1309
-	      cli_dbgmsg("------------------------------------\n");
1310
-		free(section_hdr);
1311
-		free(exe_sections);
1312
-		if(DETECT_BROKEN_PE) {
1313
-		    cli_append_virus(ctx, "Heuristics.Broken.Executable");
1314
-		    return CL_VIRUS;
1315
-		}
1316
-		return CL_CLEAN; /* no ninjas to see here! move along! */
1317
-	    }
1318
-
1319 1307
 	    if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
1320 1308
 
1321 1309
 	    /* check hash section sigs */