Пример #1
0
 /**
  * Added compatibility for hosts that do not have inet_pton.
  *
  * @param $ip
  * @return bool|string
  */
 public static function _inet_pton($ip)
 {
     // IPv4
     if (preg_match('/^(?:\\d{1,3}(?:\\.|$)){4}/', $ip)) {
         $octets = explode('.', $ip);
         $bin = chr($octets[0]) . chr($octets[1]) . chr($octets[2]) . chr($octets[3]);
         return $bin;
     }
     // IPv6
     if (preg_match('/^((?:[\\da-f]{1,4}(?::|)){0,8})(::)?((?:[\\da-f]{1,4}(?::|)){0,8})$/i', $ip)) {
         if ($ip === '::') {
             return "";
         }
         $colon_count = wfWAFUtils::substr_count($ip, ':');
         $dbl_colon_pos = wfWAFUtils::strpos($ip, '::');
         if ($dbl_colon_pos !== false) {
             $ip = str_replace('::', str_repeat(':0000', ($dbl_colon_pos === 0 || $dbl_colon_pos === wfWAFUtils::strlen($ip) - 2 ? 9 : 8) - $colon_count) . ':', $ip);
             $ip = trim($ip, ':');
         }
         $ip_groups = explode(':', $ip);
         $ipv6_bin = '';
         foreach ($ip_groups as $ip_group) {
             $ipv6_bin .= pack('H*', str_pad($ip_group, 4, '0', STR_PAD_LEFT));
         }
         return wfWAFUtils::strlen($ipv6_bin) === 16 ? $ipv6_bin : false;
     }
     // IPv4 mapped IPv6
     if (preg_match('/^((?:0{1,4}(?::|)){0,5})(::)?ffff:((?:\\d{1,3}(?:\\.|$)){4})$/i', $ip, $matches)) {
         $octets = explode('.', $matches[3]);
         return "ÿÿ" . chr($octets[0]) . chr($octets[1]) . chr($octets[2]) . chr($octets[3]);
     }
     return false;
 }
Пример #2
0
 public function getGlobal($global)
 {
     if (wfWAFUtils::strpos($global, '.') === false) {
         return null;
     }
     list($prefix, $_global) = explode('.', $global);
     switch ($prefix) {
         case 'request':
             $method = "get" . ucfirst($_global);
             if (method_exists('wfWAFRequestInterface', $method)) {
                 return call_user_func(array($this->getRequest(), $method));
             }
             break;
         case 'server':
             $key = wfWAFUtils::strtoupper($_global);
             if (isset($_SERVER) && array_key_exists($key, $_SERVER)) {
                 return $_SERVER[$key];
             }
             break;
     }
     return null;
 }
