XnView MBM Processing Heap Overflow

XnView MBM Processing Heap Overflow

1. Advisory Information

Title: XnView MBM Processing Heap Overflow
Advisory Id: CORE-2010-0514
Advisory URL: http://www.coresecurity.com/content/xnview-mbm-heap-overflow
Date published: 2010-06-14
Date of last update: 2010-06-14
Vendors contacted: XnView
Release mode: Coordinated release

2. Vulnerability Information

Class: Buffer overflow [CWE-119]
Impact: Code execution
Remotely Exploitable: Yes (client-side)
Locally Exploitable: No
CVE Name: N/A
Bugtraq ID: N/A

3. Vulnerability Description

XnView [1] is prone to a security vulnerability when processing MBM files. This vulnerability could be exploited by a remote attacker to execute arbitrary code on the target machine, by enticing the user of XnView to open a specially crafted file.

4. Vulnerable packages

  • XnView 1.97.4
  • Older versions are probably affected too, but they were not checked.

5. Non-vulnerable packages

  • XnView 1.97.5

6. Vendor Information, Solutions and Workarounds

Update to the latest version of XnView, available on the website http://www.xnview.com/

7. Credits

This vulnerability was discovered by Mauro Olea and researched by Mauro Olea and Nahuel Riva from Core Security Technologies. Publication of this advisory was coordinated by Carlos Sarraute from Core Security Advisories team.

8. Technical Description / Proof of Concept Code

XnView is prone to a security vulnerability when processing MBM files. The version used in our tests in XnView 1.97.4 running on Windows 2000 SP4. By enticing the user of XnView to open a specially crafted file, a remote attacker may exploit this vulnerability to gain arbitrary code execution.

The MBM file format (shortened from MultiBitMap) is a container for a set of bitmap images. MBM files are used by most Symbian applications to store their graphical content. MBM files can be created with the BMCONV tool which is supplied with any Symbian (and EPOC) SDK.

8.1. First Proof-of-Concept

An MBM file that triggers this vulnerability is available at [2]. The following is an excerpt of the vulnerable code, and the value of the registers when the vulnerability is triggered (the value of EAX and ECX are controlled by the attacker).

77FCC453   . 8901           MOV DWORD PTR DS:[ECX],EAX
77FCC455   . 8948 04        MOV DWORD PTR DS:[EAX+4],ECX
77FCC458   . 3BC1           CMP EAX,ECX
77FCC45A   . 75 25          JNZ SHORT ntdll.77FCC481



EAX 7A7A7A7A
ECX 7A7A7A7A
EDX 00000000
EBX 00000003
ESP 0171ED64
EBP 0171EEFC
ESI 013579F0 ASCII
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
EDI 00C60000
EIP 77FCC453 ntdll.77FCC453
C 0  ES 0023 32bit 0(FFFFFFFF)
P 1  CS 001B 32bit 0(FFFFFFFF)
A 0  SS 0023 32bit 0(FFFFFFFF)
Z 0  DS 0023 32bit 0(FFFFFFFF)
S 0  FS 0038 32bit 7FFDA000(FFF)
T 0  GS 0000 NULL
D 0
O 0  LastErr ERROR_SUCCESS (00000000)
EFL 00000206 (NO,NB,NE,A,NS,PE,GE,G)
ST0 empty -UNORM BC50 00000200 0014BC50
ST1 empty +UNORM 0014 000800EC 0049ECC0
ST2 empty +UNORM 4720 0012EF38 00000000
ST3 empty +UNORM 4730 01010052 00000014
ST4 empty 0.0000000000000000040e-4933
ST5 empty +UNORM 0018 0012EF48 77FA15EF
ST6 empty -UNORM EFB0 01010052 00000014
ST7 empty 1.0000000000000000000
               3 2 1 0      E S P U O Z D I
FST 0100  Cond 0 0 0 1  Err 0 0 0 0 0 0 0 0  (LT)
FCW 027F  Prec NEAR,53  Mask    1 1 1 1 1 1

 

8.2. Second Proof-of-Concept

