Пример #1
0
        private TrafficViewerFile removeSimilar(TrafficViewerFile source)
        {
            TrafficViewerFile dest = new TrafficViewerFile();
            TVRequestInfo     info;
            int        id         = -1;
            List <int> _reqHashes = new List <int>();

            while ((info = source.GetNext(ref id)) != null)
            {
                byte[]          request = source.LoadRequestData(info.Id);
                HttpRequestInfo reqInfo = new HttpRequestInfo(request, true);
                int             hash    = reqInfo.GetHashCode(TrafficServerMode.BrowserFriendly);

                if (!_reqHashes.Contains(hash))
                {
                    byte[] response = source.LoadResponseData(info.Id);
                    dest.AddRequestResponse(request, response);
                    _reqHashes.Add(hash);
                }
            }

            //copy profile over
            dest.Profile = source.Profile;
            return(dest);
        }
Пример #2
0
        public void EditTVF()
        {
            TrafficViewerFile tvf = UnitTestUtils.GenerateTestTvf();
            //check delete
            int initialCount = tvf.RequestCount;
            //get the first request id
            int           i      = -1;
            TVRequestInfo first  = tvf.GetNext(ref i);
            TVRequestInfo second = tvf.GetNext(ref i);

            HttpRequestInfo secondRequest = new HttpRequestInfo(tvf.LoadRequestData(second.Id));

            HttpResponseInfo secondResponse = new HttpResponseInfo();

            byte [] respBytes = tvf.LoadResponseData(second.Id);
            secondResponse.ProcessResponse(respBytes);
            int referenceResponseStatus = secondResponse.Status;

            int referenceHash = secondRequest.GetHashCode();

            Assert.IsTrue(tvf.RemoveRequest(first.Id));
            Assert.AreEqual(initialCount - 1, tvf.RequestCount);
            Assert.IsNull(tvf.GetPrevious(ref i));

            RequestDataCache.Instance.Clear();
            //check that

            //check add

            TVRequestInfo reqInfo = new TVRequestInfo();

            reqInfo.RequestLine = "GET /newrequest HTTP/1.1";
            string request  = "GET /newrequest HTTP/1.1\r\nHeader1:1\r\n\r\n";
            string response = "HTTP 200 OK\r\nHeader1:1\r\n\r\n<html><body>Added request</body></html>";

            RequestResponseBytes reqData = new RequestResponseBytes();

            reqData.AddToRequest(Constants.DefaultEncoding.GetBytes(request));
            reqData.AddToResponse(Constants.DefaultEncoding.GetBytes(response));

            tvf.AddRequestInfo(reqInfo);
            tvf.SaveRequest(reqInfo.Id, reqData);
            tvf.SaveResponse(reqInfo.Id, reqData);

            //Check that the request was added
            response = Constants.DefaultEncoding.GetString(tvf.LoadResponseData(reqInfo.Id));

            Assert.AreEqual(38, response.IndexOf("Added request"));
            Assert.AreEqual(65, response.Length);
            //modify the recently added request slightly
        }
Пример #3
0
        /// <summary>
        /// Gets the next unsent request
        /// </summary>
        /// <returns>Http Request Info</returns>
        private HttpRequestInfo GetNextRequest()
        {
            TVRequestInfo   tvReqInfo   = null;
            HttpRequestInfo httpReqInfo = null;
            ICacheable      cacheEntry  = null;

            //get the next unvisited request
            bool isCached = true;
            int  hash     = 0;

            do
            {
                tvReqInfo = Source.GetNext(ref _currId);
                if (tvReqInfo != null)
                {
                    isCached = true;
                    //skip js files and images
                    if (!Utils.IsMatch(tvReqInfo.RequestLine, KNOWN_RESOURCE_EXTENSIONS))
                    {
                        byte[] requestBytes = Source.LoadRequestData(tvReqInfo.Id);
                        httpReqInfo = new HttpRequestInfo(requestBytes);
                        //skip invalid requests
                        if (httpReqInfo.Path.Contains("/"))
                        {
                            hash = httpReqInfo.GetHashCode();

                            //check the cache for the request to see if it was already visited
                            //allow the same request to be sent more than once
                            if (hash != _lastRequestHash)
                            {
                                cacheEntry = TrafficServerCache.Instance.GetEntry(hash);
                                isCached   = cacheEntry != null;
                            }
                        }
                    }
                }
                //keep doing this until the end of requests or until we found a request that is not cached
            }while (tvReqInfo != null && isCached);

            if (hash != _lastRequestHash)
            {
                _lastRequestHash = hash;
                //clear the cache so we don't skip any repeats of the previous request
                TrafficServerCache.Instance.Clear();
            }
            return(httpReqInfo);
        }
