<?xml version="1.0"?>
<?xml-stylesheet href="../fma_report_en.xslt" type="text/xsl" ?>

<advisory xml:space="preserve">
	<meta>
		<description>IrfanView 4.33 Enhanced Compressed Wavelet (ECW) Multiple Vulnerabilities</description>
		<keywords>fuzzing, security, blackbox, tests, i_view32.exe, DoS, LCE, ECW</keywords>
	</meta>

	<title>IrfanView 4.33 Enhanced Compressed Wavelet (ECW) Multiple Vulnerabilities</title>
	<id>FMA-2012-007</id>
	
	<application>
		<name>IrfanView</name>
		<version>4.33</version>
		<url>http://www.irfanview.com</url>
		<files>
			<file>
				<name>i_view32.exe</name>
				<version>4.33</version>
				<md5>072D046EDBA5528868DB40328A8E56F5</md5>
			</file>
			<file>
				<name>NCSEcw.dll</name>
				<version>1.6.6.32</version>
				<md5>9945F8146B2B831B24FBAA9F51E83299</md5>
			</file>
		</files>		
		<verified>
			<os>
				<name>Windows XP SP3 Home Edition</name>
			</os>
			<os>
				<name>Windows XP SP3 Professional Edition</name>
			</os>
			<os>
				<name>Windows 7 SP1 Home Premium</name>
			</os>
		</verified>
	</application>
	
	<discovery>
		<found>2012.03.29</found>
		<vendor_notified>2012.04.18</vendor_notified>
		<published>2012.05.27</published>
	</discovery>

	<vulnerabilities>
	
	<vulnerability>
			<name>Denial of Service caused by lack of loop counter validation in data processing loop in modul NCSEcw.dll (Irfan ECW plugin).</name>
			<type>DoS/LCE</type>
			<description>Data processing loop reads float values from source buffer, then it does basic float math. The calculated result is stored in the destination buffer. In our case the destination buffer was larger than the source buffer, so there was no heap overflow. We forced processing loop to reach the end of the source buffer, at that point we have access violation exception which caused Denial of Service of IrfanView. If the attacker prepares a sample which forces ECW IrfanPlugin to allocate larger source buffer than destination buffer, the attacker then has a full control over loop counter so he can overflow destination buffer which will end up in heap overflow that may lead to Code Execution. During fuzzing run we have indentified 3 samples triggering the following vulnerability.</description>
			<exception>Access violation exception when reading DWORD value from source buffer.</exception>