By generating a second malformed .MBM file (available at [2]), we can trigger a heap overflow that may lead to arbitrary code execution. In this case, the crash occurs in the following code:

77F937A5    8901            MOV DWORD PTR DS:[ECX],EAX
77F937A7    8948 04         MOV DWORD PTR DS:[EAX+4],ECX
77F937AA    3BC1            CMP EAX,ECX
77F937AC    75 2E           JNZ SHORT ntdll.77F937DC

EAX 41414141
ECX 41414141
EDX 0131DA98 ASCII 41,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
EBX 00000005
ESP 0012DE68
EBP 0012E024
ESI 00C60000
EDI 0131DA98 ASCII 41,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
EIP 77F937A5 ntdll.77F937A5

 

The vulnerability is triggered in ntdll.dll. The code corresponds to the function RtlAllocateHeap when a new node is added to the double-linked list of heap chunks. As can be seen, both EAX and ECX contain arbitrary values controlled by the attacker (0x41414141). This is the Call Stack when the crash occurs:

Call stack of main thread
Address    Stack      Procedure / arguments                                                        Called from                   Frame
0012E028   77FB55EB   ntdll.77F93633                                                               ntdll.77FB55E6                0012E024
0012E0AC   77FA7C5E   ntdll.77FB5507                                                               ntdll.77FA7C59                0012E0A8
0012E27C   77FCB167   ntdll.77F93633                                                               ntdll.77FCB162                0012E278
0012E428   005AD1C6   ntdll.RtlAllocateHeap                                                        xnview.005AD1C0               0012E424
0012E42C   00C60000     hHeap = 00C60000
0012E430   40000060     Flags = HEAP_TAIL_CHECKING_ENABLED|HEAP_FREE_CHECKING_ENABLED|40000000
0012E434   00000010     HeapSize = 10 (16.)
0012E464   005AD0BD   xnview.005AD0D9                                                              xnview.005AD0B8               0012E460
0012E46C   005AD0AA   xnview.005AD0AD                                                              xnview.005AD0A5
0012E478   0049E8D4   xnview.005AD09B                                                              xnview.0049E8CF
0012E748   004A00F5   ? xnview.0049E6C0                                                            xnview.004A00F0
0012EAD4   00495075   xnview.0049FD40                                                              xnview.00495070
0012EAE8   004C8525   Includes xnview.00495075                                                     xnview.004C8523
0012EB24   77E12CA8   Includes xnview.004C8525                                                     USER32.77E12CA5
0012EB44   77E14398   ? USER32.77E12C90                                                            USER32.77E14393
0012EB48   004C8230     Arg1 = 004C8230
0012EB4C   00040124     Arg2 = 00040124
0012EB50   0000004E     Arg3 = 0000004E
0012EB54   000007D0     Arg4 = 000007D0
0012EB58   0012EC40     Arg5 = 0012EC40
0012EB74   77E14925   USER32.77E142DB                                                              USER32.77E14920               0012EB70
0012EB94   71715C13   USER32.SendMessageW                                                          COMCTL32.71715C0D             0012EB90
0012EB98   00040124     hWnd = 40124
0012EB9C   0000004E     Message = WM_NOTIFY
0012EBA0   000007D0     wParam = 7D0
0012EBA4   0012EC40     lParam = 12EC40
0012EC24   71752933   COMCTL32.717154AD                                                            COMCTL32.7175292E             0012EC20
0012ECB4   7175342C   COMCTL32.717528AB                                                            COMCTL32.71753427             0012ECB0
0012ED08   71755756   COMCTL32.7175339F                                                            COMCTL32.71755751             0012ED04
0012ED5C   77E12CA8   Includes COMCTL32.71755756                                                   USER32.77E12CA5               0012ED58
0012ED7C   77E152E6   ? USER32.77E12C90                                                            USER32.77E152E1               0012ED78
0012ED80   71755025     Arg1 = 71755025
0012ED84   0006012E     Arg2 = 0006012E
0012ED88   00001102     Arg3 = 00001102
0012ED8C   00000002     Arg4 = 00000002
0012ED90   00155FA8     Arg5 = 00155FA8
0012EDA0   77E15362   ? USER32.77E152A9                                                            USER32.77E1535D               0012ED9C
0012EDC0   0049EDED   ? USER32.CallWindowProcA                                                     xnview.0049EDE7               0012EDBC
0012EDC4   FFFF0201     PrevProc = FFFF0201
0012EDC8   0006012E     hWnd = 0006012E ('Tree View',class='SysTreeView32',parent=00040124)
0012EDCC   00001102     Message = MSG(1102)
0012EDD0   00000002     wParam = 2
0012EDD4   00155FA8     lParam = 155FA8
0012EED8   77A530AA   ntdll.RtlFreeHeap                                                            ole32.77A530A4
0012EEDC   00130000     hHeap = 00130000
0012EEE0   00000000     Flags = 0
0012EEE4   0016D990     pMemory = 0016D990
0012EEEC   77E12CA8   Includes ole32.77A530AA                                                      USER32.77E12CA5               0012EEF8
0012EF0C   77E14398   ? USER32.77E12C90                                                            USER32.77E14393               0012EEF8
0012EF10   0049ECC0     Arg1 = 0049ECC0
0012EF14   0006012E     Arg2 = 0006012E
0012EF18   00001102     Arg3 = 00001102
0012EF1C   00000002     Arg4 = 00000002
0012EF20   00155FA8     Arg5 = 00155FA8
0012EF3C   77E153A1   USER32.77E142DB                                                              USER32.77E1539C               0012EF38
0012EF5C   0049F0F9   Includes USER32.77E153A1                                                     xnview.0049F0F7               0012EF58
0012F284   004A7B45   ? xnview.0049EEC0                                                            xnview.004A7B40
0012F294   005317E9   xnview.004A7B10                                                              xnview.005317E4
0012FA44   00531276   xnview.005312C0                                                              xnview.00531271
0012FA80   004C95B8   Includes xnview.00531276                                                     xnview.004C95B4
0012FAA0   005382FE   xnview.004C9560                                                              xnview.005382F9
0012FAB8   77E12CA8   Includes xnview.005382FE                                                     USER32.77E12CA5
0012FAD8   77E14398   ? USER32.77E12C90                                                            USER32.77E14393
0012FADC   005382E0     Arg1 = 005382E0
0012FAE0   00090130     Arg2 = 00090130
0012FAE4   00000401     Arg3 = 00000401
0012FAE8   00000000     Arg4 = 00000000
0012FAEC   0012FB58     Arg5 = 0012FB58
0012FB08   77E153A1   USER32.77E142DB                                                              USER32.77E1539C               0012FB04
0012FB28   005336BA   USER32.SendMessageA                                                          xnview.005336B4               0012FB24
0012FB2C   00090130     hWnd = 90130
0012FB30   00000401     Message = WM_USER+1
0012FB34   00000000     wParam = 0
0012FB38   0012FB58     lParam = 12FB58
0012FC68   005338A2   xnview.00533590                                                              xnview.0053389D
0012FC80   004C96C7   Includes xnview.005338A2                                                     xnview.004C96C3
0012FCA4   005369E3   xnview.004C9660                                                              xnview.005369DE
0012FCC4   004C95B8   Includes xnview.005369E3                                                     xnview.004C95B4
0012FCE4   005382FE   xnview.004C9560                                                              xnview.005382F9               0012FD18
0012FCFC   77E12CA8   Includes xnview.005382FE                                                     USER32.77E12CA5               0012FD18
0012FD1C   77E12DC5   ? USER32.77E12C90                                                            USER32.77E12DC0               0012FD18
0012FD20   005382E0     Arg1 = 005382E0
0012FD24   00090130     Arg2 = 00090130
0012FD28   00000111     Arg3 = 00000111
0012FD2C   0000000B     Arg4 = 0000000B
0012FD30   00000000     Arg5 = 00000000
0012FDA8   77E1577D   USER32.77E12CBD                                                              USER32.77E15778               0012FDA4
0012FDB4   0053802B   USER32.DispatchMessageA                                                      xnview.00538025
0012FDB8   0012FDD8     pMsg = WM_COMMAND hw = 90130 ("XnView - [Browser - C:\Docu...") Notify =
0012FF38   005B21E2   ? xnview.005377E0                                                            xnview.<ModuleEntryPoint>
  +0D
  0012FF3C   00400000     Arg1 = 00400000
  0012FF40   00000000     Arg2 = 00000000
  0012FF44   0013326B     Arg3 = 0013326B
  0012FF48   0000000A     Arg4 = 0000000A

 