Пример #4
0
        /// <summary>
        /// Compares two requests infos
        /// </summary>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static bool IsMatch(HttpRequestInfo first, HttpRequestInfo second, TrafficServerMode mode)
        {
            bool result;

            if (mode == TrafficServerMode.IgnoreCookies)
            {
                result = first.QueryVariables.GetHashCode() == second.QueryVariables.GetHashCode() &&
                         first.BodyVariables.GetHashCode() == second.BodyVariables.GetHashCode();
            }
            else if (mode == TrafficServerMode.Strict)
            {
                result = first.GetHashCode() == second.GetHashCode();
            }
            else
            {
                result = first.QueryVariables.GetHashCode(false) == second.QueryVariables.GetHashCode(false) &&
                         first.BodyVariables.GetHashCode(false) == second.BodyVariables.GetHashCode(false);
            }

            return(result);
        }
Пример #5
0
        private void RequestHandlerThread()
        {
            while (IsListening)
            {
                HttpRequestInfo  reqInfo   = null;
                HttpResponseInfo respInfo  = null;
                int thisThreadRequestIndex = -1;
                lock (_lock)
                {
                    reqInfo = null;
                    if (_requestsToTest.Count > 0)
                    {
                        thisThreadRequestIndex = _requestsToTest.Dequeue();
                        _currentTestReqIdx     = thisThreadRequestIndex;
                        reqInfo  = _requestIndex[thisThreadRequestIndex];
                        respInfo = _responseIndex[thisThreadRequestIndex];
                    }
                }

                if (reqInfo != null)
                {
                    bool   isSecure   = reqInfo.IsSecure;
                    string rawRequest = reqInfo.ToString();

                    string rawResponse = respInfo != null?respInfo.ToString() : String.Empty;

                    if (ShouldBeTested(rawRequest))
                    {
                        //parse parameters
                        reqInfo          = new HttpRequestInfo(rawRequest, true);
                        reqInfo.IsSecure = isSecure;
                        int hash = reqInfo.GetHashCode(TrafficServerMode.IgnoreCookies);
                        lock (_lock)
                        {
                            if (_testedRequestHashes.Contains(hash))
                            {
                                HttpServerConsole.Instance.WriteLine(LogMessageType.Warning,
                                                                     "Request already tested: '{0}'", reqInfo.FullUrl);
                                continue; //we tested this request before
                            }
                            else
                            {
                                _testedRequestHashes.Add(hash);
                            }
                        }
                        Uri reqUri = new Uri(reqInfo.FullUrl);
                        MultiThreadedTestExecution testExecution = new MultiThreadedTestExecution(_tester, rawRequest, rawResponse, reqUri, _numThreads);

                        lock (_lock)
                        {
                            GenerateEntities(thisThreadRequestIndex, reqInfo);
                            testExecution.TestsQueue = _workList[thisThreadRequestIndex];
                        }

                        testExecution.StartTestsAsync();

                        while (testExecution.IsRunning)
                        {
                            if (!IsListening)
                            {
                                testExecution.CancelTests();
                                break;
                            }
                            HttpServerConsole.Instance.WriteLine(LogMessageType.Notification,
                                                                 "Requests in queue: {0}, Tests in queue for current request: {1}, testing with {2} threads.", _requestsToTest.Count, testExecution.TestsQueue.Count, _numThreads);

                            Thread.Sleep(1000);
                        }

                        HttpServerConsole.Instance.WriteLine(LogMessageType.Notification,
                                                             "Test execution completed.");
                    }
                }


                Thread.Sleep(10);
            }
            HttpServerConsole.Instance.WriteLine(LogMessageType.Notification,
                                                 "Drive by Attack Proxy stopped.");
        }