<disasm>5FFB12A5    F64424 2C 01    TEST BYTE PTR SS:[ESP+2C],1
5FFB12AA    75 5C           JNZ SHORT NCSEcw.5FFB1308
5FFB12AC    D947 04         FLD DWORD PTR DS:[EDI+4]
5FFB12AF    D845 04         FADD DWORD PTR SS:[EBP+4]
5FFB12B2    8B5424 28       MOV EDX,DWORD PTR SS:[ESP+28]
5FFB12B6    83C0 04         ADD EAX,4
5FFB12B9    83C6 04         ADD ESI,4
5FFB12BC    83C7 04         ADD EDI,4
5FFB12BF    D835 B004FD5F   FDIV DWORD PTR DS:[5FFD04B0]
5FFB12C5    83C5 04         ADD EBP,4
5FFB12C8    83C1 04         ADD ECX,4
5FFB12CB    D82E            FSUBR DWORD PTR DS:[ESI]
5FFB12CD    D941 FC         FLD DWORD PTR DS:[ECX-4]
5FFB12D0    D801            FADD DWORD PTR DS:[ECX]
5FFB12D2    D835 B004FD5F   FDIV DWORD PTR DS:[5FFD04B0]
5FFB12D8    DEE9            FSUBP ST(1),ST
5FFB12DA    D942 04         FLD DWORD PTR DS:[EDX+4]
5FFB12DD    D802            FADD DWORD PTR DS:[EDX]
5FFB12DF    8B5424 34       MOV EDX,DWORD PTR SS:[ESP+34]
5FFB12E3    D842 04         FADD DWORD PTR DS:[EDX+4]           ; [FuzzMyApp.com] access violation exception
5FFB12E6    83C2 04         ADD EDX,4
5FFB12E9    895424 34       MOV DWORD PTR SS:[ESP+34],EDX       ; [FuzzMyApp.com] read float from source buffer
5FFB12ED    D842 FC         FADD DWORD PTR DS:[EDX-4]           ; [FuzzMyApp.com] add two floats
5FFB12F0    8B5424 28       MOV EDX,DWORD PTR SS:[ESP+28]
5FFB12F4    83C2 04         ADD EDX,4
5FFB12F7    D835 AC04FD5F   FDIV DWORD PTR DS:[5FFD04AC]        ; [FuzzMyApp.com] divide by const
5FFB12FD    895424 28       MOV DWORD PTR SS:[ESP+28],EDX
5FFB1301    DEC1            FADDP ST(1),ST                      ; [FuzzMyApp.com] add two floats
5FFB1303    D958 FC         FSTP DWORD PTR DS:[EAX-4]           ; [FuzzMyApp.com] store float in destination buffer
5FFB1306    EB 3A           JMP SHORT NCSEcw.5FFB1342
5FFB1308    D946 04         FLD DWORD PTR DS:[ESI+4]
5FFB130B    D806            FADD DWORD PTR DS:[ESI]
5FFB130D    8B5424 28       MOV EDX,DWORD PTR SS:[ESP+28]
5FFB1311    83C0 04         ADD EAX,4
5FFB1314    D835 B004FD5F   FDIV DWORD PTR DS:[5FFD04B0]
5FFB131A    D945 04         FLD DWORD PTR SS:[EBP+4]
5FFB131D    D847 04         FADD DWORD PTR DS:[EDI+4]
5FFB1320    D845 00         FADD DWORD PTR SS:[EBP]
5FFB1323    D807            FADD DWORD PTR DS:[EDI]
5FFB1325    D835 AC04FD5F   FDIV DWORD PTR DS:[5FFD04AC]
5FFB132B    DEE9            FSUBP ST(1),ST
5FFB132D    D801            FADD DWORD PTR DS:[ECX]
5FFB132F    D902            FLD DWORD PTR DS:[EDX]
5FFB1331    8B5424 34       MOV EDX,DWORD PTR SS:[ESP+34]
5FFB1335    D802            FADD DWORD PTR DS:[EDX]
5FFB1337    D835 B004FD5F   FDIV DWORD PTR DS:[5FFD04B0]
5FFB133D    DEE9            FSUBP ST(1),ST
5FFB133F    D958 FC         FSTP DWORD PTR DS:[EAX-4]
5FFB1342    8B5424 2C       MOV EDX,DWORD PTR SS:[ESP+2C]
5FFB1346    42              INC EDX
5FFB1347    895424 2C       MOV DWORD PTR SS:[ESP+2C],EDX
5FFB134B    8B5424 1C       MOV EDX,DWORD PTR SS:[ESP+1C]
5FFB134F    4A              DEC EDX                             ; [FuzzMyApp.com] decrement counter
5FFB1350    895424 1C       MOV DWORD PTR SS:[ESP+1C],EDX
5FFB1354  ^ 0F85 4BFFFFFF   JNZ NCSEcw.5FFB12A5                 ; [FuzzMyApp.com] loop till counter is nonzero</disasm>
			<images>
				<image>
					<thumbnail>
						<src>image01s.png</src>
						<width>94</width>
						<height>100</height>
					</thumbnail>
					<src>image01.png</src>
					<alt>Access violation exception when reading DWORD value from source buffer.</alt>
					<text>Access violation exception when reading DWORD value from source buffer.</text>
				</image>
			</images>
		</vulnerability>	
	
		<vulnerability>
			<name>Denial of Service during processing of malformed ECW file.</name>
			<type>DoS</type>
			<description>Denial of Service is caused by a not handled integer division by zero exception in modul NCSEcw.dll (Irfan ECW plugin) during processing of malformed ECW file. During fuzzing run we have indentified 5 samples triggering the following vulnerability.</description>
			<exception>Integer division by zero exception.</exception>
