/// <summary>
        /// Adds the request to the proxy data store
        /// </summary>
        protected void AddRequestToDataStore()
        {
            TVRequestInfo currDataStoreRequestInfo = new TVRequestInfo();

            currDataStoreRequestInfo.RequestLine = _requestInfo.RequestLine;

            currDataStoreRequestInfo.Description = _requestDescription;
            currDataStoreRequestInfo.RequestTime = _currentRequestTime;
            currDataStoreRequestInfo.ThreadId    = Utils.GetCurrentWin32ThreadId().ToString();
            currDataStoreRequestInfo.IsHttps     = _requestInfo.IsSecure;
            currDataStoreRequestInfo.Host        = _requestInfo.Host;

            int reqId = TrafficDataStore.AddRequestInfo(currDataStoreRequestInfo);

            if (reqId != -1)
            {
                _currentRequestResponseBytes = new RequestResponseBytes();
                _currentRequestResponseBytes.AddToRequest(_requestInfo.ToArray(false));
                //saving the request in a direct to site format, since it will come
                //in proxy format GET http://site.com/ rather than  GET /,
                //if we need a server to connect to the target the client will handle that
                TrafficDataStore.SaveRequest(reqId, _currentRequestResponseBytes);
                _currDataStoreRequestInfo = TrafficDataStore.GetRequestInfo(reqId);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Triggered before the response is sent back to the client
        /// </summary>
        /// <param name="responseInfo"></param>
        /// <returns></returns>
        protected override HttpResponseInfo OnBeforeResponseToClient(HttpResponseInfo responseInfo)
        {
            if (_responseReplacements != null && _responseReplacements.Count > 0)
            {
                string response    = responseInfo.ToString();
                bool   wasReplaced = false;

                foreach (string key in _responseReplacements.Keys)
                {
                    if (Utils.IsMatch(response, key))
                    {
                        response = Utils.ReplaceGroups(response, key, _responseReplacements[key]);
                        HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Response replacement applied for pattern: '{0}'", key);
                        wasReplaced = true;
                    }
                }

                if (wasReplaced)
                {
                    //remove chunked encoding
                    response     = Regex.Replace(response, "Transfer-Encoding:\\s?chunked\\r\\n", "", RegexOptions.IgnoreCase);
                    responseInfo = new HttpResponseInfo(response);
                }
            }

            if (!_isNonEssential)
            {
                //update tracked paterns from the response
                PatternTracker.Instance.UpdatePatternValues(responseInfo);
            }


            if (CurrDataStoreRequestInfo != null)
            {
                //trap the response (this will only occur if the trap is enabled)
                if (HttpTrap.Instance.TrapResponses)
                {
                    TrafficDataStore.SaveResponse(CurrDataStoreRequestInfo.Id, responseInfo.ToArray());

                    if (HttpTrap.Instance.TrapResponse(CurrDataStoreRequestInfo, responseInfo))
                    {
                        responseInfo = new HttpResponseInfo(TrafficDataStore.LoadResponseData(CurrDataStoreRequestInfo.Id));

                        if (responseInfo.ResponseBody != null && responseInfo.ResponseBody.IsChunked == false)
                        {
                            responseInfo.Headers["Content-Length"] = responseInfo.ResponseBody.Length.ToString();
                        }
                    }
                }

                if (_trackRequestContext)
                {
                    //replace the request with its request id
                    //store information about where the request was found in previous traffic responses stored in the
                    //current traffic file
                    TrackRequestContext(_requestInfo);
                }
            }
            return(responseInfo);
        }
Ejemplo n.º 3
0
 protected override HttpRequestInfo OnBeforeRequestToSite(HttpRequestInfo requestInfo)
 {
     requestInfo = base.OnBeforeRequestToSite(requestInfo);
     if (!_isNonEssential)
     {
         bool mutated;
         requestInfo = _parentProxy.HandleRequest(requestInfo, out mutated);
         if (mutated)
         {
             CurrDataStoreRequestInfo.Description = "Custom Test";
         }
         TrafficDataStore.SaveRequest(CurrDataStoreRequestInfo.Id, requestInfo.ToArray(false));
         TrafficDataStore.UpdateRequestInfo(CurrDataStoreRequestInfo);
     }
     return(requestInfo);
 }
Ejemplo n.º 4
0
        protected override HttpResponseInfo OnBeforeResponseToClient(HttpResponseInfo responseInfo)
        {
            responseInfo = base.OnBeforeResponseToClient(responseInfo);
            if (!_isNonEssential)
            {
                //validate if the test was successful
                if (_parentProxy.ValidateResponse(responseInfo))
                {
                    //the test was found
                    CurrDataStoreRequestInfo.Description = "Vulnerable Response";
                    TrafficDataStore.UpdateRequestInfo(CurrDataStoreRequestInfo);
                }
            }


            return(responseInfo);
        }
        /// <summary>
        /// Writes a CRWAE message to the client when response is not available from server
        /// </summary>
        /// <param name="statusCode">HTTP status code for the response</param>
        /// <param name="reason">Brief explanation of error</param>
        /// <param name="serviceCode">ID of the CRAWE message</param>
        /// <param name="args">Message args</param>
        protected virtual void ReturnHttpErrorResponse(HttpStatusCode statusCode, string reason, ServiceCode serviceCode, params object [] args)
        {
            byte[] messageBytes = HttpErrorResponse.GenerateHttpErrorResponse(statusCode, reason, serviceCode, args);
            if (!TryWriteToStream(messageBytes))
            {
                return;
            }

            //add the response if we are adding requests to the data source
            if (_currDataStoreRequestInfo != null)
            {
                _currDataStoreRequestInfo.ResponseStatus = statusCode.ToString();
                _currDataStoreRequestInfo.ResponseTime   = DateTime.Now;
                TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, messageBytes);
                _currDataStoreRequestInfo = null;
            }
            ClientStreamWrapper.Close();
        }
        /// <summary>
        /// Writes a response to the client stream
        /// </summary>
        /// <param name="responseInfo"></param>
        protected virtual void ReturnResponse(HttpResponseInfo responseInfo)
        {
            HttpServerConsole.Instance.WriteLine(LogMessageType.Information,
                                                 "Sending response: {0} for request: {1}", responseInfo.StatusLine, _requestInfo.RequestLine);


            if (_currDataStoreRequestInfo != null)
            {
                _currDataStoreRequestInfo.ResponseStatus = responseInfo.Status.ToString();
                _currDataStoreRequestInfo.ResponseTime   = DateTime.Now;
            }

            //process response headers
            if (responseInfo.Status == 401)
            {
                //we need to send the proxy support header/ or overwrite the existing proxy support header
                responseInfo.Headers["Proxy-Support"] = "Session-Based-Authentication";
            }

            //if connection is close disconnect, or if the client sent us a connection close message
            if (String.Compare(responseInfo.Headers[CONNECTION_HEADER], "close", true) == 0 ||
                String.Compare(_requestInfo.Headers[CONNECTION_HEADER], "close", true) == 0)
            {
                _isClose = true;
            }

            byte[] responseHead = HandleResponseByteChunk(responseInfo.ResponseHead);

            if (!TryWriteToStream(responseHead))
            {
                return;
            }
            ;

            // Return the substitute response body
            if (responseInfo.ResponseBody.IsChunked)
            {
                byte[] chunk;
                byte[] chunkBuf;
                while ((chunk = responseInfo.ResponseBody.ReadChunk()) != null)
                {
                    //write the chunk size line
                    chunkBuf = Constants.DefaultEncoding.GetBytes(String.Format("{0:x}\r\n", chunk.Length));
                    chunkBuf = HandleResponseByteChunk(chunkBuf);
                    if (!TryWriteToStream(chunkBuf))
                    {
                        return;
                    }
                    //write the chunk
                    chunk = HandleResponseByteChunk(chunk);
                    if (!TryWriteToStream(chunk))
                    {
                        return;
                    }
                    chunkBuf = Constants.DefaultEncoding.GetBytes("\r\n");
                    chunkBuf = HandleResponseByteChunk(chunkBuf);
                    if (!TryWriteToStream(chunkBuf))
                    {
                        return;
                    }
                }
                //write a last chunk with the value 0
                // write the last chunk size
                chunkBuf = Constants.DefaultEncoding.GetBytes("0\r\n\r\n");
                chunkBuf = HandleResponseByteChunk(chunkBuf);
                if (!TryWriteToStream(chunkBuf))
                {
                    return;
                }
            }
            else
            {
                byte[] buffer = responseInfo.ResponseBody.ToArray();
                if (buffer != null)
                {
                    buffer = HandleResponseByteChunk(buffer);
                    if (!TryWriteToStream(buffer))
                    {
                        return;
                    }
                }
            }


            //cleanup the request info
            _requestBuilder = new ByteArrayBuilder();

            if (_currDataStoreRequestInfo != null)
            {
                TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, _currentRequestResponseBytes);
            }

            _currDataStoreRequestInfo    = null;
            _currentRequestResponseBytes = null;

            //close the connection if the request had a connection close header
            if (_isClose)
            {
                ClientStreamWrapper.Close();
            }
            else
            {
                _isBusy = false;
                ClientStreamWrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), ClientStreamWrapper);
            }
        }