The problem is found in the function 0x65a310:

0065A310  /$  53            PUSH EBX
0065A311  |.  55            PUSH EBP
0065A312  |.  8B6C24 14     MOV EBP,DWORD PTR SS:[ESP+14]
0065A316  |.  33C0          XOR EAX,EAX
0065A318  |.  56            PUSH ESI
0065A319  |.  57            PUSH EDI
0065A31A  |.  85ED          TEST EBP,EBP
0065A31C  |.  0F8E AB000000 JLE xnview.0065A3CD
0065A322  |.  8B5C24 14     MOV EBX,DWORD PTR SS:[ESP+14]
0065A326  |.  8B7C24 18     MOV EDI,DWORD PTR SS:[ESP+18]
0065A32A  |>  8B03          /MOV EAX,DWORD PTR DS:[EBX]
0065A32C  |.  8D4C24 1C     |LEA ECX,DWORD PTR SS:[ESP+1C]
0065A330  |.  50            |PUSH EAX                                      ; /Arg4
0065A331  |.  6A 01         |PUSH 1                                        ; |Arg3 = 00000001
0065A333  |.  6A 01         |PUSH 1                                        ; |Arg2 = 00000001
0065A335  |.  51            |PUSH ECX                                      ; |Arg1
0065A336  |.  E8 284BF5FF   |CALL xnview.005AEE63                          ; \xnview.005AEE63
0065A33B  |.  83C4 10       |ADD ESP,10
0065A33E  |.  83F8 01       |CMP EAX,1
0065A341  |.  0F85 81000000 |JNZ xnview.0065A3C8
0065A347  |.  8A4424 1C     |MOV AL,BYTE PTR SS:[ESP+1C]
0065A34B  |.  84C0          |TEST AL,AL
0065A34D  |.  66:0FBEC0     |MOVSX AX,AL
0065A351  |.  7D 22         |JGE SHORT xnview.0065A375
0065A353  |.  8B13          |MOV EDX,DWORD PTR DS:[EBX]
0065A355  |.  F7D8          |NEG EAX
0065A357  |.  0FBFF0        |MOVSX ESI,AX
0065A35A  |.  52            |PUSH EDX                                      ; /Arg4
0065A35B  |.  6A 01         |PUSH 1                                        ; |Arg3 = 00000001
0065A35D  |.  56            |PUSH ESI                                      ; |Arg2
0065A35E  |.  57            |PUSH EDI                                      ; |Arg1
0065A35F  |.  2BEE          |SUB EBP,ESI                                   ; |
0065A361  |.  E8 FD4AF5FF   |CALL xnview.005AEE63                          ; \xnview.005AEE63
0065A366  |.  83C4 10       |ADD ESP,10
0065A369  |.  85C0          |TEST EAX,EAX
0065A36B  |.  74 5B         |JE SHORT xnview.0065A3C8
0065A36D  |.  03FE          |ADD EDI,ESI
0065A36F  |.  897C24 18     |MOV DWORD PTR SS:[ESP+18],EDI
0065A373  |.  EB 44         |JMP SHORT xnview.0065A3B9
0065A375  |>  40            |INC EAX
0065A376  |.  0FBFF0        |MOVSX ESI,AX
0065A379  |.  8B03          |MOV EAX,DWORD PTR DS:[EBX]
0065A37B  |.  2BEE          |SUB EBP,ESI
0065A37D  |.  50            |PUSH EAX
0065A37E  |.  E8 AB4DF5FF   |CALL xnview.005AF12E
0065A383  |.  83C4 04       |ADD ESP,4
0065A386  |.  66:3D FFFF    |CMP AX,0FFFF
0065A38A  |.  74 3C         |JE SHORT xnview.0065A3C8
0065A38C  |.  0FBFC0        |MOVSX EAX,AX
0065A38F  |.  8AD8          |MOV BL,AL
0065A391  |.  8BCE          |MOV ECX,ESI
0065A393  |.  8AFB          |MOV BH,BL
0065A395  |.  8BD1          |MOV EDX,ECX
0065A397  |.  8BC3          |MOV EAX,EBX
0065A399  |.  C1E0 10       |SHL EAX,10
0065A39C  |.  66:8BC3       |MOV AX,BX
0065A39F  |.  8B5C24 14     |MOV EBX,DWORD PTR SS:[ESP+14]
0065A3A3  |.  C1E9 02       |SHR ECX,2
0065A3A6  |.  F3:AB         |REP STOS DWORD PTR ES:[EDI]
0065A3A8  |.  8BCA          |MOV ECX,EDX
0065A3AA  |.  83E1 03       |AND ECX,3
0065A3AD  |.  F3:AA         |REP STOS BYTE PTR ES:[EDI]
0065A3AF  |.  8B7C24 18     |MOV EDI,DWORD PTR SS:[ESP+18]
0065A3B3  |.  03FE          |ADD EDI,ESI
0065A3B5  |.  897C24 18     |MOV DWORD PTR SS:[ESP+18],EDI
0065A3B9  |>  85ED          |TEST EBP,EBP
0065A3BB  |.^ 0F8F 69FFFFFF \JG xnview.0065A32A
0065A3C1  |.  5F            POP EDI
0065A3C2  |.  5E            POP ESI
0065A3C3  |.  5D            POP EBP
0065A3C4  |.  33C0          XOR EAX,EAX
0065A3C6  |.  5B            POP EBX
0065A3C7  |.  C3            RETN
0065A3C8  |>  B8 04000000   MOV EAX,4
0065A3CD  |>  5F            POP EDI
0065A3CE  |.  5E            POP ESI
0065A3CF  |.  5D            POP EBP
0065A3D0  |.  5B            POP EBX
0065A3D1  \.  C3            RETN

 

