コード例 #1
0
ファイル: request.php プロジェクト: ashenkar/sanga
    /**
     * @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;
    }
コード例 #2
0
ファイル: file.php プロジェクト: ashenkar/sanga
 /**
  * @param string $binary
  * @return wfWAFAttackDataStorageFileEngineRow
  */
 public static function unpack($binary)
 {
     $attackLogTime = wfWAFAttackDataStorageFileEngine::unpackMicrotime(wfWAFUtils::substr($binary, 0, 8));
     $data = wfWAFAttackDataStorageFileEngine::decompress(wfWAFUtils::substr($binary, 8));
     return new self($attackLogTime, $data);
 }
コード例 #3
0
 /**
  * @param $algo
  * @param $data
  * @param $key
  * @param bool|false $raw_output
  * @return bool|string
  */
 private static function _hash_hmac($algo, $data, $key, $raw_output = false)
 {
     $packs = array('md5' => 'H32', 'sha1' => 'H40');
     if (!isset($packs[$algo])) {
         return false;
     }
     $pack = $packs[$algo];
     if (wfWAFUtils::strlen($key) > 64) {
         $key = pack($pack, $algo($key));
     }
     $key = str_pad($key, 64, chr(0));
     $ipad = wfWAFUtils::substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
     $opad = wfWAFUtils::substr($key, 0, 64) ^ str_repeat(chr(0x5c), 64);
     $hmac = $algo($opad . pack($pack, $algo($ipad . $data)));
     if ($raw_output) {
         return pack($pack, $hmac);
     }
     return $hmac;
 }
コード例 #4
0
 /**
  * @return string
  * @throws wfWAFRuleException
  */
 public function renderRule()
 {
     if (!$this->isActionValid()) {
         throw new wfWAFRuleException('Invalid action passed to ' . get_class($this) . ', action: ' . var_export($this->getAction(), true));
     }
     $subjectExport = '';
     /** @var wfWAFRuleComparisonSubject $subject */
     foreach ($this->getSubjects() as $subject) {
         $subjectExport .= $subject->renderRule() . ", ";
     }
     $subjectExport = wfWAFUtils::substr($subjectExport, 0, -2);
     $expected = $this->getExpected();
     return sprintf('%s(%s, %s)', $this->getAction(), $expected instanceof wfWAFRuleVariable ? $expected->renderRule() : wfWAFRule::exportString($expected), $subjectExport);
 }
コード例 #5
0
ファイル: lexer.php プロジェクト: ashenkar/sanga
 /**
  * The current column of the line of the scanned string.
  *
  * @return int
  */
 public function getColumn()
 {
     return $this->getPointer() - (int) wfWAFUtils::strrpos(wfWAFUtils::substr($this->getString(), 0, $this->getPointer() + 1), "\n") + 1;
 }
コード例 #6
0
ファイル: http.php プロジェクト: ashenkar/sanga
 /**
  * @todo Proxy settings
  * @param wfWAFHTTP $request
  * @return wfWAFHTTPResponse|bool
  */
 public function send($request)
 {
     $url = $request->getUrl();
     if ($queryString = $request->getQueryString()) {
         if (is_array($queryString)) {
             $queryString = http_build_query($queryString);
         }
         $url .= (wfWAFUtils::strpos($url, '?') !== false ? '&' : '?') . $queryString;
     }
     $ch = curl_init($url);
     switch (wfWAFUtils::strtolower($request->getMethod())) {
         case 'post':
             curl_setopt($ch, CURLOPT_POST, 1);
             break;
     }
     if ($body = $request->getBody()) {
         curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
     }
     if ($auth = $request->getAuth()) {
         curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
     }
     if ($cookies = $request->getCookies()) {
         if (is_array($cookies)) {
             $cookies = self::buildCookieString($cookies);
         }
         curl_setopt($ch, CURLOPT_COOKIE, $cookies);
     }
     if ($headers = $request->getHeaders()) {
         if (is_array($headers)) {
             $_headers = array();
             foreach ($headers as $header => $value) {
                 $_headers[] = $header . ': ' . $value;
             }
             curl_setopt($ch, CURLOPT_HTTPHEADER, $_headers);
         }
     }
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_TIMEOUT, 5);
     curl_setopt($ch, CURLOPT_HEADER, 1);
     $curlResponse = curl_exec($ch);
     if ($curlResponse !== false) {
         $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
         $header = wfWAFUtils::substr($curlResponse, 0, $headerSize);
         $body = wfWAFUtils::substr($curlResponse, $headerSize);
         $response = new wfWAFHTTPResponse();
         $response->setBody($body);
         $response->setHeaders($header);
         return $response;
     }
     return false;
 }
コード例 #7
0
ファイル: parser.php プロジェクト: ashenkar/sanga
 /**
  * @return mixed|string
  * @throws wfWAFRuleParserSyntaxError
  */
 private function expectLiteral()
 {
     $expectedToken = $this->expectNextToken();
     $this->expectTokenTypeInArray($expectedToken, array(wfWAFRuleLexer::T_SINGLE_STRING_LITERAL, wfWAFRuleLexer::T_DOUBLE_STRING_LITERAL, wfWAFRuleLexer::T_IDENTIFIER, wfWAFRuleLexer::T_NUMBER_LITERAL, wfWAFRuleLexer::T_OPEN_BRACKET));
     if ($expectedToken->getType() === wfWAFRuleLexer::T_SINGLE_STRING_LITERAL) {
         // Remove quotes, strip slashes
         $value = wfWAFUtils::substr($expectedToken->getValue(), 1, -1);
         $value = str_replace("\\'", "'", $value);
     } else {
         if ($expectedToken->getType() === wfWAFRuleLexer::T_DOUBLE_STRING_LITERAL) {
             // Remove quotes, strip slashes
             $value = wfWAFUtils::substr($expectedToken->getValue(), 1, -1);
             $value = str_replace('\\"', '"', $value);
         } else {
             if ($expectedToken->getType() === wfWAFRuleLexer::T_IDENTIFIER) {
                 // Remove quotes, strip slashes
                 $value = new wfWAFRuleVariable($this->getWAF(), $expectedToken->getValue());
             } else {
                 if ($expectedToken->getType() === wfWAFRuleLexer::T_OPEN_BRACKET) {
                     $value = array();
                     while (true) {
                         $nextToken = $this->expectNextToken();
                         if ($nextToken->getType() === wfWAFRuleLexer::T_CLOSE_BRACKET) {
                             break;
                         }
                         if ($nextToken->getType() === wfWAFRuleLexer::T_COMMA) {
                             continue;
                         }
                         $this->index--;
                         $value[] = $this->expectLiteral();
                     }
                 } else {
                     $value = $expectedToken->getValue();
                 }
             }
         }
     }
     return $value;
 }