xmin. guest@xmin ~ $
~/ $
[보안 리서치] 2026년 6월 14일

IrfanView Legacy JPM.dll 분석 회고: Integer Overflow와 Heap OOB Write

현재 IrfanView 기본 설정 영향 항목이 아닌, 비활성화된 legacy JPM.dll 플러그인 대상 퍼징 분석 회고입니다. 파일 크기 값이 할당 크기 계산과 쓰기 오프셋 계산에 함께 사용되며 heap OOB write로 이어진 케이스를 정리한 기록입니다.

irfanviewjpm.dlljpeg2000legacy-plugininteger-overflowoob-writeheapwinaflcrash-analysisvendor-not-accepted

공개 범위 메모 : 이 글은 현재 IrfanView 기본 설정에서 악용 가능한 취약점 공개가 아닙니다. 개발자 답변에 따르면 JPM.dll 플러그인은 약 2년 전부터 기본 비활성화된 legacy plugin이며, 사용자가 수동으로 활성화하고 IrfanView의 보안 경고를 무시해야만 도달 가능한 코드입니다. 따라서 본문은 현재 제품 advisory가 아니라 WinAFL 기반 파일 포맷 파서 퍼징과 크래시 분석 과정을 정리한 연구 회고로 봐야 합니다.

개발자 답변과 현재 영향 범위

제보 후 IrfanView 개발자는 해당 JPM 플러그인이 현재 IrfanView에서 기본 활성화되어 있지 않으며, 이 문제를 현재 IrfanView의 보안 취약점으로 보지 않는다고 답변했습니다. 이 내용을 반영해 본 글에서는 해당 케이스를 비활성화된 legacy 플러그인 분석 기록 으로 정리합니다.

개요

이번 케이스는 JPM 파일의 크기 필드를 검증 없이 사용하면서 발생한 integer overflow와 heap out-of-bounds write의 조합이다.

앞선 integer overflow 케이스와 비슷해 보이지만, 이 샘플에서는 파일에서 읽은 크기 값이 할당 크기 계산과 쓰기 오프셋 계산에 모두 사용된다. 따라서 작은 버퍼를 할당한 뒤, 같은 입력 값에서 파생된 큰 오프셋으로 쓰기를 시도한다.

크래시 샘플: fuzzer10id00006900EXCEPTIONACCESSVIOLATION.jpm Size: 673 bytes

크래시

Exception: Access violation (0xc0000005) Address: 0x61c1e68f Module: JPM.dll Base: 0x61bc0000

Crash instruction: mov dword ptr [eax], ecx

Write target: 0x88ce00b8

두 번의 실행에서 유사한 0x88xx00b8 패턴이 재현되어, 랜덤한 UAF보다는 입력 기반의 결정론적 주소 계산 문제로 보는 편이 자연스럽다.

호출 흐름

fuzzReadJPMW!fuzzme JPM!ReadJPMW+0x94b ShowPlugInSaveOptionsW+0x138b2 ShowPlugInSaveOptionsW+0x1a144 ShowPlugInSaveOptionsW+0x2d065 ShowPlugInSaveOptionsW+0x2cdad ShowPlugInSaveOptionsW+0x28ba3 ShowPlugInSaveOptionsW+0x1ae15 ShowPlugInSaveOptionsW+0x2fd4d ShowPlugInSaveOptionsW+0x3baae sub1005E640

핵심 함수는 sub1005E640 , 보고서 기준 JPM!ShowPlugInSaveOptionsW+0x3c460 부근이다.

원인 분석

파일에서 읽은 크기 필드는 0x200013ce 로 관찰되었다. 이 값은 이후 다음과 같은 계산에 들어간다.

allocationsize = ((size + 5) & 1) << 3

문제는 32비트 산술에서 이 계산이 오버플로우된다는 점이다.

((0x200013ce + 5) & 1) << 3 = 0x100009e90 → 32-bit truncation = 0x00009e90

결과적으로 실제 할당은 약 40KB 수준으로 축소된다.

하지만 같은 size 값은 쓰기 오프셋 계산에도 사용된다.

writeoffset = ((size + 5) & 1) 4

이 오프셋은 할당 크기보다 훨씬 크고, 최종적으로 할당 버퍼 바깥의 주소에 4바이트 쓰기가 발생한다.