Пример #6
0
        /// <summary>
        /// Actually gets a matching response from the mock data
        /// </summary>
        /// <param name="requestInfo"></param>
        /// <returns></returns>
        public HttpResponseInfo SendRequest(HttpRequestInfo requestInfo)
        {
            HttpResponseInfo  responseInfo         = null;
            string            currentRequestString = requestInfo.ToString();
            string            currentAlertId       = Utils.RegexFirstGroupValue(currentRequestString, ALERT_MATCH);
            TrafficServerMode currentMatchMode     = _matchMode;

            if (!String.IsNullOrEmpty(currentAlertId))             //override the redundancy tuning if we are trying to match a alert
            {
                currentMatchMode = TrafficServerMode.BrowserFriendly;
            }

            //parse the request variables because we will need them to construct the hash
            requestInfo.ParseVariables();


            TrafficServerResponseSet responseSet = null;

            //look in the server cache for the request
            ICacheable entry =
                TrafficServerCache.Instance.GetEntry(requestInfo.GetHashCode(currentMatchMode));


            if (entry != null)
            {
                responseSet = entry.Reserve() as TrafficServerResponseSet;
                entry.Release();
            }

            TrafficServerResponseSet similarRequests = new TrafficServerResponseSet();

            if (responseSet == null)
            {
                //create a new empty response set
                responseSet = new TrafficServerResponseSet();

                RequestSearcher searcher = new RequestSearcher();

                SearchCriteriaSet criteriaSet;

                criteriaSet = GetCriteriaSet(requestInfo, currentMatchMode);

                RequestMatches matches = new RequestMatches();

                //do the search!
                searcher.Search(_sourceStore, criteriaSet, matches);

                //normalize the matches and keep only the ones that have the same variables and values
                if (matches.Count > 0)
                {
                    HttpRequestInfo original;
                    HttpRequestInfo found;
                    byte[]          requestBytes;
                    int             i, n = matches.Count;
                    for (i = 0; i < n & i < MATCHES_LIMIT; i++)
                    {
                        int           match  = matches[i];
                        TVRequestInfo header = _sourceStore.GetRequestInfo(match);
                        if (_ignoreAuth)
                        {
                            if (
                                String.Compare(header.ResponseStatus, "401", true) == 0 ||
                                String.Compare(header.ResponseStatus, "407", true) == 0)
                            {
                                HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping authentication challenge");
                                //simply skip 401 matches
                                continue;
                            }
                        }

                        if (String.Compare(header.Description, Resources.TrafficLogProxyDescription, true) == 0)
                        {
                            //is likely that the source store is also the save store and this may be
                            //the current request being saved
                            HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping request to traffic store");
                            continue;
                        }


                        requestBytes = _sourceStore.LoadRequestData(match);
                        string requestString = Constants.DefaultEncoding.GetString(requestBytes);

                        if (String.IsNullOrEmpty(requestString))
                        {
                            continue;                             //skip the current match is incorrect
                        }
                        original = new HttpRequestInfo(DynamicElementsRemover.Remove(currentRequestString));
                        found    = new HttpRequestInfo(DynamicElementsRemover.Remove(requestString));

                        if (RequestMatcher.IsMatch(original, found, TrafficServerMode.Strict))
                        {
                            responseSet.Add(match);
                        }
                        else if (currentMatchMode != TrafficServerMode.Strict &&
                                 RequestMatcher.IsMatch(original, found, currentMatchMode))
                        {
                            similarRequests.Add(match);
                        }
                    }
                    //if no exact requests were found
                    if (responseSet.Count == 0 && similarRequests.Count > 0)
                    {
                        HttpServerConsole.Instance.WriteLine
                            (LogMessageType.Warning, "Warning, exact match was not found for {0} returning a similar request.",
                            requestInfo.RequestLine);
                    }
                    responseSet.AddRange(similarRequests.Matches);
                }

                //add this response set to the cache
                TrafficServerCache.Instance.Add(requestInfo.GetHashCode(currentMatchMode), new CacheEntry(responseSet));
            }

            //get the next response id from the response set
            int requestId = responseSet.GetNext();

            if (requestId == NULL_INDEX)
            {
                HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "(404) Request not found: {0}"
                                                     , requestInfo.RequestLine);
                //the request was not found at all, return a 404
                return(new HttpResponseInfo(HttpErrorResponse.GenerateHttpErrorResponse(HttpStatusCode.NotFound, "Request Not Found",
                                                                                        "<html><head><title>Error code: 404</title><body><h1>Request was not found or variables didn't match.</h1></body></html>")));
            }

            if (requestId != NULL_INDEX)
            {
                HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Returning response from request id: {0}", requestId);
                byte[] responseBytes = _sourceStore.LoadResponseData(requestId);

                if (responseBytes != null)
                {
                    responseInfo = new HttpResponseInfo(responseBytes);

                    if (!String.IsNullOrEmpty(currentAlertId))
                    {
                        Encoding encoding       = HttpUtil.GetEncoding(responseInfo.Headers["Content-Type"]);
                        string   responseString = encoding.GetString(responseBytes);
                        responseString = Utils.ReplaceGroups(responseString, ALERT_MATCH, currentAlertId);
                        responseInfo   = new HttpResponseInfo(encoding.GetBytes(responseString));
                    }
                }

                //add the request id header
                responseInfo.Headers.Add("Traffic-Store-Req-Id", requestId.ToString());
            }

            return(responseInfo);
        }