According to the .MBM format [3], the structure of an MBM is the following (beginning with a Header Section):

Offset Size Data Description

0000 ID 37 00 00 10 UID1: Header Section layout

0004 ID 42 00 00 10 UID2: File kind

0008 ID 00 00 00 00 UID3: Application ID

000C L 39 64 39 47 UID4: Checksum of UID1, UID2 and UID3

0010 Offset MBM Jumptable

 

The MBM Jumptable is an LListL of offsets in which each offset points to a Paint Data Section. An LListL is basically a list where, as can be deduced from [4], the first letter ("L") represents the encoding of the list size indicator and the last letter ("L") represents the size of each element of the list. In this case, we have a list of LONGs and the size of this list is encoded as a LONG. So in our case, we have the following:

37000010 // Header Section Layout
42000010 // File  Kind
00000000 // Application ID
39643947 // Checksum Header Section, File Kind and Application ID
14000000 // Offset to MBM Jumptable

 

Our MBM Jumptable contains the following:

01000000 // List lenght
1C000000 // Offset to the list

 

This is a list with one element (there is only one drawing in the file). The structure of each Paint Data Section is described in [5]. Inside this structure, there is a field called "Encoding", represented as Long and which contains the following values:

00 00 00 00 Plain data
01 00 00 00 8-bit RLE encoding
02 00 00 00 12-bit RLE encoding
03 00 00 00 16-bit RLE encoding
04 00 00 00 24-bit RLE encoding

 