Пример #3
0
    /**
     * @param array $failedParams
     * @param string $highlightParamFormat
     * @param string $highlightMatchFormat
     * @return string
     */
    public function highlightFailedParams($failedParams = array(), $highlightParamFormat = '[param]%s[/param]', $highlightMatchFormat = '[match]%s[/match]')
    {
        $highlights = array();
        // Cap at 50kb
        $maxRequestLen = 1024 * 50;
        $this->highlightParamFormat = $highlightParamFormat;
        $this->highlightMatchFormat = $highlightMatchFormat;
        if (is_array($failedParams)) {
            foreach ($failedParams as $paramKey => $categories) {
                foreach ($categories as $categoryKey => $failedRules) {
                    foreach ($failedRules as $failedRule) {
                        $rule = $failedRule['rule'];
                        /** @var wfWAFRuleComparisonFailure $failedComparison */
                        $failedComparison = $failedRule['failedComparison'];
                        $action = $failedRule['action'];
                        $paramKey = $failedComparison->getParamKey();
                        if (preg_match('/request\\.([a-z0-9]+)(?:\\[(.*?)\\](.*?))?$/i', $paramKey, $matches)) {
                            $global = $matches[1];
                            if (method_exists('wfWAFRequestInterface', "get" . ucfirst($global))) {
                                $highlight = array('match' => $failedComparison->getMatches());
                                if (isset($matches[2])) {
                                    $highlight['param'] = "{$matches['2']}{$matches['3']}";
                                }
                                $highlights[$global][] = $highlight;
                            }
                        }
                    }
                }
            }
        }
        $uri = $this->getURI();
        $queryStringPos = wfWAFUtils::strpos($uri, '?');
        if ($queryStringPos !== false) {
            $uri = wfWAFUtils::substr($uri, 0, $queryStringPos);
        }
        $queryString = $this->getQueryString();
        if ($queryString) {
            $uri .= '?' . http_build_query($queryString);
        }
        if (!empty($highlights['queryString'])) {
            foreach ($highlights['queryString'] as $matches) {
                if (!empty($matches['param'])) {
                    $this->highlightMatches = $matches['match'];
                    $uri = preg_replace_callback('/(&|\\?|^)(' . preg_quote(urlencode($matches['param']), '/') . ')=(.*?)(&|$)/', array($this, 'highlightParam'), $uri);
                }
            }
        }
        if (!empty($highlights['uri'])) {
            foreach ($highlights['uri'] as $matches) {
                if ($matches) {
                }
            }
            $uri = sprintf($highlightParamFormat, $uri);
        }
        $request = "{$this->getMethod()} {$uri} HTTP/1.1\n";
        $hasAuth = false;
        $auth = $this->getAuth();
        if (is_array($this->getHeaders())) {
            foreach ($this->getHeaders() as $header => $value) {
                switch (wfWAFUtils::strtolower($header)) {
                    case 'cookie':
                        // TODO: Hook up highlights to cookies
                        $cookies = '';
                        foreach ($this->getCookies() as $cookieName => $cookieValue) {
                            $cookies .= $cookieName . '=' . urlencode($cookieValue) . '; ';
                        }
                        $request .= 'Cookie: ' . trim($cookies) . "\n";
                        break;
                    case 'host':
                        $request .= 'Host: ' . $this->getHost() . "\n";
                        break;
                    case 'authorization':
                        $hasAuth = true;
                        if ($auth) {
                            $request .= 'Authorization: Basic ' . base64_encode($auth['user'] . ':' . $auth['password']) . "\n";
                        }
                        break;
                    default:
                        $request .= $header . ': ' . $value . "\n";
                        break;
                }
            }
        }
        if (!$hasAuth && $auth) {
            $request .= 'Authorization: Basic ' . base64_encode($auth['user'] . ':' . $auth['password']) . "\n";
        }
        $body = $this->getBody();
        $contentType = $this->getHeaders('Content-Type');
        if (is_array($body)) {
            if (wfWAFUtils::stripos($contentType, 'application/x-www-form-urlencoded') === 0) {
                $body = http_build_query($body);
                if (!empty($highlights['body'])) {
                    foreach ($highlights['body'] as $matches) {
                        if (!empty($matches['param'])) {
                            $this->highlightMatches = $matches['match'];
                            $body = preg_replace_callback('/(&|^)(' . preg_quote(urlencode($matches['param']), '/') . ')=(.*?)(&|$)/', array($this, 'highlightParam'), $body);
                        }
                    }
                }
            } else {
                if (preg_match('/^multipart\\/form\\-data; boundary=(.*?)$/i', $contentType, $boundaryMatches)) {
                    $boundary = $boundaryMatches[1];
                    $bodyArray = array();
                    foreach ($body as $key => $value) {
                        $bodyArray = array_merge($bodyArray, $this->reduceBodyParameter($key, $value));
                    }
                    $body = '';
                    foreach ($bodyArray as $param => $value) {
                        if (!empty($highlights['body'])) {
                            foreach ($highlights['body'] as $matches) {
                                if (!empty($matches['param']) && $matches['param'] === $param) {
                                    $value = sprintf($this->highlightParamFormat, $value);
                                    if (is_array($matches['match'][0])) {
                                        $replace = array();
                                        foreach ($matches['match'][0] as $key => $match) {
                                            $replace[$match] = sprintf($this->highlightMatchFormat, $match);
                                        }
                                        if ($replace) {
                                            $value = str_replace(array_keys($replace), $replace, $value);
                                        }
                                    } else {
                                        // preg_match
                                        $value = str_replace($matches['match'][0], sprintf($this->highlightMatchFormat, $matches['match'][0]), $value);
                                    }
                                    break;
                                }
                            }
                        }
                        $body .= <<<FORM
--{$boundary}
Content-Disposition: form-data; name="{$param}"

{$value}

FORM;
                    }
                    foreach ($this->getFiles() as $param => $file) {
                        $name = array_key_exists('name', $file) ? $file['name'] : '';
                        if (is_array($name)) {
                            continue;
                            // TODO: implement files as arrays
                        }
                        $mime = array_key_exists('type', $file) ? $file['type'] : '';
                        $value = '';
                        $lenToRead = $maxRequestLen - (wfWAFUtils::strlen($request) + wfWAFUtils::strlen($body) + 1);
                        if (array_key_exists('content', $file)) {
                            $value = $file['content'];
                        } else {
                            if ($lenToRead > 0 && file_exists($file['tmp_name'])) {
                                $handle = fopen($file['tmp_name'], 'r');
                                $value = fread($handle, $lenToRead);
                                fclose($handle);
                            }
                        }
                        if (!empty($highlights['fileNames'])) {
                            foreach ($highlights['fileNames'] as $matches) {
                                if (!empty($matches['param']) && $matches['param'] === $param) {
                                    $name = sprintf($this->highlightParamFormat, $name);
                                    $name = str_replace($matches['match'][0], sprintf($this->highlightMatchFormat, $matches['match'][0]), $name);
                                    break;
                                }
                            }
                        }
                        $body .= <<<FORM
--{$boundary}
Content-Disposition: form-data; name="{$param}"; filename="{$name}"
Content-Type: {$mime}
Expires: 0

{$value}

FORM;
                    }
                    if ($body) {
                        $body .= "--{$boundary}--\n";
                    }
                }
            }
        }
        if (!is_string($body)) {
            $body = '';
        }
        $request .= "\n" . $body;
        if (wfWAFUtils::strlen($request) > $maxRequestLen) {
            $request = wfWAFUtils::substr($request, 0, $maxRequestLen);
        }
        return $request;
    }
