AnonSec Shell
Server IP : 172.67.157.199  /  Your IP : 3.15.150.226   [ Reverse IP ]
Web Server : Apache
System : Linux b70eb322-3aee-0c53-7c82-0db91281f2c6.secureserver.net 6.1.90-1.el9.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 2 12:09:22 EDT 2024 x86_64
User : root ( 0)
PHP Version : 8.0.30.2
Disable Function : NONE
Domains : 0 Domains
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/wp-content/plugins/defender-security/src/traits/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     [ BACKUP SHELL ]     [ JUMPING ]     [ MASS DEFACE ]     [ SCAN ROOT ]     [ SYMLINK ]     

Current File : /var/www/wp-content/plugins/defender-security/src/traits/ip.php
<?php
/**
 * Helper functions for IP related tasks.
 *
 * @package WP_Defender\Traits
 */

namespace WP_Defender\Traits;

use WP_Defender\Component\Http\Remote_Address;
use WP_Defender\Component\Smart_Ip_Detection;
use WP_Defender\Model\Setting\Firewall;

trait IP {

	/**
	 * Check if the IP is IPv4 address.
	 *
	 * @param  mixed $ip  IP address.
	 *
	 * @return mixed
	 */
	private function is_v4( $ip ) {
		return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 );
	}

	/**
	 * Check if the given IP address is an IPv6 address.
	 *
	 * @param  string $ip  The IP address to check.
	 *
	 * @return bool Returns true if the IP address is an IPv6 address, false otherwise.
	 */
	private function is_v6( $ip ) {
		return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 );
	}

	/**
	 * Check if IPv6 is supported.
	 *
	 * @return bool
	 */
	private function is_v6_support(): bool {
		return defined( 'AF_INET6' );
	}

	/**
	 * Convert IPv4 address to IPv6 address.
	 *
	 * @param  string $ip  IPv4 address.
	 *
	 * @return bool|string
	 */
	private function expand_ip_v6( $ip ) {
		$hex = unpack( 'H*hex', inet_pton( $ip ) );

		return substr( preg_replace( '/([A-f0-9]{4})/', '$1:', $hex['hex'] ), 0, - 1 );
	}

	/**
	 * Convert IPv6 address to binary.
	 *
	 * @param  string $inet  The packed data.
	 * @src https://stackoverflow.com/a/7951507
	 *
	 * @return string
	 */
	private function ine_to_bits( $inet ): string {
		$unpacked = unpack( 'a16', $inet );
		$unpacked = str_split( $unpacked[1] );
		$binaryip = '';
		foreach ( $unpacked as $char ) {
			$binaryip .= str_pad( decbin( ord( $char ) ), 8, '0', STR_PAD_LEFT );
		}

		return $binaryip;
	}

	/**
	 * Compare if an IPv4 address is within a specified range.
	 *
	 * @param  string $ip  The IPv4 address to compare.
	 * @param  string $first_in_range  The lower bound of the range.
	 * @param  string $last_in_range  The upper bound of the range.
	 *
	 * @return bool Returns true if the IP address is within the range, false otherwise.
	 */
	private function compare_v4_in_range( $ip, $first_in_range, $last_in_range ): bool {
		$low  = sprintf( '%u', ip2long( $first_in_range ) );
		$high = sprintf( '%u', ip2long( $last_in_range ) );

		$cip = sprintf( '%u', ip2long( $ip ) );
		if ( $high >= $cip && $cip >= $low ) {
			return true;
		}

		return false;
	}

	/**
	 * Compare if an IPv6 address is within a specified range.
	 *
	 * @param  string $ip  The IPv6 address to compare.
	 * @param  string $first_in_range  The lower bound of the range.
	 * @param  string $last_in_range  The upper bound of the range.
	 *
	 * @return bool Returns true if the IP address is within the range, false otherwise.
	 */
	private function compare_v6_in_range( $ip, $first_in_range, $last_in_range ): bool {
		$first_in_range = inet_pton( $this->expand_ip_v6( $first_in_range ) );
		$last_in_range  = inet_pton( $this->expand_ip_v6( $last_in_range ) );
		$ip             = inet_pton( $this->expand_ip_v6( $ip ) );

		if ( ( strlen( $ip ) === strlen( $first_in_range ) )
			&& ( $ip >= $first_in_range && $ip <= $last_in_range ) ) {
			return true;
		} else {
			return false;
		}
	}


	/**
	 * Compares an IPv4 address with a CIDR block.
	 *
	 * @param  string $ip  The IPv4 address to compare.
	 * @param  string $block  The CIDR block to compare against.
	 *
	 * @return bool Returns true if the IP address is within the CIDR block, false otherwise.
	 */
	private function compare_cidrv4( $ip, $block ): bool {
		[ $subnet, $bits ] = explode( '/', $block );
		if ( is_null( $bits ) ) {
			$bits = 32;
		}
		$ip      = ip2long( $ip );
		$subnet  = ip2long( $subnet );
		$mask    = - 1 << ( 32 - $bits );
		$subnet &= $mask;// nb: in case the supplied subnet wasn't correctly aligned.

		return ( $ip & $mask ) === $subnet;
	}

	/**
	 * Compares an IPv6 address with a CIDR block.
	 *
	 * @param  string $ip  The IPv6 address to compare.
	 * @param  string $block  The CIDR block to compare against.
	 *
	 * @return bool Returns true if the IP address is within the CIDR block, false otherwise.
	 */
	private function compare_cidrv6( $ip, $block ): bool {
		$ip                = $this->expand_ip_v6( $ip );
		$ip                = inet_pton( $ip );
		$b_ip              = $this->ine_to_bits( $ip );
		[ $subnet, $bits ] = explode( '/', $block );
		$subnet            = $this->expand_ip_v6( $subnet );
		$subnet            = inet_pton( $subnet );
		$b_subnet          = $this->ine_to_bits( $subnet );

		$ip_net_bits = substr( $b_ip, 0, $bits );
		$subnet_bits = substr( $b_subnet, 0, $bits );

		return $ip_net_bits === $subnet_bits;
	}

	/**
	 * Compare ip2 to ip1, true if ip2>ip1, false if not.
	 *
	 * @param  string $ip1  The first IP address to compare.
	 * @param  string $ip2  The second IP address to compare.
	 *
	 * @return bool Returns true if ip2 is greater than ip1, false otherwise.
	 */
	public function compare_ip( $ip1, $ip2 ): bool {
		if ( $this->is_v4( $ip1 ) && $this->is_v4( $ip2 ) ) {
			if ( sprintf( '%u', ip2long( $ip2 ) ) - sprintf( '%u', ip2long( $ip1 ) ) > 0 ) {
				return true;
			}
		} elseif ( $this->is_v6( $ip1 ) && $this->is_v6( $ip2 ) && $this->is_v6_support() ) {
			$ip1 = inet_pton( $this->expand_ip_v6( $ip1 ) );
			$ip2 = inet_pton( $this->expand_ip_v6( $ip2 ) );

			return $ip2 > $ip1;
		}

		return false;
	}

	/**
	 * Compare if an IP address is within a specified range.
	 *
	 * @param  string $ip  The IP address to compare.
	 * @param  string $first_in_range  The lower bound of the range.
	 * @param  string $last_in_range  The upper bound of the range.
	 *
	 * @return bool Returns true if the IP address is within the range, false otherwise.
	 */
	public function compare_in_range( $ip, $first_in_range, $last_in_range ): bool {
		if ( $this->is_v4( $first_in_range ) && $this->is_v4( $last_in_range ) ) {
			return $this->compare_v4_in_range( $ip, $first_in_range, $last_in_range );
		} elseif ( $this->is_v6( $first_in_range ) && $this->is_v6( $last_in_range ) && $this->is_v6_support() ) {
			return $this->compare_v6_in_range( $ip, $first_in_range, $last_in_range );
		}

		return false;
	}

	/**
	 * Compares an IP address with a CIDR block.
	 *
	 * @param  string $ip  The IP address to compare.
	 * @param  string $block  The CIDR block to compare against.
	 *
	 * @return bool Returns true if the IP address is within the CIDR block, false otherwise.
	 */
	public function compare_cidr( $ip, $block ): bool {
		[ $subnet, $bits ] = explode( '/', $block );
		if ( $this->is_v4( $ip ) && $this->is_v4( $subnet ) ) {
			return $this->compare_cidrv4( $ip, $block );
		} elseif ( $this->is_v6( $ip ) && $this->is_v6( $subnet ) && $this->is_v6_support() ) {
			return $this->compare_cidrv6( $ip, $block );
		}

		return false;
	}

	/**
	 * $ip an be single ip, or a range like xxx.xxx.xxx.xxx - xxx.xxx.xxx.xxx or CIDR.
	 *
	 * @param  string $ip  The IP address to validate.
	 *
	 * @return bool
	 */
	public function validate_ip( $ip ): bool {
		if (
			! stristr( $ip, '-' )
			&& ! stristr( $ip, '/' )
			&& filter_var( $ip, FILTER_VALIDATE_IP ) ) {
			// Only ip, no '-', '/' symbols.
			return true;
		} elseif ( stristr( $ip, '-' ) ) {
			$ips = explode( '-', $ip );
			foreach ( $ips as $ip_key ) {
				if ( ! filter_var( $ip_key, FILTER_VALIDATE_IP ) ) {
					return false;
				}
			}
			if ( $this->compare_ip( $ips[0], $ips[1] ) ) {
				return true;
			}
		} elseif ( stristr( $ip, '/' ) ) {
			[ $ip, $bits ] = explode( '/', $ip );
			if ( filter_var( $ip, FILTER_VALIDATE_IP ) && filter_var( $bits, FILTER_VALIDATE_INT ) ) {
				if ( $this->is_v4( $ip ) && 0 <= $bits && $bits <= 32 ) {
					return true;
				} elseif ( $this->is_v6( $ip ) && 0 <= $bits && $bits <= 128 && $this->is_v6_support() ) {
					return true;
				}
			}
		}

		return false;
	}

	/**
	 * Display a message if IP is non-valid. The cases:
	 * 1) single IP (no '-', '/' symbols),
	 * 2) IP range,
	 * 3) CIDR.
	 * Ignore cases with private, reserved ranges.
	 *
	 * @src https://en.wikipedia.org/wiki/IPv4#Special-use_addresses
	 * @src https://en.wikipedia.org/wiki/IPv6#Special-use_addresses
	 *
	 * @param  mixed $ip  IP address.
	 *
	 * @return array
	 */
	public function display_validation_message( $ip ): array {
		$errors = array();
		// Case 1: single IP.
		if (
			! stristr( $ip, '-' )
			&& ! stristr( $ip, '/' )
			&& ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
			$errors[] = sprintf(
			/* translators: %s: IP value. */
				esc_html__( '%s – invalid format', 'defender-security' ),
				'<b>' . $ip . '</b>'
			);
			// Case 2: IP range.
		} elseif ( stristr( $ip, '-' ) ) {
			$ips = explode( '-', $ip );
			foreach ( $ips as $ip_key ) {
				if ( ! filter_var( $ip_key, FILTER_VALIDATE_IP ) ) {
					$errors[] = sprintf(
					/* translators: %s: IP value. */
						esc_html__( '%s – invalid format', 'defender-security' ),
						'<b>' . $ip_key . '</b>'
					);
				}
			}
			if ( ! $this->compare_ip( $ips[0], $ips[1] ) ) {
				$errors[] = sprintf(
				/* translators: 1. IP value. 2. IP value. */
					esc_html__( 'Can\'t compare %1$s with %2$s.', 'defender-security' ),
					'<b>' . $ips[1] . '</b>',
					'<b>' . $ips[0] . '</b>'
				);
			}
			// Case 3: CIDR.
		} elseif ( stristr( $ip, '/' ) ) {
			[ $ip, $bits ] = explode( '/', $ip );
			if ( filter_var( $ip, FILTER_VALIDATE_IP ) && filter_var( $bits, FILTER_VALIDATE_INT ) ) {
				if ( ! $this->is_v4( $ip ) || 0 > $bits || $bits > 32 ) {
					if ( ! $this->is_v6( $ip ) || 0 > $bits || $bits > 128 || ! $this->is_v6_support() ) {
						$errors[] = sprintf(
						/* translators: %s: IP value. */
							esc_html__( '%s – address out of range', 'defender-security' ),
							'<b>' . $ip . '</b>'
						);
					}
				}
			} else {
				$errors[] = sprintf(
				/* translators: %s: IP value. */
					esc_html__( '%s – invalid format', 'defender-security' ),
					'<b>' . $ip . '</b>'
				);
			}
		}

		// @since 2.6.3
		return (array) apply_filters( 'wd_display_ip_validations', $errors );
	}

	/**
	 * Validate IP.
	 *
	 * @param  mixed $ip  IP address.
	 *
	 * @return bool
	 */
	public function check_validate_ip( $ip ): bool {
		// Validate the localhost IP address.
		if ( in_array( $ip, array( '127.0.0.1', '::1' ), true ) ) {
			return true;
		}

		$filter_flags = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
		// @since 2.4.7
		if ( apply_filters( 'wp_defender_filtered_internal_ip', false ) ) {
			// Todo: improve display of IP log when filtering reserved or private IPv4/IPv6 ranges.
			$filter_flags = $filter_flags | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
		}

		if ( false === filter_var( $ip, FILTER_VALIDATE_IP, $filter_flags ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Get user IP.
	 *
	 * @return array
	 */
	public function get_user_ip(): array {
		$service = wd_di()->get( Smart_Ip_Detection::class );
		if ( $service->is_smart_ip_detection_enabled() ) {
			$ip_detail = $service->get_smart_ip_detection_details();
			$ips       = isset( $ip_detail[0] ) ? array( $ip_detail[0] ) : array();
		} else {
			$remote_addr = wd_di()->get( Remote_Address::class );
			$ips         = (array) $remote_addr->get_ip_address();
		}

		return $this->filter_user_ips( $ips );
	}

	/**
	 * Get user IP header.
	 *
	 * @return string
	 */
	public function get_user_ip_header(): string {
		$ip_header = '';

		$service = wd_di()->get( Smart_Ip_Detection::class );
		if ( $service->is_smart_ip_detection_enabled() ) {
			$ip_detail = $service->get_smart_ip_detection_details();
			$ip_header = isset( $ip_detail[1] ) ? $ip_detail[1] : '';
		} else {
			$model       = wd_di()->get( Firewall::class );
			$remote_addr = wd_di()->get( Remote_Address::class );
			$ip_header   = $remote_addr->get_http_ip_header_value( esc_html( $model->http_ip_header ) );
		}

		return $ip_header;
	}

	/**
	 * Checks if an IP address is in the correct format within a given array of IP addresses.
	 *
	 * @param  string $ip  The IP address to check.
	 * @param  array  $arr_ips  An array of IP addresses to check against.
	 *
	 * @return bool Returns true if the IP address is in the correct format within the array, false otherwise.
	 */
	public function is_ip_in_format( $ip, $arr_ips ): bool {
		foreach ( $arr_ips as $wip ) {
			if ( false === strpos( $wip, '-' ) && false === strpos( $wip, '/' ) && trim( $wip ) === $ip ) {
				return true;
			} elseif ( false !== strpos( $wip, '-' ) ) {
				$ips = explode( '-', $wip );
				if ( $this->compare_in_range( $ip, $ips[0], $ips[1] ) ) {
					return true;
				}
			} elseif ( false !== strpos( $wip, '/' ) && $this->compare_cidr( $ip, $wip ) ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Filter user IPs.
	 * This function takes an array of user IPs, applies the 'defender_user_ip'
	 * filter to each IP, and returns a unique array of filtered values.
	 *
	 * @param  array $ips  An array of user IPs.
	 *
	 * @return array An array of unique, filtered user IPs.
	 * @since 4.4.2
	 */
	public function filter_user_ips( array $ips ): array {
		$ips_filtered = array();
		foreach ( $ips as $ip ) {
			/**
			 * Filters the user IP.
			 *
			 * @param  string  $ip  The user IP.
			 */
			$ips_filtered[] = apply_filters( 'defender_user_ip', $ip );
		}

		return array_unique( $ips_filtered );
	}

	/**
	 * Use $_SERVER['REMOTE_ADDR'] as the first protection layer to avoid spoofed headers.
	 *
	 * @param  string $blocked_ip  The IP address to check.
	 *
	 * @return string
	 */
	public function check_ip_by_remote_addr( $blocked_ip ): string {
		$ip_addr = defender_get_data_from_request( 'REMOTE_ADDR', 's' );

		return ! empty( $ip_addr ) ? $ip_addr : $blocked_ip;
	}

	/**
	 * Check if the given IP is a private IP.
	 *
	 * @param  string $ip  The IP address to check.
	 *
	 * @return bool True if the IP is a private IP, false otherwise.
	 */
	public function is_private_ip( string $ip ): bool {
		return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE ) === false;
	}
}

Anon7 - 2022
AnonSec Team