<disasm>5FFCB67D    8B4C24 10       MOV ECX,DWORD PTR SS:[ESP+10]       ; [FuzzMyApp.com] [ESP+10] == 0
5FFCB681    66:8B5424 14    MOV DX,WORD PTR SS:[ESP+14]
5FFCB686    C646 03 02      MOV BYTE PTR DS:[ESI+3],2
5FFCB68A    B8 01000000     MOV EAX,1
5FFCB68F    C646 04 04      MOV BYTE PTR DS:[ESI+4],4
5FFCB693    8946 3C         MOV DWORD PTR DS:[ESI+3C],EAX
5FFCB696    8946 40         MOV DWORD PTR DS:[ESI+40],EAX
5FFCB699    66:8B4424 18    MOV AX,WORD PTR SS:[ESP+18]
5FFCB69E    66:8906         MOV WORD PTR DS:[ESI],AX
5FFCB6A1    8B4424 1C       MOV EAX,DWORD PTR SS:[ESP+1C]
5FFCB6A5    66:894E 2C      MOV WORD PTR DS:[ESI+2C],CX
5FFCB6A9    81E1 FFFF0000   AND ECX,0FFFF                       ; [FuzzMyApp.com] ECX == 0
5FFCB6AF    8946 08         MOV DWORD PTR DS:[ESI+8],EAX
5FFCB6B2    66:8956 2E      MOV WORD PTR DS:[ESI+2E],DX
5FFCB6B6    8D4401 FF       LEA EAX,DWORD PTR DS:[ECX+EAX-1]
5FFCB6BA    33D2            XOR EDX,EDX
5FFCB6BC    F7F1            DIV ECX                             ; [FuzzMyApp.com] integer division by zero exception
5FFCB6BE    8B4C24 14       MOV ECX,DWORD PTR SS:[ESP+14]</disasm>
			<images>
				<image>
					<thumbnail>
						<src>image02s.png</src>
						<width>100</width>
						<height>69</height>
					</thumbnail>
					<src>image02.png</src>
					<alt>Integer division by zero exception.</alt>
					<text>Integer division by zero exception.</text>
				</image>
			</images>
		</vulnerability>	
		
		<vulnerability>
			<name>Denial of Service during processing of malformed ECW file.</name>
			<type>DoS</type>
			<description>Denial of Service is caused by a not handled integer division by zero exception in modul NCSEcw.dll (Irfan ECW plugin) during processing of malformed ECW file. During fuzzing run we have indentified 5 samples triggering the following vulnerability.</description>
			<exception>Integer division by zero exception.</exception>
