/// <summary> /// Updates patterns to be tracked with values from response info /// </summary> /// <param name="rawResponse"></param> public void UpdatePatternValues(string rawResponse) { lock (_trackingLock) { if (_patternsToTrack != null && !String.IsNullOrWhiteSpace(rawResponse)) { foreach (string key in _patternsToTrack.Keys) { TrackingPattern pattern = _patternsToTrack[key]; if (pattern.TrackingType == TrackingType.ResponsePattern) { string regex = pattern.TrackingValue; string value = Utils.RegexFirstGroupValue(rawResponse, regex); if (!String.IsNullOrWhiteSpace(value)) { if (_currentValues.ContainsKey(key)) { _currentValues[key] = value; } else { _currentValues.Add(key, value); } } } } } } }
/// <summary> /// Constructor for an advanced proxy connection /// </summary> /// <param name="tcpClient"></param> /// <param name="isSecure"></param> /// <param name="dataStore"></param> /// <param name="description"></param> /// <param name="networkSettings">Settings used for the connection, proxy etc.</param> /// <param name="replacements">Strings to be replaced in the request</param> public AdvancedExploreProxyConnection(TcpClient tcpClient, bool isSecure, ITrafficDataAccessor dataStore, string description, INetworkSettings networkSettings, bool trackRequestContext) : base(tcpClient, isSecure, dataStore, description, networkSettings) { _requestReplacements = dataStore.Profile.GetRequestReplacements(); _responseReplacements = dataStore.Profile.GetResponseReplacements(); _trackRequestContext = trackRequestContext; _autoTrackingPatternList = new Dictionary <string, TrackingPattern>(); _dynamicReplacements.Add(Constants.SEQUENCE_VAR_PATTERN, () => { return(DateTime.Now.Ticks.ToString()); }); _dynamicReplacements.Add(Constants.GUID_VAR_PATTERN, () => { return(Guid.NewGuid().ToString()); }); _dynamicReplacements.Add("__RSHORT__", () => { return(this._rng.Next(0, short.MaxValue).ToString()); }); var trackingPatterns = dataStore.Profile.GetTrackingPatterns(); foreach (var key in trackingPatterns.Keys) { TrackingPattern item = trackingPatterns[key]; if (item.TrackingType == TrackingType.AutoDetect) { _autoTrackingPatternList.Add(item.Name, item); } } }
/// <summary> /// If the response obtained is different than original attempt to update the path and resend to obtain a good response /// </summary> /// <param name="responseInfo"></param> /// <returns></returns> protected override HttpResponseInfo OnBeforeResponseToClient(HttpResponseInfo responseInfo) { responseInfo = base.OnBeforeResponseToClient(responseInfo); if (_trackingReqInfo != null) { //this is a tracked request we may need to update it if (IsDifferentThanOriginalResponse(responseInfo)) { //we need to obtain the referer response and update the request if (_trackingReqInfo.RefererId > -1 && !String.IsNullOrWhiteSpace(_trackingReqInfo.RequestContext)) { //load the referer request var refererInfo = _dataStore.GetRequestInfo(_trackingReqInfo.RefererId); var refererReqBytes = _dataStore.LoadRequestData(_trackingReqInfo.RefererId); if (refererReqBytes != null && refererReqBytes.Length > 0) { var refererHttpInfo = new HttpRequestInfo(refererReqBytes); refererHttpInfo.IsSecure = refererInfo.IsHttps; //update request cookie headers from the current request refererHttpInfo.Cookies.Clear(); refererHttpInfo.Headers["Cookie"] = _requestInfo.Headers["Cookie"]; //now that the referer request is ready send it to the tracking proxy where if the response is different than the original it will in turn //get its referer resent IHttpClient trackingProxyClient = GetTrackingProxyHttpClient(); //following lines equivalent to a recursive call var refererUpdatedResponse = trackingProxyClient.SendRequest(refererHttpInfo); string refererRawResponse = refererUpdatedResponse.ToString(); //update autotrack traccking patterns string updatedRequestValue = Utils.RegexFirstGroupValue(refererRawResponse, _trackingReqInfo.RequestContext); if (!String.IsNullOrWhiteSpace(updatedRequestValue) && AutoTrackingPatternList.ContainsKey(_trackingReqInfo.TrackingPattern)) { TrackingPattern curPattern = AutoTrackingPatternList[_trackingReqInfo.TrackingPattern]; //update request _originalRawRequest = Utils.ReplaceGroups(_originalRawRequest, curPattern.RequestPattern, updatedRequestValue); } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Could not update autodetect parameter for tracked request id {0}. Will resend anyway", _trackingReqInfo.Id); } //update patterns string updatedRawRequest = PatternTracker.Instance.UpdateRequest(_originalRawRequest); updatedRawRequest = UpdateDynamicPatterns(updatedRawRequest); HttpRequestInfo newRequest = new HttpRequestInfo(updatedRawRequest); newRequest.IsSecure = _requestInfo.IsSecure; AddSpecialHeader(newRequest); if (!_trackingReqInfo.UpdatedPath.Equals(newRequest.Path)) { _trackingReqInfo.UpdatedPath = newRequest.Path; //update the path in the ui _dataStore.UpdateRequestInfo(_trackingReqInfo); //now send the request one more time } //send the request with the normal HTTP client this time responseInfo = HttpClient.SendRequest(newRequest); //no matter what we return the last value PatternTracker.Instance.UpdatePatternValues(responseInfo); } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Missing http traffic for request id {0}", _trackingReqInfo.Id); } } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Missing referer or request context for request id {0}", _trackingReqInfo.Id); } } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Response similar for request id {0}", _trackingReqInfo.Id); } } return(responseInfo); }
/// <summary> /// Updates the request with the current values /// </summary> /// <param name="rawRequest"></param> public string UpdateRequest(string rawRequest) { lock (_trackingLock) { if (_patternsToTrack != null && !String.IsNullOrWhiteSpace(rawRequest)) { foreach (string key in _patternsToTrack.Keys) { string currentValue = null; TrackingPattern currentPattern = _patternsToTrack[key]; if (currentPattern.TrackingType == TrackingType.ResponsePattern) { //check if we have an updated value for this pattern if (_currentValues.ContainsKey(key)) { currentValue = _currentValues[key]; } //update the request with this pattern if (!String.IsNullOrWhiteSpace(currentValue)) { rawRequest = Utils.ReplaceGroups(rawRequest, currentPattern.RequestPattern, currentValue); HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Tracking pattern applied for: '{0}'", key); } } if (currentPattern.TrackingType == TrackingType.Function) { //execute a function on the parameter value currentValue = Utils.RegexFirstGroupValue(rawRequest, currentPattern.RequestPattern); if (!String.IsNullOrWhiteSpace(currentValue)) { //extract the functions to execute string[] functions = currentPattern.TrackingValue.Split(','); foreach (string func in functions) { //apply the functions in order switch (func.ToLower()) { case "base64encode": currentValue = Utils.Base64Encode(currentValue); break; case "base64decode": currentValue = Utils.Base64Decode(currentValue); break; case "urlencode": currentValue = Utils.UrlEncode(currentValue); break; case "urldecode": currentValue = Utils.UrlDecode(currentValue); break; case "ticks": currentValue = DateTime.Now.Ticks.ToString(); break; case "increment": int currentValueInt = 0; if (int.TryParse(currentValue, out currentValueInt)) { currentValueInt++; currentValue = currentValueInt.ToString(); } break; } } rawRequest = Utils.ReplaceGroups(rawRequest, currentPattern.RequestPattern, currentValue); HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Function tracking pattern applied for: '{0}'", key); } } } } } return(rawRequest); }