Accueil Cross-Site Scripting (reflected) dans le plugin Wordpress Verifyne
Post
Annuler

Cross-Site Scripting (reflected) dans le plugin Wordpress Verifyne

Présentation du plugin

Le plugin Verifyne se présente de cette façon :

This is the WordPress plugin for use with the verifyne.me android app. It allows you to login to you WordPress site without having to enter a username or password while increasing security.

All you have to do is scan a QR code, confirm the login on your android smartphone and you are logged in automatically.

Verifyne uses modern elliptic curve (ed25519) cryptography for highest security. It allows user authentication without having to trust a third-party or foreign servers.

C’est donc un plugin qui permet une autre méthode d’authentification que celle via mot de passe.

La version testée est la 0.3.4 et date d’il y a 8 ans au moment de ces lignes.

La vulnérabilité

Le script wp-verifyne.php du plugin défini une classe dont le constructeur en instancie d’autres :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Wordpress_Verifyne_Plugin {                                                                                      
                                                                                                                       
    const PLUGIN_VERSION_NUMBER = 5;                                                                                   
                                                                                                                       
    #############################################################################                                      
    # VARIABLES                                                                                                        
    #############################################################################                                      
                                                                                                                       
    private $login_page_handler;                                                                                       
    private $userprofile_handler;                                                                                      
    private $admin_settings;                                                                                           
                                                                                                                       
    #############################################################################                                      
    # CONSTRUCTOR /  SINGLETON                                                                                         
    #############################################################################                                      
                                                                                                                       
    private static $instance = NULL;                                                                                   
                                                                                                                       
    public static function get_instance() {                                                                            
        if(NULL === self::$instance) {                                                                                 
            self::$instance = new self;                                                                                
        }                                                                                                              
        return self::$instance;                                                                                        
    }                                                                                                                  
                                                                                                                       
    function __construct() {                                                                                           
        # Load instances                                                                                               
        $this->login_page_handler  = new Wordpress_Verifyne_Loginpage_Handler();                                       
        $this->userprofile_handler = new Wordpress_Verifyne_Userprofile_Handler();                                     
        $this->admin_settings      = new Wordpress_Verifyne_Adminsettings(plugin_basename(__FILE__));                  
        # Register hooks                                                                                               
        add_action( 'init', array( $this, 'set_verifyne_cookie' ));                                                    
    }
    --- snip ---

C’est dans le fichier vf_login_page.php que l’on trouve la classe Wordpress_Verifyne_Loginpage_Handler :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Wordpress_Verifyne_Loginpage_Handler {                                                                           

    function __construct() {                                                                                           
        add_action( 'login_form', array( $this, 'on_login_form_load' ));                                               
    }                                                                                                                  
                                                                                                                       
    /**                                                                                                                
    * Enqueue styles and decide what to do                                                                             
    *                                                                                                                  
    * Evaluates "action" parameter.                                                                                    
    */                                                                                                                 
    function on_login_form_load() {                                                                                    
        # Load CSS                                                                                                     
        wp_enqueue_style('wp-verifyne-style', plugin_dir_url( __FILE__ ) . 'wp-verifyne.css', array());                
        wp_enqueue_script('jquery');                                                                                   
                                                                                                                       
        # Get action parameter                                                                                         
        $action = $_GET["action"];                                                                                     
                                                                                                                       
        # Someone clicked the verifyne button                                                                          
        if("vf_show" === $action) {                                                                                    
            $this->handle_show_request();                                                                              
            return;                                                                                                    
        }                                                                                                              
                                                                                                                       
        # Someone scanned the QR code and needs to be verified                                                         
        if("vf_verify" === $action) {                                                                                  
            $ret = $this->handle_verify_request();                                                                     
            if( is_wp_error( $ret )) {                                                                                 
                print("<div id='verifyne-state-div' class='verifyne-center'>".$ret->get_error_message()."<br><a href='?action=vf_show'>Try again</a></div>");
            }                                                                                                          
            return;                                                                                                    
        }                                                                                                              
                                                                                                                       
        # Remember redirect_to                                                                                         
        $redir_param = isset($_REQUEST["redirect_to"]) ? "&redirect_to=".$_REQUEST["redirect_to"] : "";                
                                                                                                                       
        # Get the button image URL                                                                                     
        $login_img_url = plugins_url( 'vf_button_login.png', __FILE__ );                                               
                                                                                                                       
        # Display the button                                                                                           
        echo "<a href='?action=vf_show".$redir_param."'><div class='verifyne-login-button-container'><img class='verifyne-login-button' src='".$login_img_url."'></div></a>";
                                                                                                                       
    }
    --- snip ---

La classe hooke la fonction login_form de Wordpress pour rajouter des éléments HTML.

On voit que le paramètre redirect_to est récupéré et affiché tel quel, ce qui laisse un attaquant injecter tout ce qu’il souhaite.

PoC :

1
http://localhost:8000/wp-login.php?redirect_to=%27%3E%3C%2Fa%3E%3CScRiPt%3Ealert%28%2FXSS%2F%29%3C%2FsCrIpT%3E&reauth=1
Cet article est sous licence CC BY 4.0 par l'auteur.