Headline
CVE-2021-21871: TALOS-2021-1308 || Cisco Talos Intelligence Group
A memory corruption vulnerability exists in the DMG File Format Handler functionality of PowerISO 7.9. A specially crafted DMG file can lead to an out-of-bounds write. An attacker can provide a malicious file to trigger this vulnerability. The vendor fixed it in a bug-release of the current version.
Summary
A memory corruption vulnerability exists in the DMG File Format Handler functionality of PowerISO 7.9. A specially crafted DMG file can lead to an out-of-bounds write. An attacker can provide a malicious file to trigger this vulnerability. The vendor fixed it in a bug-release of the current version.
Tested Versions
PowerISO 7.9
Product URLs
https://www.poweriso.com/
CVSSv3 Score
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE
CWE-787 - Out-of-bounds Write
Details
PowerISO is a powerful CD/DVD/BD image file processing tool, which allows to open, extract, burn, create, edit, compress, encrypt, split and convert ISO files, and mount ISO files with an internal virtual drive. Recent versions provide support for Apple Disk Image file format (also known as DMG - file extension).
Apple Disk Image is a disk image format commonly used by the macOS operating system. This format can be structured according to one of several proprietary disk image formats, including the Universal Disk Image Format (UDIF) from Mac OS X and the New Disk Image Format (NDIF) from Mac OS 9. This format is still not officially documented by Apple. However there are various 3rd party resources that provide additional details regarding the Apple Disk Image format.
Typically, when inflating a ZLIB block inside a DMG file, the output buffer size should be limited to SECTOR_SIZE * BuffersNeeded (from the BLKXTable), but whatever the output buffer size limit is, it should be checked during the inflation operation. PowerISO, while inflating ZLIB section, does not correctly check the boundary of the output buffer. This leads to memory corruption when specifically crafted DMG file is parsed:
.text:0000000000006E73 loc_6E73: ; CODE XREF: sub_6B20+376↓j
.text:0000000000006E73 mov al, [rcx+1]
.text:0000000000006E76 add rcx, 3
.text:0000000000006E7A add r8, 3
.text:0000000000006E7E mov [r8-2], al ; memory corruption 1
.text:0000000000006E82 mov al, [rcx-1]
.text:0000000000006E85 add r11d, 0FFFFFFFDh
.text:0000000000006E89 cmp r11d, 2
.text:0000000000006E8D mov [r8-1], al
.text:0000000000006E91 mov al, [rcx]
.text:0000000000006E93 mov [r8], al ; memory corruption 2
.text:0000000000006E96 ja short loc_6E73
.text:0000000000006E98 test r11d, r11d
.text:0000000000006E9B jz short loc_6EC0
Memory for decompression function is provided here:
0x71E8: entry func init r11=dest=000000002fdd7b20
0x833E: set dest buff r11=000000002fdd7b2d
0x7F0A: before CALL buggy_inflate entry r11=dest=000000002fdd7b2d max_write=000000002fddfb2d r9=0000000000007ff3
0:000> db 0x2fdd7b2d+0x8000
00000000`2fddfb2d ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fddfb3d ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fddfb4d ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fddfb5d ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
Typical window size is 0x8000 bytes. In a malformed DMG file (malformed ZLIB section) it is possible to add a malformed DIST (waiting for distance code) or DISTEX (waiting for distance extra bits) to the ZLIB bytecode. This leads to further problems with decompression.
In a typical ZLIB implementation, after each cycle of inflate function, there is a safety check present [1]:
in -= strm->avail_in;
out -= strm->avail_out;
strm->total_in += in;
strm->total_out += out;
state->total += out;
if (state->wrap && out)
strm->adler = state->check =
UPDATE(state->check, strm->next_out - out, out);
strm->data_type = state->bits + (state->last ? 64 : 0) +
(state->mode == TYPE ? 128 : 0);
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) [1]
ret = Z_BUF_ERROR;
Typical ZLIB output when inflating our malformed file:
INFLATE
have=0 left=1637
LEN have=0 left=1637
in = 0 (strm->avail_in = 0)
out = 0 (strm->avail_out = 1637)
return ERROR Z_BUF_ERROR
Z_BUF_ERROR is returned when no progress was possible or if there was not enough room in the output buffer.
In PowerISO’s implementation the output buffer length is not verified or is not verified correctly, which leads to memory corruption.
PowerISO+0x6e7e:
00000000`00406e7e 418840fe mov byte ptr [r8-2],al ds:00000000`2fdd9000=??
0:000> db @r8-2
00000000`2fdd9000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9030 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9040 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9050 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9060 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
00000000`2fdd9070 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
Crash Information
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
KEY_VALUES_STRING: 1
Key : AV.Fault
Value: Write
Key : Analysis.CPU.Sec
Value: 1
Key : Analysis.DebugAnalysisProvider.CPP
Value: Create: 8007007e on I
Key : Analysis.DebugData
Value: CreateObject
Key : Analysis.DebugModel
Value: CreateObject
Key : Analysis.Elapsed.Sec
Value: 81
Key : Analysis.Memory.CommitPeak.Mb
Value: 108
Key : Analysis.System
Value: CreateObject
Key : Timeline.OS.Boot.DeltaSec
Value: 19890
Key : Timeline.Process.Start.DeltaSec
Value: 1513
NTGLOBALFLAG: 400
PROCESS_BAM_CURRENT_THROTTLED: 0
PROCESS_BAM_PREVIOUS_THROTTLED: 0
APPLICATION_VERIFIER_FLAGS: 0
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 0000000000406e93 (PowerISO+0x0000000000006e93)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000001
Parameter[1]: 0000000005b57000
Attempt to write to address 0000000005b57000
FAULTING_THREAD: 0000197c
PROCESS_NAME: PowerISO.exe
WRITE_ADDRESS: 0000000005b57000
ERROR_CODE: (NTSTATUS) 0xc0000005 - Instrukcja w 0x%p odwo a a si do pami ci pod adresem 0x%p. Pami nie mo e by %s.
EXCEPTION_CODE_STR: c0000005
EXCEPTION_PARAMETER1: 0000000000000001
EXCEPTION_PARAMETER2: 0000000005b57000
STACK_TEXT:
00000000`0014ddc0 00000000`00407f2a : 00000000`00008000 00000000`01010117 00000000`0000003f 00000000`00008000 : PowerISO+0x6e93
00000000`0014de40 00000000`004092fa : 00000000`00007ff3 00000000`00000000 00000000`00008000 00000000`05000401 : PowerISO+0x7f2a
00000000`0014dee0 00000000`0040afa1 : 00000000`00000000 00000000`05a1c730 00000000`00000bc0 00000000`00000000 : PowerISO+0x92fa
00000000`0014dfb0 00000000`004059a2 : 00000000`00000bc0 00000000`00001000 00000000`00010000 00000000`00010000 : PowerISO+0xafa1
00000000`0014e020 00000000`0041486a : 00000000`00000002 00000000`058de6f0 00000000`00000008 00000000`00000000 : PowerISO+0x59a2
00000000`0014e080 00000000`004167d6 : 00000000`059e3ed0 00000000`00416d44 00000000`00000028 00000000`005d115a : PowerISO+0x1486a
00000000`0014e0f0 00000000`00415b5d : 00000000`00000000 00000000`059cbe30 00000000`00000004 00000000`059e3db0 : PowerISO+0x167d6
00000000`0014e180 00000000`00417518 : 00000000`00000000 00000000`059e3db0 00000000`058de6f0 00000000`00000000 : PowerISO+0x15b5d
00000000`0014e1e0 00000000`00405ea2 : 00000000`00000028 00000000`00000000 00000000`058829a0 00000000`00000000 : PowerISO+0x17518
00000000`0014e260 00000000`004063f8 : 00000000`01188be3 00000000`12b97fcb 00000000`c0340a62 00000000`4609824c : PowerISO+0x5ea2
00000000`0014e310 00000000`005af9db : 00000000`0014e550 00000000`0014e550 00000000`00000001 00000000`02b77d4c : PowerISO+0x63f8
00000000`0014e4c0 00000000`004e507d : 00000000`0014e670 00000000`00000000 00000000`00000000 00000000`00000000 : PowerISO+0x1af9db
00000000`0014e5e0 00000000`004e5949 : 00000000`01188b17 00000000`0014e948 00000000`12b97fcb 00000000`c0340a62 : PowerISO+0xe507d
00000000`0014e910 00000000`00531da3 : 00000000`00000004 00000000`05895e8c 00000000`00000000 00000000`030cb650 : PowerISO+0xe5949
00000000`0014e940 00000000`004e09a1 : 00000000`0014ea80 00000000`00000000 00000000`00000004 00007ff9`00000002 : PowerISO+0x131da3
00000000`0014e970 00000000`005fbce5 : 00000000`00000001 00007ff9`2272c7b8 00000000`00000000 00000000`00503eec : PowerISO+0xe09a1
00000000`0014f890 00000000`005f887f : 00000000`02a50150 00000000`00613ddd 00000000`00000005 00000000`00000080 : PowerISO+0x1fbce5
00000000`0014f9c0 00000000`004e0f37 : 00000000`00000000 00000000`0010046a 00000000`030cb650 00000000`00000001 : PowerISO+0x1f887f
00000000`0014fa20 00000000`005fa008 : ffffffff`fffffffe 00000000`00000113 00000000`00000000 00000000`00000113 : PowerISO+0xe0f37
00000000`0014fa50 00000000`005fa1b6 : 00000000`008b3bc0 00000000`00c4d430 00000000`00000001 00007ff9`02000002 : PowerISO+0x1fa008
00000000`0014fb10 00007ff9`2272e858 : 00000000`008b3b60 00000000`00000113 00000000`00000001 00000000`00000000 : PowerISO+0x1fa1b6
00000000`0014fb70 00007ff9`2272e299 : 00000000`0010046a 00000000`005fa168 00000000`0010046a 00000000`00000113 : USER32!UserCallWinProcCheckWow+0x2f8
00000000`0014fd00 00000000`005f6295 : 00000000`005fa168 00000000`008b3b60 00000000`00000002 00000000`008b3b60 : USER32!DispatchMessageWorker+0x249
00000000`0014fd80 00000000`005f60d1 : 00000000`008b3b60 00000000`00400000 00000000`00000001 00000000`00000000 : PowerISO+0x1f6295
00000000`0014fdc0 00000000`005fe64f : 00000000`005c948c 00000000`00000000 00000000`00621258 00000000`00621268 : PowerISO+0x1f60d1
00000000`0014fe20 00000000`005ceeab : 00000000`00000041 00000000`00000000 00000000`00000000 00000000`00400000 : PowerISO+0x1fe64f
00000000`0014fe80 00007ff9`22dc7034 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : PowerISO+0x1ceeab
00000000`0014ff30 00007ff9`24062651 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
00000000`0014ff60 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
STACK_COMMAND: ~0s ; .cxr ; kb
SYMBOL_NAME: PowerISO+6e93
MODULE_NAME: PowerISO
IMAGE_NAME: PowerISO.exe
FAILURE_BUCKET_ID: INVALID_POINTER_WRITE_c0000005_PowerISO.exe!Unknown
OS_VERSION: 10.0.19041.1
BUILDLAB_STR: vb_release
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
FAILURE_ID_HASH: {1b12d601-7fad-79d8-d5a8-9f7caedc20c8}
Followup: MachineOwner
---------
Timeline
2021-06-05 - Vendor Disclosure
2021-06-28 - Public Release
Discovered by Piotr Bania of Cisco Talos.