Check mismatch in filename lengths

This commit is contained in:
atxr 2024-02-22 11:54:16 +01:00
parent e3147c10c7
commit 3122c5b76f
2 changed files with 27 additions and 17 deletions

View file

@ -6,7 +6,6 @@
#include "libmineziper_huffman_tree.h" #include "libmineziper_huffman_tree.h"
#include "libmineziper_zip.h" #include "libmineziper_zip.h"
bool detect_overlaps(char* filename);
int get_uncompressed_size(zip* in); int get_uncompressed_size(zip* in);
bool scan_zip(char* zip_data, int zip_size); bool scan_zip(char* zip_data, int zip_size);

View file

@ -5,11 +5,6 @@
#include "libmineziper.h" #include "libmineziper.h"
bool detect_overlaps(char* filename)
{
return true;
}
int get_uncompressed_size(zip* in) int get_uncompressed_size(zip* in)
{ {
int size = 0; int size = 0;
@ -29,17 +24,25 @@ bool scan_zip(char* zip_data, int zip_size)
for (int i = 0; i < zip.entries; i++) for (int i = 0; i < zip.entries; i++)
{ {
LFH* lfh = &zip.start[zip.lfh_off[i]]; LFH* lfh = zip.start + zip.lfh_off[i];
// Verify CDH/LFH parsed sizes to avoid undefined behavior
if (lfh->filename_length != zip.cdh_filename_length[i])
{
printf("[ERROR] Mismatch in CDH/LFH filename lengths.\n");
return true;
}
char* decoded_data = "";
if (lfh->compression_method == DEFLATE) if (lfh->compression_method == DEFLATE)
{ {
int lfh_length = sizeof(LFH) + lfh->filename_length + lfh->extraf_length; int lfh_length = sizeof(LFH) + lfh->filename_length + lfh->extraf_length;
char* encoded_block = &((char*) lfh)[lfh_length]; char* encoded_block = &((char*) lfh)[lfh_length];
char* decoded_data = "";
bitstream bs = init_bitstream(encoded_block, lfh->compressed_size, 0); bitstream bs = init_bitstream(encoded_block, lfh->compressed_size, 0);
ISH deflate_header = {.raw = get_bits(&bs, 3)}; ISH deflate_header = {.raw = get_bits(&bs, 3)};
// Stored block
if (deflate_header.block_type == 0) if (deflate_header.block_type == 0)
{ {
align_to_next_byte(&bs); align_to_next_byte(&bs);
@ -52,6 +55,7 @@ bool scan_zip(char* zip_data, int zip_size)
memcpy(decoded_data, &bs.data[bs.current_data_offset], block_size); memcpy(decoded_data, &bs.data[bs.current_data_offset], block_size);
} }
// Fixed Huffman Codes
else if (deflate_header.block_type == 1) else if (deflate_header.block_type == 1)
{ {
printf("[FILE %d] Scanning 1 block...\n", i); printf("[FILE %d] Scanning 1 block...\n", i);
@ -60,6 +64,7 @@ bool scan_zip(char* zip_data, int zip_size)
decode_type1_block_vuln(&bs, decoded_data); decode_type1_block_vuln(&bs, decoded_data);
} }
// Dynamic Huffman Codes
else if (deflate_header.block_type == 2) else if (deflate_header.block_type == 2)
{ {
fprintf( fprintf(
@ -68,11 +73,18 @@ bool scan_zip(char* zip_data, int zip_size)
i); i);
} }
// Invalid type
else else
{ {
fprintf(stderr, "[FILE %d] Error in compressed data\n", i); fprintf(stderr, "[FILE %d] Error in compressed data\n", i);
} }
}
else
{
fprintf(stderr, "Unknown decompression algorithm. Skipping...\n");
}
// Test the decoded data
if (strcmp("VIRUS", decoded_data) == 0) if (strcmp("VIRUS", decoded_data) == 0)
{ {
printf("-> VIRUS FOUND\n"); printf("-> VIRUS FOUND\n");
@ -83,7 +95,6 @@ bool scan_zip(char* zip_data, int zip_size)
printf("-> OK\n\n"); printf("-> OK\n\n");
} }
} }
}
return false; return false;
} }