[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

in_midi multiple vulnerabilities in Winamp 5.61



#######################################################################

                             Luigi Auriemma

Application:  Winamp
              http://www.winamp.com
Versions:     <= 5.61
Platforms:    Windows
Bugs:         A] in_midi Controller messages heap overflow
              B] in_midi Note On messages heap overflow
              C] in_midi MTrk heap overflow
Date:         27 Jun 2011
Author:       Luigi Auriemma
              e-mail: aluigi@xxxxxxxxxxxxx
              web:    aluigi.org


#######################################################################


1) Introduction
2) Bugs
3) The Code
4) Fix


#######################################################################

===============
1) Introduction
===============


Winamp is one of the most diffused and appreciated media players for
Windows.


#######################################################################

=======
2) Bugs
=======

--------------------------------------------
A] in_midi Controller messages heap overflow
--------------------------------------------

The Controller status message of the MIDI files is an 8bit value from
0xb0 to 0xbf followed by the controller number and the value to assign.

The in_midi native plugin of Winamp follows the specifications
allocating a buffer that fits the 128 instruments but the "Controller
number" is an 8bit value which arrives to 255 and there are no checks
to avoid the usage of this additional memory.

The result is a heap overflow and its usual effects like arbitrary
memory freeing, write4 and so on.
From in_midi.dll:

  07662918  |. 8A4D 08              MOV CL,BYTE PTR SS:[EBP+8]
                                    ; "Controller message"
  0766291B  |. 56                   PUSH ESI
  0766291C  |. 8BF0                 MOV ESI,EAX
  0766291E  |. 8AC1                 MOV AL,CL
  07662920  |. 24 F0                AND AL,0F0
  07662922  |. 80E1 0F              AND CL,0F
  07662925  |. 884D FF              MOV BYTE PTR SS:[EBP-1],CL
  07662928  |. 3C B0                CMP AL,0B0
  0766292A  |. 0F85 B1000000        JNZ in_midi.076629E1
  07662930  |. 33D2                 XOR EDX,EDX
  07662932  |. 3915 98896707        CMP DWORD PTR DS:[7678998],EDX
  07662938  |. 74 1B                JE SHORT in_midi.07662955
  0766293A  |. 80F9 09              CMP CL,9
  0766293D  |. 75 16                JNZ SHORT in_midi.07662955
  0766293F  |. 3856 01              CMP BYTE PTR DS:[ESI+1],DL
  07662942  |. 75 11                JNZ SHORT in_midi.07662955
  07662944  |. 8A06                 MOV AL,BYTE PTR DS:[ESI]
                                    ; "Controller Number"
  07662946  |. 3AC2                 CMP AL,DL
  07662948  |. 74 04                JE SHORT in_midi.0766294E
  0766294A  |. 3C 20                CMP AL,20
  0766294C  |. 75 07                JNZ SHORT in_midi.07662955
  0766294E  |> 33C0                 XOR EAX,EAX
  07662950  |. E9 E4010000          JMP in_midi.07662B39
  07662955  |> 0FB6C1               MOVZX EAX,CL
  07662958  |. 0FB60E               MOVZX ECX,BYTE PTR DS:[ESI]
                                    ; "Controller Number"
  0766295B  |. 8945 F8              MOV DWORD PTR SS:[EBP-8],EAX
  0766295E  |. C165 F8 07           SHL DWORD PTR SS:[EBP-8],7
  07662962  |. 034D F8              ADD ECX,DWORD PTR SS:[EBP-8]
  07662965  |. 8945 FC              MOV DWORD PTR SS:[EBP-4],EAX
  07662968  |. 8A46 01              MOV AL,BYTE PTR DS:[ESI+1]  ; "value"
  0766296B  |. 884419 08            MOV BYTE PTR DS:[ECX+EBX+8],AL

and the arbitrary free() exploitation:

  07662BE5  |> 8DBE 24080000        LEA EDI,DWORD PTR DS:[ESI+824]
  07662BEB  |. C74424 10 10000000   MOV DWORD PTR SS:[ESP+10],10
  07662BF3  |> 8B07                 /MOV EAX,DWORD PTR DS:[EDI]
                                    ; our 32 bit, 0x61616161
  07662BF5  |. 3BC5                 |CMP EAX,EBP
  07662BF7  |. 74 06                |JE SHORT in_midi.07662BFF
  07662BF9  |. 50                   |PUSH EAX
  07662BFA  |. FFD3                 |CALL EBX   ; MSVCR90.free
  07662BFC  |. 59                   |POP ECX
  07662BFD  |. 892F                 |MOV DWORD PTR DS:[EDI],EBP
  07662BFF  |> 83C7 04              |ADD EDI,4
  07662C02  |. FF4C24 10            |DEC DWORD PTR SS:[ESP+10]
  07662C06  |.^75 EB                \JNZ SHORT in_midi.07662BF3


-----------------------------------------
B] in_midi Note On messages heap overflow
-----------------------------------------

The Note On messages (from 0x90 to 0x9f) have the same format of the
Controller ones and also in this case Winamp doesn't check the channel
number specified in the file leading to another heap oveflow using
channels greater than 127.