The original value in our case was 0x00000000, that the encoding indicates as plain data. When we change this value to 0x00007a7a, XnView interprets the data as RLE encoding. According to the format documentation [5]: "RLE encoding consists of sequences of marker bytes with data bytes. A marker byte of 00 to 7F means that the next byte should be repeated that many times and once more. A marker byte of 80 to FF means that (100-marker) bytes of data follow."

The function 0x65A310 is responsible for handling this encoding and copying the data indicated by the marker byte according to the encoding indicated by the "Encoding" field. In our case, the encoding field contains the following values:

0x00007a7a // Malformed encoding
0x7a41 // Data for this encoding

 

We now look with more detail at that function, and how it handles data:

0065A347  |.  8A4424 1C     |MOV AL,BYTE PTR SS:[ESP+1C] // takes the marker byte
0065A34B  |.  84C0          |TEST AL,AL
0065A34D  |.  66:0FBEC0     |MOVSX AX,AL				        // moves it to AX
0065A351  |.  7D 22         |JGE SHORT xnview.0065A375  // checks if it's greater that 0

 

In this part, the program uses the third byte of the encoding, that is 0x7A, and since it is greater that 0, jumps to:

0065A375  |> \40            |INC EAX 						  // increments EAX
0065A376  |.  0FBFF0        |MOVSX ESI,AX 				// copies the high part of EAX to ESI
0065A379  |.  8B03          |MOV EAX,DWORD PTR DS:[EBX]
0065A37B  |.  2BEE          |SUB EBP,ESI
0065A37D  |.  50            |PUSH EAX
0065A37E  |.  E8 AB4DF5FF   |CALL xnview.005AF12E // obtains the byte following 0x7A, that is the last byte of the encoding
0065A383  |.  83C4 04       |ADD ESP,4
0065A386  |.  66:3D FFFF    |CMP AX,0FFFF					// is this last byte 0xFFFF? in fact it should be 0xFF, it's one byte
0065A38A  |.  74 3C         |JE SHORT xnview.0065A3C8		// if it is, then good bye!
0065A38C  |.  0FBFC0        |MOVSX EAX,AX					// otherwise move AX to EAX
0065A38F  |.  8AD8          |MOV BL,AL						// AL = 0x41 goes to BL
0065A391  |.  8BCE          |MOV ECX,ESI					// ESI = 0x7B = 0x7A + 1 = ECX
0065A393  |.  8AFB          |MOV BH,BL						// BL a BH -> BH takes the value 0x4141
0065A395  |.  8BD1          |MOV EDX,ECX					// EDX = 0x7B
0065A397  |.  8BC3          |MOV EAX,EBX					// EAX == EBX
0065A399  |.  C1E0 10       |SHL EAX,10						// aca EAX == 0x41410000
0065A39C  |.  66:8BC3       |MOV AX,BX						// AX == 0x4141 -> EAX == 0x41414141
0065A39F  |.  8B5C24 14     |MOV EBX,DWORD PTR SS:[ESP+14]
0065A3A3  |.  C1E9 02       |SHR ECX,2						// ECX / 4 = 0x1E, counter
0065A3A6  |.  F3:AB         |REP STOS DWORD PTR ES:[EDI]	// EDI points to a HEAP of 0x32 bytes.
0065A3A8  |.  8BCA          |MOV ECX,EDX
0065A3AA  |.  83E1 03       |AND ECX,3
0065A3AD  |.  F3:AA         |REP STOS BYTE PTR ES:[EDI]		// copies another DWORD

 

