Post

Wordpress Redux Framework Class Redux Helpers Php Sensitive Information Leakage Vulnerability Cve 2021 38314

Wordpress Redux Framework Class Redux Helpers Php Sensitive Information Leakage Vulnerability Cve 2021 38314

WordPress Redux Framework class-redux-helpers.php Sensitive information leakage vulnerability CVE-2021-38314

Vulnerability Description

In August 2021, there was an unauthorized sensitive information leakage vulnerability in Redux Framework. The CVE number is CVE-2021-38314, affecting v4.2.11 and below. Sending a specific request packet can obtain server sensitive information without authorization.

Vulnerability Impact

Redux Framework <= v4.2.11

Plugin Name

Redux Framework

https://github.com/reduxframework/redux-framework

Vulnerability reappears

The impact range is below v4.211. Let’s take a look at the update differences between versions.

img

Here all the functions registered with add_action are deleted. Please check the function related code for local installation.

img

1
2
3
4
5
6
7
8
9
10
$support_hash = md5( md5( Redux_Functions_Ex::hash_key() . '-redux' ) . '-support' );
add_action( 'wp_ajax_nopriv_' . $support_hash, array( 'Redux_Helpers', 'support_args' ) );
add_action( 'wp_ajax_' . $support_hash, array( 'Redux_Helpers', 'support_args' ) );
$hash_arg = md5( trailingslashit( network_site_url() ) . '-redux' );
add_action( 'wp_ajax_nopriv_' . $hash_arg, array( 'Redux_Helpers', 'hash_arg' ) );
add_action( 'wp_ajax_' . $hash_arg, array( 'Redux_Helpers', 'hash_arg' ) );
add_action( 'wp_ajax_redux_support_hash', array( 'Redux_Functions', 'support_hash' ) );

add_filter( 'redux/tracking/options', array( 'Redux_Helpers', 'redux_stats_additions' ) );
		

View the add_action registered functions hash_arg() and support_args()

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public static function hash_arg() {
			echo esc_html( md5( Redux_Functions_Ex::hash_key() . '-redux' ) );
			die();
		}
public static function support_args() {
			header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
			header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . 'GMT' );
			header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
			header( 'Cache-Control: no-store, no-cache, must-revalidate' );
			header( 'Cache-Control: post-check=0, pre-check=0', false );
			header( 'Pragma: no-cache' );

			$instances = Redux::all_instances();

			if ( isset( $_REQUEST['i'] ) && ! empty( $_REQUEST['i'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
				if ( is_array( $instances ) && ! empty( $instances ) ) {
					foreach ( $instances as $opt_name => $data ) {
						if ( md5( $opt_name . '-debug' ) === $_REQUEST['i'] ) { // phpcs:ignore WordPress.Security.NonceVerification
							$array = $data;
						}
					}
				}

				if ( isset( $array ) ) {

					// We only want the extension names and versions.
					$array->extensions = self::get_extensions( $opt_name );
					$to_return         = array();

					// Filter out all the unwanted data.
					foreach ( $array as $key => $value ) {
						if ( in_array(
							$key,
							array(
								// 'fields',
								'extensions',
								'sections',
								'args',
								// 'field_types'
							),
							true
						) ) {
							$to_return[ $key ] = $value;
						} else { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement
							// phpcs:ignore Squiz.PHP.CommentedOutCode
							/* echo $key.PHP_EOL; */
						}
					}
					$array = $to_return;
				} else {
					die();
				}
			} else {
				$array = self::get_statistics_object();
				if ( is_array( $instances ) && ! empty( $instances ) ) {
					$array['instances'] = array();
					foreach ( $instances as $opt_name => $data ) {
						$array['instances'][] = $opt_name;
					}
				}
				$array['key'] = md5( Redux_Functions_Ex::hash_key() );
			}

			ksort( $array ); // Let's make that pretty.

			// phpcs:ignored WordPress.PHP.NoSilencedErrors, WordPress.Security.EscapeOutput
			echo @htmlspecialchars( @wp_json_encode( $array, true ), ENT_QUOTES );

			die();
		}

support_args() function $_REQUEST[‘i’] is empty, and comes to another branch

1
2
3
4
5
6
7
8
9
10
} else {
				$array = self::get_statistics_object();
				if ( is_array( $instances ) && ! empty( $instances ) ) {
					$array['instances'] = array();
					foreach ( $instances as $opt_name => $data ) {
						$array['instances'][] = $opt_name;
					}
				}
				$array['key'] = md5( Redux_Functions_Ex::hash_key() );
			}

Track the get_statistics_object() function, which can obtain information about environment variables such as plugins

img

Go back and see that the function is wp_ajax_nopriv_* and can be called unauthorizedimg

The variable $support_hash is required, and the hash_key() method is tracked.

1
$support_hash = md5( md5( Redux_Functions_Ex::hash_key() . '-redux' ) . '-support' );

img

The AUTH_KEY parameter exists in wp-config.php, which is a random value

img

Here comes the hash_arg() functionimg

1
2
3
4
public static function hash_arg() {
			echo esc_html( md5( Redux_Functions_Ex::hash_key() . '-redux' ) );
			die();
		}

Here the function in Redux_Functions_Ex::hash_key() is called, and the md5 value is returned.

Going back to the code just now, we can find that the result is also the parameters we need to know about $support_hash. The following is the equivalent replacement.

1
$support_hash = md5(hash_arg(). '-support' );

img

In this way we get a utilization chain

1
2
3
4
5
6
7
8
9
$hash_arg = md5( trailingslashit( network_site_url() ) . '-redux' );
add_action( 'wp_ajax_nopriv_' . $hash_arg, array( 'Redux_Helpers', 'hash_arg' ) );
|
获取 md5( Redux_Functions_Ex::hash_key() . '-redux') 
|
$support_hash = md5( md5( Redux_Functions_Ex::hash_key() . '-redux' ) . '-support' );
add_action( 'wp_ajax_nopriv_' . $support_hash, array( 'Redux_Helpers', 'support_args' ) );
|
调用函数 support_args 获取系统敏感信息

img

img

img

img

Successfully obtained plug-in version and other related information

This post is licensed under CC BY 4.0 by the author.