Пример #7
0
        /// <summary>
        /// Handles a request
        /// </summary>
        /// <param name="requestInfo"></param>
        /// <returns></returns>
        public HttpRequestInfo HandleRequest(HttpRequestInfo requestInfo, out bool mutated)
        {
            lock (_lock)
            {
                mutated = false;
                //make a request info that we parse in order to generate a hash and entities to test
                _curWorkingRawRequest = requestInfo.ToString();


                if (!ShouldBeTested(_curWorkingRawRequest))
                {
                    return(requestInfo);
                }

                _curWorkingReqInfo          = new HttpRequestInfo(_curWorkingRawRequest, true);
                _curWorkingReqInfo.IsSecure = requestInfo.IsSecure;

                int hash = _curWorkingReqInfo.GetHashCode(TrafficServerMode.IgnoreCookies); //get a hash including only the parameter names

                if (_firstRequestHash == 0)
                {
                    _firstRequestHash = hash;
                }

                if (hash == _firstRequestHash)
                {
                    if (_currentReqIdx > _detectedFlowRequests)
                    {
                        _detectedFlowRequests = _currentReqIdx + 1;
                    }
                    //reset the counter
                    _currentReqIdx = 0;
                }
                else
                {
                    //increment the request counter
                    _currentReqIdx++;
                }


                if (_currentTestReqIdx < 0)                                          //this is the first request
                {
                    if (String.IsNullOrEmpty(_testFile.PatternOfFirstRequestToTest)) //if this is not the first request
                    {
                        _currentTestReqIdx = 0;
                    }
                    else
                    {
                        if (Utils.IsMatch(_curWorkingRawRequest, _testFile.PatternOfFirstRequestToTest))
                        {
                            _currentTestReqIdx = _currentReqIdx;
                        }
                    }
                }



                if (_currentReqIdx == _currentTestReqIdx)
                {
                    if (!_workList.ContainsKey(_currentTestReqIdx)) //no tests have been generated for this request
                    {
                        GenerateEntities(_currentReqIdx, _curWorkingReqInfo);
                    }

                    //this is the test request execute the next test
                    Queue <TestJob> testQueue = _workList[_currentTestReqIdx];
                    if (testQueue.Count == 0 && _curMutatedRawReqQueue.Count == 0)
                    {
                        _currentTestReqIdx++;
                    }
                    else
                    {
                        if (_curMutatedRawReqQueue.Count == 0)
                        {
                            _curTestJob = testQueue.Dequeue();
                            //TODO: alter the request
                            Uri workingReqUri = new Uri(_curWorkingReqInfo.FullUrl);
                            _curEntityId = _tester.GetEntityId(workingReqUri, _curTestJob.ParameterName);

                            string entityString = _tester.GetEntityString(_curWorkingRawRequest, workingReqUri, _curTestJob.ParameterName, _curTestJob.ParameterValue);

                            if (entityString == null)//we could not find the parameter name /value combination
                            {
                                //try to obtain an updated value for the parameter
                                string updatedParameterValue = GetUpdatedParameterValue(_curWorkingReqInfo, _curTestJob);
                                entityString = _tester.GetEntityString(_curWorkingRawRequest, workingReqUri, _curTestJob.ParameterName, updatedParameterValue);
                            }

                            _curMutatedRequestList = _tester.GenerateMutatedRequestList(_curWorkingRawRequest, _curTestJob, entityString, _curEntityId);
                            foreach (string req in _curMutatedRequestList)
                            {
                                _curMutatedRawReqQueue.Enqueue(req);
                            }
                            _curTestResponseCollection = new Dictionary <int, List <string> >(); //re-init the current test response list for multi response validation
                        }
                        //check again in case for some reason requests could not be generated (empty parameters)
                        if (_curMutatedRawReqQueue.Count > 0)
                        {
                            //if multiple mutations are generated for the test then they need to be executed with each flow iteration
                            _curMutatedRawReq = _curMutatedRawReqQueue.Dequeue();
                            //return the mutated request
                            requestInfo          = new HttpRequestInfo(_curMutatedRawReq, false);
                            requestInfo.IsSecure = _curWorkingReqInfo.IsSecure;
                            mutated = true;
                        }
                    }
                }
            }
            return(requestInfo);
        }