-----------------------------
C] in_midi MTrk heap overflow
-----------------------------

Winamp calculates the size of the memory to allocate through the
parsing of the chunk size of all the MTrk fields.
A combination of signed comparisons, integer overflows and
portions of data copied in predictable positions allow the
exploiting of the relative heap overflow:

  07663738  |> 8B45 0C           /MOV EAX,DWORD PTR SS:[EBP+C]
                                 ; current total size
  0766373B  |> 813C38 4D54726B   |CMP DWORD PTR DS:[EAX+EDI],6B72544D
                                 ; MUST be equal to "MTrk"
  07663742  |. 75 5A             |JNZ SHORT in_midi.0766379E
  07663744  |. 8D48 0C           |LEA ECX,DWORD PTR DS:[EAX+C]  ; +12
  07663747  |. 3B4D 10           |CMP ECX,DWORD PTR SS:[EBP+10]
  0766374A  |. 7F 52             |JG SHORT in_midi.0766379E
                                 ; signed comparison
  0766374C  |. 8B4C38 04         |MOV ECX,DWORD PTR DS:[EAX+EDI+4]
                                 ; get "next" MTrk size
  07663750  |. 83C0 08           |ADD EAX,8                     ; +8
  07663753  |. 8945 0C           |MOV DWORD PTR SS:[EBP+C],EAX
  07663756  |. 8945 FC           |MOV DWORD PTR SS:[EBP-4],EAX
  07663759  |. E8 7A9D0000       |CALL in_midi.0766D4D8     ; ntohl(ecx)
  0766375E  |. 0145 0C           |ADD DWORD PTR SS:[EBP+C],EAX
  07663761  |. 8B45 10           |MOV EAX,DWORD PTR SS:[EBP+10]
  07663764  |. 3945 0C           |CMP DWORD PTR SS:[EBP+C],EAX
  07663767  |. 7F 08             |JG SHORT in_midi.07663771 ; signed comp
  07663769  |. 46                |INC ESI
  0766376A  |. 3B75 F8           |CMP ESI,DWORD PTR SS:[EBP-8]
  0766376D  |.^7C C9             \JL SHORT in_midi.07663738
  ...
  076635D5  |> 53                PUSH EBX
  076635D6  |. 56                PUSH ESI
  076635D7  |. 8B75 10           MOV ESI,DWORD PTR SS:[EBP+10]
  076635DA  |. 8D46 10           LEA EAX,DWORD PTR DS:[ESI+10]
  076635DD  |. 50                PUSH EAX
                                 ; controlled miscalculated size
  076635DE  |. FF15 B0316707     CALL DWORD PTR DS:[<&MSVCR90.malloc>]
                                 ; malloc
  ...
  076636CF  |> 57                PUSH EDI           ; 0xFFFFF81F
  076636D0  |. 51                PUSH ECX           ; all data from MThd
  076636D1  |. 53                PUSH EBX           ; allocated buffer
  076636D2  |. E8 77C80000       CALL <JMP.&MSVCR90.memcpy> ; memcpy

And the following is the situation caused by my proof-of-concept
during the total size calculation with EDI 01246298 and EAX FFFFF816,
so the "dword[EAX+EDI] == 6B72544D" check is perfectly bypassed:

01246188 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 rkMTrkMTrkMTrkMT
01246198 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 rkMTrkMTrkMTrkMT
012461A8 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 rkMTrkMTrkMTrkMT
012461B8 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 rkMTrkMTrkMTrkMT
012461C8 72 6B 4D 54 72 6B 4D 54 72 6B 4D 54 72 6B AB AB rkMTrkMTrkMTrkÂÂ
012461D8 AB AB AB AB AB AB EE FE 00 00 00 00 00 00 00 00 ÂÂÂÂÂÂÃÃ........
012461E8 15 00 A3 21 EE 07 18 01 50 DC 22 01 20 00 00 00 ..Â!Ã...PÃ". ...
012461F8 19 00 00 00 88 C2 22 01 08 00 00 00 00 00 00 00 ....ËÃ".........
01246208 00 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 ................
01246218 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01246228 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01246238 00 00 00 00 00 00 00 00 00 00 00 00 C0 53 23 01 ............ÃS#.
01246248 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01246258 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01246268 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01246278 00 00 00 00 01 00 00 00 AB AB AB AB AB AB AB AB ........ÂÂÂÂÂÂÂÂ
01246288 00 00 00 00 00 00 00 00 93 21 15 00 81 07 1A 01 ........â!..Â...
01246298 4D 54 68 64 00 00 00 06 00 01 00 13 00 78 4D 54 MThd.........xMT
012462A8 72 6B FF FF F8 00 41 41 41 41 41 41 41 41 41 41 rkÃÃÃ.AAAAAAAAAA
012462B8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
012462C8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
012462D8 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA


#######################################################################

===========
3) The Code
===========


http://aluigi.org/poc/winamp_3.zip

winamp_3a.mid will exploit the arbitrary freeing of address 0x61616161.


#######################################################################

======
4) Fix
======


No fix.


#######################################################################


---
Luigi Auriemma
http://aluigi.org