Root Cause Pseudo code
sub (ImageBuffer* img) {
uint16 image_height = 0xF45D; // 입력으로 준 파일 header의 height값
int16 idx = 0;
uint16 counter = 0;
do {
char* dst = (char*)get_ptr(img, idx);
memcopy(src, dst, len(src)); // crash here
++idx; // root cause (Integer Overflow)
++counter;
} while (counter < image_height); // loop condition
}
int get_ptr(ImageBuffer* img, int idx) {
return img->base_address + img->bytes_per_line * (img->height - idx - 1);
}
dst 가 img 보다 높은 주소(Heap Overflow)로 설정A vulnerability exists in the row calculation logic of the affected application, where a 16-bit unsigned integer is incorrectly cast to a 32-bit signed integer without proper bounds checking. Specifically, an unsigned short value such as 0xFD4F is assigned to a signed int, resulting in sign extension and an unexpected negative index. This erroneous index is later used in pointer arithmetic for image buffer access, leading to a large positive offset after integer wraparound. As a result, a heap-based buffer overflow occurs due to writing outside the bounds of the allocated image buffer. An attacker with control over the row index may exploit this to cause memory corruption or execute arbitrary code.
uint16 image_height, int16 start_idx, int idx 간의 Sign Extension 버그
uint16 image_height = 0xFD4F // 입력으로 준 파일 header의 height 값
int16 start_idx = image_height - 1;
int idx = start_idx; // 0xFFFFFD4E, -690
...
do {
...
--idx; // -691, -692, .., -4802(0xFFFFED3E) occurs crash in this case
} while (...);
idx가 음수로, dst를 계산하면 img→base_address에서 의도된 범위보다 높은 주소(Heap Overflow)에 write하려고 함.
최초 idx인 -690이라도 의도된(추정) 범위를 벗어나지만, idx = -4802 일 때 Access Violation 발생.
→ heap에 padding 존재할 것이라 추정.
(idx=-690일 때 그 주변 heap은 전부 0x0 으로 padding이지 않을까 싶습니다. 아니면 나중에 쓰이는거라던가..?)
위 분석을 토대로 ZDI 형식의 Report를 작성해보겠습니다.