<disasm>5FFCB6BE    8B4C24 14       MOV ECX,DWORD PTR SS:[ESP+14]
5FFCB6C2    55              PUSH EBP
5FFCB6C3    8B6C24 24       MOV EBP,DWORD PTR SS:[ESP+24]
5FFCB6C7    81E1 FFFF0000   AND ECX,0FFFF
5FFCB6CD    33D2            XOR EDX,EDX
5FFCB6CF    8B7C24 28       MOV EDI,DWORD PTR SS:[ESP+28]
5FFCB6D3    895E 78         MOV DWORD PTR DS:[ESI+78],EBX
5FFCB6D6    895E 48         MOV DWORD PTR DS:[ESI+48],EBX
5FFCB6D9    895E 7C         MOV DWORD PTR DS:[ESI+7C],EBX
5FFCB6DC    896E 0C         MOV DWORD PTR DS:[ESI+C],EBP
5FFCB6DF    66:897E 06      MOV WORD PTR DS:[ESI+6],DI
5FFCB6E3    895E 4C         MOV DWORD PTR DS:[ESI+4C],EBX
5FFCB6E6    895E 50         MOV DWORD PTR DS:[ESI+50],EBX
5FFCB6E9    885E 5C         MOV BYTE PTR DS:[ESI+5C],BL
5FFCB6EC    895E 54         MOV DWORD PTR DS:[ESI+54],EBX
5FFCB6EF    895E 58         MOV DWORD PTR DS:[ESI+58],EBX
5FFCB6F2    895E 28         MOV DWORD PTR DS:[ESI+28],EBX
5FFCB6F5    895E 64         MOV DWORD PTR DS:[ESI+64],EBX
5FFCB6F8    895E 60         MOV DWORD PTR DS:[ESI+60],EBX
5FFCB6FB    899E 80000000   MOV DWORD PTR DS:[ESI+80],EBX
5FFCB701    899E 84000000   MOV DWORD PTR DS:[ESI+84],EBX
5FFCB707    889E 90000000   MOV BYTE PTR DS:[ESI+90],BL
5FFCB70D    899E 88000000   MOV DWORD PTR DS:[ESI+88],EBX
5FFCB713    899E 8C000000   MOV DWORD PTR DS:[ESI+8C],EBX
5FFCB719    899E 94000000   MOV DWORD PTR DS:[ESI+94],EBX
5FFCB71F    895E 10         MOV DWORD PTR DS:[ESI+10],EBX
5FFCB722    895E 14         MOV DWORD PTR DS:[ESI+14],EBX
5FFCB725    895E 20         MOV DWORD PTR DS:[ESI+20],EBX
5FFCB728    895E 24         MOV DWORD PTR DS:[ESI+24],EBX
5FFCB72B    66:895E 68      MOV WORD PTR DS:[ESI+68],BX
5FFCB72F    895E 6C         MOV DWORD PTR DS:[ESI+6C],EBX
5FFCB732    895E 70         MOV DWORD PTR DS:[ESI+70],EBX
5FFCB735    8946 30         MOV DWORD PTR DS:[ESI+30],EAX
5FFCB738    8D4429 FF       LEA EAX,DWORD PTR DS:[ECX+EBP-1]
5FFCB73C    F7F1            DIV ECX                             ; [FuzzMyApp.com] integer division by zero exception</disasm>
			<images>
				<image>
					<thumbnail>
						<src>image03s.png</src>
						<width>100</width>
						<height>67</height>
					</thumbnail>
					<src>image03.png</src>
					<alt>Integer division by zero exception.</alt>
					<text>Integer division by zero exception.</text>
				</image>
			</images>
		</vulnerability>	
		
		<vulnerability>
			<name>Heap Overflow vulnerability caused by invalid input parameters validation by recursive data processing procedure during processing of malformed ECW file.</name>
			<type>LCE</type>
			<description>During processing of the malformed ECW file, recursive procedure is called, which overflows the allocated heap buffer. When the next heap block header is overflowed, the procedure calls msvcrt.free() function in order to free the heap buffer which was overlowed. A successful exploitation can lead to Code Exception.</description>
			<exception>Exception (ntdll.DbgBreakPoint()) raised by msvcrt.free() after detecting corrupted heap buffer.</exception>
