####################################################################### 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@autistici.org 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 comparison 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 the data from MThd 076636D1 |. 53 PUSH EBX ; previously allocated buffer 076636D2 |. E8 77C80000 CALL ; 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. #######################################################################