As we can see, in this part it takes the marker byte (0x7A), increments it by 1 (0x7B) and copies the following byte (0x41) the number of times indicated by the marker byte, but the buffer has only 0x32 bytes allocated. Below those 0x32 bytes we find the header of another chunk on the heap:

01355570  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  // beginning of the 0x32 bytes heap
01355580  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01355590  AB AB AB AB AB AB AB AB 00 00 00 00 00 00 00 00
013555A0  20 00 07 00 01 04 EE FE 78 02 C6 00 78 02 C6 00
013555B0  EE FE EE FE EE FE EE FE EE FE EE FE EE FE EE FE
013555C0  EE FE EE FE EE FE EE FE EE FE EE FE EE FE EE FE

 

0x31355A0 is the beginning of the header of the next chunk. After executing REP STOS, the corruption of the header of that chunk occurs:

013555D8  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
013555E8  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
013555F8  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
01355608  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
01355618  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
01355628  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
01355638  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
01355648  41 41 41 41 41 41 41 41 EE FE EE FE EE FE EE FE

 

The error is the following: since it copies DWORDs, instead of copying 0x1E bytes, it should have copied 0x0F bytes (0x1E / 2). Finally, the heap block is allocated in this part of the code:

005AC5F7    56              PUSH ESI					// Heap Size
005AC5F8    6A 08           PUSH 8						// HEAP_ZERO_MEMORY
005AC5FA    FF35 A4347900   PUSH DWORD PTR DS:[7934A4]	// Heap
005AC600    FF15 84726E00   CALL DWORD PTR DS:[<&KERNEL32.HeapAlloc>]      ; ntdll.RtlAllocateHeap

 