<disasm>5FFCE6E7    50              PUSH EAX                                  ; [FuzzMyApp.com] size = 0x1B00
5FFCE6E8    FF15 0002FD5F   CALL DWORD PTR DS:[5FFD0200]              ; [FuzzMyApp.com] msvcrt.malloc
5FFCE6EE    83C4 04         ADD ESP,4                                 ; [FuzzMyApp.com] buffer allocated at 0x0F2?BC48 (? - changed after re-reun)
5FFCE6F1    85C0            TEST EAX,EAX
5FFCE6F3    75 03           JNZ SHORT NCSEcw.5FFCE6F8                 ; [FuzzMyApp.com] ok, allocation was successful
5FFCE6F5    5E              POP ESI
5FFCE6F6    59              POP ECX
5FFCE6F7    C3              RETN
5FFCE6F8    8B5424 0C       MOV EDX,DWORD PTR SS:[ESP+C]              ; [FuzzMyApp.com] counter = 240
5FFCE6FC    8B0E            MOV ECX,DWORD PTR DS:[ESI]
5FFCE6FE    57              PUSH EDI                                  ; [FuzzMyApp.com] 0x2000
5FFCE6FF    8BF8            MOV EDI,EAX
5FFCE701    83C0 0C         ADD EAX,0C                                ; [FuzzMyApp.com] start of allocated buffer
5FFCE704    4A              DEC EDX                                   ; [FuzzMyApp.com] --counter
5FFCE705    894424 08       MOV DWORD PTR SS:[ESP+8],EAX
5FFCE709    895424 10       MOV DWORD PTR SS:[ESP+10],EDX             ; [FuzzMyApp.com] update local variable with decremented counter
5FFCE70D    8A01            MOV AL,BYTE PTR DS:[ECX]
5FFCE70F    41              INC ECX
5FFCE710    84C0            TEST AL,AL
5FFCE712    890E            MOV DWORD PTR DS:[ESI],ECX
5FFCE714    75 2E           JNZ SHORT NCSEcw.5FFCE744
5FFCE716    8D4C24 10       LEA ECX,DWORD PTR SS:[ESP+10]
5FFCE71A    8D5424 08       LEA EDX,DWORD PTR SS:[ESP+8]
5FFCE71E    51              PUSH ECX
5FFCE71F    52              PUSH EDX
5FFCE720    56              PUSH ESI
5FFCE721    E8 7A000000     CALL NCSEcw.5FFCE7A0                      ; [FuzzMyApp.com] invoke recursive procedure
(...)
5FFCE7A0    53              PUSH EBX
5FFCE7A1    8B5C24 0C       MOV EBX,DWORD PTR SS:[ESP+C]
5FFCE7A5    55              PUSH EBP
5FFCE7A6    8B6C24 14       MOV EBP,DWORD PTR SS:[ESP+14]
5FFCE7AA    56              PUSH ESI
5FFCE7AB    8B33            MOV ESI,DWORD PTR DS:[EBX]
5FFCE7AD    57              PUSH EDI
5FFCE7AE    8B7C24 14       MOV EDI,DWORD PTR SS:[ESP+14]
5FFCE7B2    8D46 0C         LEA EAX,DWORD PTR DS:[ESI+C]
5FFCE7B5    8903            MOV DWORD PTR DS:[EBX],EAX
5FFCE7B7    8B55 00         MOV EDX,DWORD PTR SS:[EBP]
5FFCE7BA    4A              DEC EDX                                   ; [FuzzMyApp.com] decrement counter
5FFCE7BB    8955 00         MOV DWORD PTR SS:[EBP],EDX                ; [FuzzMyApp.com] update variable on stack
5FFCE7BE    8B0F            MOV ECX,DWORD PTR DS:[EDI]
5FFCE7C0    8A01            MOV AL,BYTE PTR DS:[ECX]
5FFCE7C2    41              INC ECX
5FFCE7C3    84C0            TEST AL,AL
5FFCE7C5    890F            MOV DWORD PTR DS:[EDI],ECX
5FFCE7C7    75 1F           JNZ SHORT NCSEcw.5FFCE7E8                 ; [FuzzMyApp.com] omit recursion
5FFCE7C9    55              PUSH EBP
5FFCE7CA    53              PUSH EBX
5FFCE7CB    57              PUSH EDI
5FFCE7CC    E8 CFFFFFFF     CALL NCSEcw.5FFCE7A0                      ; [FuzzMyApp.com] invoke recursive call
5FFCE7D1    55              PUSH EBP
5FFCE7D2    53              PUSH EBX
5FFCE7D3    57              PUSH EDI
5FFCE7D4    8906            MOV DWORD PTR DS:[ESI],EAX
5FFCE7D6    E8 C5FFFFFF     CALL NCSEcw.5FFCE7A0                      ; [FuzzMyApp.com] invoke recursive call
5FFCE7DB    83C4 18         ADD ESP,18
5FFCE7DE    8946 04         MOV DWORD PTR DS:[ESI+4],EAX
5FFCE7E1    8BC6            MOV EAX,ESI
5FFCE7E3    5F              POP EDI
5FFCE7E4    5E              POP ESI
5FFCE7E5    5D              POP EBP
5FFCE7E6    5B              POP EBX
5FFCE7E7    C3              RETN
5FFCE7E8    A8 40           TEST AL,40
5FFCE7EA    C746 04 0000000>MOV DWORD PTR DS:[ESI+4],0                ; [FuzzMyApp.com] write to our buffer
5FFCE7F1    C706 00000000   MOV DWORD PTR DS:[ESI],0                  ; [FuzzMyApp.com] write to our buffer
5FFCE7F7    74 20           JE SHORT NCSEcw.5FFCE819
5FFCE7F9    8AC8            MOV CL,AL
5FFCE7FB    66:33D2         XOR DX,DX
5FFCE7FE    80E1 30         AND CL,30
5FFCE801    24 0F           AND AL,0F
5FFCE803    8AD1            MOV DL,CL
5FFCE805    5F              POP EDI
5FFCE806    66:0FB6C0       MOVZX AX,AL
5FFCE80A    C1E2 0A         SHL EDX,0A
5FFCE80D    0BD0            OR EDX,EAX
5FFCE80F    8BC6            MOV EAX,ESI
5FFCE811    66:8956 08      MOV WORD PTR DS:[ESI+8],DX
5FFCE815    5E              POP ESI
5FFCE816    5D              POP EBP
5FFCE817    5B              POP EBX
5FFCE818    C3              RETN
5FFCE819    8B07            MOV EAX,DWORD PTR DS:[EDI]
5FFCE81B    33D2            XOR EDX,EDX
5FFCE81D    66:0FB608       MOVZX CX,BYTE PTR DS:[EAX]
5FFCE821    40              INC EAX
5FFCE822    8907            MOV DWORD PTR DS:[EDI],EAX
5FFCE824    8A30            MOV DH,BYTE PTR DS:[EAX]
5FFCE826    0BCA            OR ECX,EDX
5FFCE828    40              INC EAX
5FFCE829    8907            MOV DWORD PTR DS:[EDI],EAX
5FFCE82B    66:894E 08      MOV WORD PTR DS:[ESI+8],CX
5FFCE82F    8BC6            MOV EAX,ESI
5FFCE831    5F              POP EDI
5FFCE832    5E              POP ESI
5FFCE833    5D              POP EBP
5FFCE834    5B              POP EBX
5FFCE835    C3              RETN                                      ; [FuzzMyApp.com] back to recursive procedure</disasm>
			<images>
				<image>
					<thumbnail>
						<src>image04s.png</src>
						<width>100</width>
						<height>88</height>
					</thumbnail>
					<src>image04.png</src>
					<alt>Before heap header overflow.</alt>
					<text>Before heap header overflow.</text>
				</image>
				<image>
					<thumbnail>
						<src>image05s.png</src>
						<width>100</width>
						<height>75</height>
					</thumbnail>
					<src>image05.png</src>
					<alt>After heap header overflow.</alt>
					<text>After heap header overflow.</text>
				</image>
				<image>
					<thumbnail>
						<src>image06s.png</src>
						<width>100</width>
						<height>53</height>
					</thumbnail>
					<src>image06.png</src>
					<alt>msvcrt.free() call for overflowed buffer.</alt>
					<text>msvcrt.free() call for overflowed buffer.</text>
				</image>
				<image>
					<thumbnail>
						<src>image07s.png</src>
						<width>100</width>
						<height>66</height>
					</thumbnail>
					<src>image07.png</src>
					<alt>Exception (ntdll.DbgBreakPoint()) raised by msvcrt.free() after detecting corrupted heap buffer.</alt>
					<text>Exception (ntdll.DbgBreakPoint()) raised by msvcrt.free() after detecting corrupted heap buffer.</text>
				</image>
			</images>
		</vulnerability>
	</vulnerabilities>
</advisory>