Ejemplo n.º 7
0
        private void TrackRequestContext(HttpRequestInfo requestInfo)
        {
            foreach (TrackingPattern pattern in _autoTrackingPatternList.Values)
            {
                string rawRequest = requestInfo.ToString();

                string needle = Utils.RegexFirstGroupValue(rawRequest, pattern.RequestPattern);

                if (String.IsNullOrWhiteSpace(needle))
                {
                    continue;
                }


                //first search for the path of the current request in responses
                LineMatches results = SearchParameterValue(needle);

                if (results.Count == 0)
                {
                    needle  = Utils.UrlDecode(needle);
                    results = SearchParameterValue(needle);
                }

                //if any of the two searches returned results
                if (results.Count != 0)
                {
                    //get the last match to extract the request context
                    var match = results[results.Count - 1];
                    CurrDataStoreRequestInfo.RefererId = match.RequestId;
                    //replace the path in the match
                    string requestContext = match.Line.Replace(needle, REQ_CONTEXT_ID);

                    if (requestContext.Length > MAX_REQUEST_CONTEXT_SIZE)
                    {
                        requestContext = TrimRequestContext(requestContext);
                    }

                    //also replace hexadecimal values
                    requestContext = Regex.Replace(requestContext, HEX_REGEX, HEX_VAL);

                    //escape the line
                    requestContext = Regex.Escape(requestContext);
                    //insert the group
                    requestContext = requestContext.Replace(REQ_CONTEXT_ID, RX_GROUP);
                    //insert the HEX regex
                    requestContext = requestContext.Replace(HEX_VAL, HEX_REGEX);

                    CurrDataStoreRequestInfo.RequestContext  = requestContext;
                    CurrDataStoreRequestInfo.TrackingPattern = pattern.Name;

                    TrafficDataStore.UpdateRequestInfo(CurrDataStoreRequestInfo);

                    string originalPath = requestInfo.Path;
                    CurrDataStoreRequestInfo.UpdatedPath = originalPath;

                    //change the path of the request
                    HttpRequestInfo newReq = new HttpRequestInfo(requestInfo.ToArray(false), false);

                    //we are only replacing the last portion of the path and the query string to prevent relative path issues and also cookie path issues
                    int lastIndexOfSlash = originalPath.LastIndexOf('/');
                    if (lastIndexOfSlash >= 0)
                    {
                        originalPath = originalPath.Substring(0, lastIndexOfSlash + 1);
                    }


                    newReq.Path = String.Format("{0}{1}{2}", originalPath, REQ_ID_STRING, CurrDataStoreRequestInfo.Id);

                    TrafficDataStore.SaveRequest(CurrDataStoreRequestInfo.Id, newReq.ToArray(false));

                    HttpServerConsole.Instance.WriteLine
                        ("Found request context for request '{0}' id: {1}, referer id:{2}",
                        requestInfo.Path, CurrDataStoreRequestInfo.Id, CurrDataStoreRequestInfo.RefererId);
                    HttpServerConsole.Instance.WriteLine
                        (requestContext);

                    return;                     //we can only have one tracking pattern per request
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Triggered before the request is sent to the site
        /// </summary>
        /// <param name="requestInfo"></param>
        /// <returns></returns>
        protected override HttpRequestInfo OnBeforeRequestToSite(HttpRequestInfo requestInfo)
        {
            bool wasModified = false;

            if (_requestReplacements != null)
            {
                string request = requestInfo.ToString();



                foreach (string key in _requestReplacements.Keys)
                {
                    if (Utils.IsMatch(request, key))
                    {
                        request     = Utils.ReplaceGroups(request, key, _requestReplacements[key]);
                        wasModified = true;
                        HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Request replacement applied for pattern: '{0}'", key);
                    }
                }

                if (wasModified)
                {
                    requestInfo = new HttpRequestInfo(request, false);
                    //update the content length
                    if (requestInfo.ContentData != null)
                    {
                        requestInfo.Headers["Content-Length"] = requestInfo.ContentData.Length.ToString();
                    }
                    requestInfo.IsSecure = ClientStreamWrapper.IsSecure;
                }
            }


            if (!_isNonEssential)
            {
                var originalRawRequest = requestInfo.ToString();
                //update tracked values
                string updatedRequest = PatternTracker.Instance.UpdateRequest(originalRawRequest);
                updatedRequest = UpdateDynamicPatterns(updatedRequest);
                if (!originalRawRequest.Equals(updatedRequest))
                {
                    bool isSecure = requestInfo.IsSecure;
                    requestInfo          = new HttpRequestInfo(updatedRequest, false);
                    requestInfo.IsSecure = isSecure;
                    wasModified          = true;
                }

                if (wasModified)
                {
                    //update the request in the file
                    TrafficDataStore.SaveRequest(CurrDataStoreRequestInfo.Id, Constants.DefaultEncoding.GetBytes(updatedRequest));
                }
            }


            if (CurrDataStoreRequestInfo != null)
            {
                //see if the request was trapped
                if (HttpTrap.Instance.TrapRequests &&
                    HttpTrap.Instance.TrapRequest(CurrDataStoreRequestInfo, requestInfo))
                {
                    //then we need to update the request info from the data source
                    requestInfo = new HttpRequestInfo(TrafficDataStore.LoadRequestData(CurrDataStoreRequestInfo.Id), false);
                    //update the content length
                    if (requestInfo.ContentData != null)
                    {
                        requestInfo.Headers["Content-Length"] = requestInfo.ContentData.Length.ToString();
                    }
                    requestInfo.IsSecure = ClientStreamWrapper.IsSecure;
                }
            }



            return(requestInfo);
        }