9. Report Timeline

  • 2010-05-27: Core Security Technologies notifies XnView of the vulnerability.
  • 2010-05-27: The XnView author acknowledges receipt of the notification.
  • 2010-05-27: Core sends a technical description of the vulnerability, and a Proof-of-Concept file that triggers the bug.
  • 2010-05-28: The XnView author notifies Core that the vulnerability has been fixed, and that a fixed version will be released.
  • 2010-06-02: Core asks XnView when the fixed version will be released, in order to coordinate the publication of the advisory with the release of a fixed version.
  • 2010-06-03: The XnView author responds that version 1.97.5 will be available in 2 weeks.
  • 2010-06-03: Core requests a more precise date for the release, and reschedules publication of its advisory to June 14th, 2010.
  • 2010-06-07: The XnView author responds that the update will be available on June 14th.
  • 2010-06-10: Core sends a second Proof-of-Concept, and asks the XnView author if it triggers a different vulnerability.
  • 2010-06-11: The XnView author responds that the second PoC triggers the same vulnerability.
  • 2010-06-14: Advisory CORE-2010-0514 is published.

10. References

[1] XnView website http://www.xnview.com/
[2] Proof of Concept files /legacy/files/attachments/CORE-2010-0514-Xnview-PoCs.rar
[3] MBM file format http://software.frodo.looijaard.name/psiconv/formats/MBM_File.html
[4] Basic elements: LListL http://software.frodo.looijaard.name/psiconv/formats/Basic_Elements.html#LListL
[5] Paint Data Section http://software.frodo.looijaard.name/psiconv/formats/Paint_Data_Section.html#Paint%20Data%20Section

11. About CoreLabs

CoreLabs, the research center of Core Security Technologies, is charged with anticipating the future needs and requirements for information security technologies. We conduct our research in several important areas of computer security including system vulnerabilities, cyber attack planning and simulation, source code auditing, and cryptography. Our results include problem formalization, identification of vulnerabilities, novel solutions and prototypes for new technologies. CoreLabs regularly publishes security advisories, technical papers, project information and shared software tools for public use at: http://corelabs.coresecurity.com/.

12. About Core Security Technologies

Core Security Technologies develops strategic solutions that help security-conscious organizations worldwide develop and maintain a proactive process for securing their networks. The company's flagship product, CORE IMPACT, is the most comprehensive product for performing enterprise security assurance testing. CORE IMPACT evaluates network, endpoint and end-user vulnerabilities and identifies what resources are exposed. It enables organizations to determine if current security investments are detecting and preventing attacks. Core Security Technologies augments its leading technology solution with world-class security consulting services, including penetration testing and software security auditing. Based in Boston, MA and Buenos Aires, Argentina, Core Security Technologies can be reached at 617-399-6980 or on the Web at http://www.coresecurity.com.

13. Disclaimer

The contents of this advisory are copyright (c) 2010 Core Security Technologies and (c) 2010 CoreLabs, and may be distributed freely provided that no fee is charged for this distribution and proper credit is given.

14. PGP/GPG Keys

This advisory has been signed with the GPG key of Core Security Technologies advisories team, which is available for download at /legacy/files/attachments/core_security_advisories.asc.

Locally Exploitable: 
no
Remotely Exploitable: 
no
  • Request Info

Research Blog