Пример #4
0
 public function contains($subject)
 {
     if (is_array($this->getExpected())) {
         return in_array($this->getExpected(), $subject);
     }
     return wfWAFUtils::strpos((string) $subject, (string) $this->getExpected()) !== false;
 }
Пример #5
0
 /**
  * @param string $regex
  * @return mixed
  */
 public function check($regex)
 {
     $remaining = $this->getRemainingString();
     if ($this->regexMatch($regex, $remaining, $matches)) {
         $matchLen = wfWAFUtils::strlen($matches[0]);
         if ($matchLen > 0 && wfWAFUtils::strpos($remaining, $matches[0]) === 0) {
             return $this->setState($matches);
         }
     }
     return $this->setState();
 }
Пример #6
0
 /**
  * @todo Implement wfWAFHTTPTransportStreams::send.
  * @param wfWAFHTTP $request
  * @return mixed
  * @throws wfWAFHTTPTransportException
  */
 public function send($request)
 {
     $timeout = 5;
     $url = $request->getUrl();
     if ($queryString = $request->getQueryString()) {
         if (is_array($queryString)) {
             $queryString = http_build_query($queryString);
         }
         $url .= (wfWAFUtils::strpos($url, '?') !== false ? '&' : '?') . $queryString;
     }
     $urlParsed = parse_url($request->getUrl());
     $headers = "Host: {$urlParsed['host']}\r\n";
     if ($auth = $request->getAuth()) {
         $headers .= 'Authorization: Basic ' . base64_encode($auth['user'] . ':' . $auth['password']) . "\r\n";
     }
     if ($cookies = $request->getCookies()) {
         if (is_array($cookies)) {
             $cookies = self::buildCookieString($cookies);
         }
         $headers .= "Cookie: {$cookies}\r\n";
     }
     $hasUA = false;
     if ($_headers = $request->getHeaders()) {
         if (is_array($_headers)) {
             foreach ($_headers as $header => $value) {
                 if (trim(wfWAFUtils::strtolower($header)) === 'user-agent') {
                     $hasUA = true;
                 }
                 $headers .= $header . ': ' . $value . "\r\n";
             }
         }
     }
     if (!$hasUA) {
         $headers .= "User-Agent: Wordfence Streams UA\r\n";
     }
     $httpOptions = array('method' => $request->getMethod(), 'ignore_errors' => true, 'timeout' => $timeout, 'follow_location' => 1, 'max_redirects' => 5);
     if (wfWAFUtils::strlen($request->getBody()) > 0) {
         $httpOptions['content'] = $request->getBody();
         $headers .= 'Content-Length: ' . wfWAFUtils::strlen($httpOptions['content']) . "\r\n";
     }
     $httpOptions['header'] = $headers;
     $options = array(wfWAFUtils::strtolower($urlParsed['scheme']) => $httpOptions);
     $context = stream_context_create($options);
     $stream = fopen($request->getUrl(), 'r', false, $context);
     if (!is_resource($stream)) {
         return false;
     }
     $metaData = stream_get_meta_data($stream);
     // Get the HTTP response code
     $httpResponse = array_shift($metaData['wrapper_data']);
     if (preg_match_all('/(\\w+\\/\\d\\.\\d) (\\d{3})/', $httpResponse, $matches) !== false) {
         // $protocol = $matches[1][0];
         $status = (int) $matches[2][0];
     } else {
         // $protocol = null;
         $status = null;
     }
     $responseObj = new wfWAFHTTPResponse();
     $responseObj->setHeaders(join("\r\n", $metaData['wrapper_data']));
     $responseObj->setBody(stream_get_contents($stream));
     $responseObj->setStatusCode($status);
     // Close the stream after use
     fclose($stream);
     return $responseObj;
 }