public static List<Session> ProcessHeaderResults(Session s, List<HeaderMatch> matches, Token tt) { List<Session> ret = new List<Session>(); foreach (HeaderMatch match in matches) { Session newSession = s.deepClone(); List<string> headersForKey = s.Request.Headers[match.HeaderName]; foreach (string header in headersForKey) { //HACK: This is to support token Id's infront of the canary for tracing back persistent Xss vulns. string id = String.Format("{0:x4}", ResultProcessingEngine.TokenId); Token t = new Token(id + tt.Identifier); ResultProcessingEngine.TokenId++; StringBuilder sb = new StringBuilder(header); if (match.Token.TokenLength > 0) { sb.Replace(match.Token.Identifier, t.Identifier, match.Offset, match.Token.TokenLength); } else { sb.Insert(match.Offset, t.Identifier); } headersForKey.Remove(header); headersForKey.Add(sb.ToString()); } ret.Add(newSession); } return ret; }
public MatchCollection InspectResponse(Session s, Token t) { MatchCollection retList = new MatchCollection(); retList.AddRange(s.Response.FindTokenInHeaders(t, s.Id)); retList.AddRange(s.Response.FindTokenInBody(t, s.Id)); return retList; }
public static List<Session> ProcessBodyResults(Session s, List<BodyMatch> bodyMatches, Token tt) { List<Session> ret = new List<Session>(); foreach (BodyMatch match in bodyMatches) { //HACK: This is to support token Id's infront of the canary for tracing back persistent Xss vulns. string id = String.Format("{0:x4}", ResultProcessingEngine.TokenId); Token t = new Token(id + tt.Identifier); ResultProcessingEngine.TokenId++; Session newSession = s.deepClone(); StringBuilder sb = new StringBuilder(newSession.Request.GetBodyEncodedAs(Encoding.UTF8)); if (match.Token.TokenLength > 0) { sb.Replace(match.Token.Identifier, t.Identifier, match.Offset, match.Token.TokenLength); } else { sb.Insert(match.Offset, t.Identifier); } newSession.Request.BodyBytes = Encoding.UTF8.GetBytes(sb.ToString()); ret.Add(newSession); } return ret; }
//below is for dealing with "Request checking" when looking for a token in a request to replace with a test case. public MatchCollection LocateTokensInRequest(Session s, Token canary) { MatchCollection retList = new MatchCollection(); retList.AddRange(s.Request.FindTokenInHeaders(canary, s.Id)); retList.AddRange(s.Request.FindTokenInBody(canary, s.Id)); return retList; }
public MatchCollection FindTokenInBody(Token t, int sessionId) { string body = System.Text.Encoding.UTF8.GetString(this.BodyBytes); MatchCollection mc = new MatchCollection(); for (int i = body.IndexOf(t.Identifier); i > 0 && i != -1; ) { //so the canary is present, lets muck with it! mc.Add(new BodyMatch(t, i, sessionId)); i = body.IndexOf(t.Identifier, i + t.TokenLength); } return mc; }
public MatchCollection FindTokenInHeaders(Token t, int sessionId) { MatchCollection mc = new MatchCollection(); foreach (string header in this.headers.Keys) { int k = 0; foreach(string val in this.headers[header]){ if (val.Contains(t.Identifier)) { for (int i = header.IndexOf(t.Identifier); i > 0 && i != -1; ) { //so the canary is present, lets muck with it! mc.Add(new ResponseHeaderMatch(t, i, sessionId, header, k)); i = header.IndexOf(t.Identifier, i + t.TokenLength); } } k++; } } return mc; }
/// <summary> /// This method creates the session list to be injected.. /// </summary> /// <param name="s"></param> /// <param name="queryStringMatches"></param> /// <param name="t">This token is the replacement value..</param> /// <param name="encodeQueryStringParams"></param> /// <returns></returns> public static List<Session> ProcessQueryStringResults(Session s, List<QueryStringMatch> queryStringMatches, Token tt, bool encodeQueryStringParams) { List<Session> ret = new List<Session>(); foreach (QueryStringMatch match in queryStringMatches) { //HACK: This is to support token Id's infront of the canary for tracing back persistent Xss vulns. string id = String.Format("{0:x4}", ResultProcessingEngine.TokenId); Token t = new Token(id + tt.Identifier); ResultProcessingEngine.TokenId++; Session newSession = s.deepClone(); StringBuilder sb = new StringBuilder(newSession.Request.Path); if (match.Token.TokenLength > 0) { sb.Replace(match.Token.Identifier, t.Identifier, match.Offset, match.Token.TokenLength); } else { sb.Insert(match.Offset, t.Identifier); } newSession.Request.Path = sb.ToString(); ret.Add(newSession); } return ret; }
public MatchBase(Token t, int offset, int sessionId) { this.token = t; this.Offset = offset; this.SessionId = sessionId; }
/// <summary> /// /// </summary> /// <param name="s">Original Session</param> /// <param name="mc">Collection which contains the tokens to be replaced</param> /// <param name="t">The token to replace with</param> /// <returns></returns> private List<Session> GetSessionsForToken(Session s, MatchCollection mc, Token t) { List<Session> sessions = new List<Session>(); if (Settings.checkRequestForCanary || Settings.injectIntoPost) { if (Settings.urlEncodeBodyMatches) { t = new Token(HttpUtility.UrlEncode(t.Identifier)); } sessions.AddRange(ResultProcessingEngine.ProcessBodyResults(s, mc.GetMatchesInBody(), t)); } if (Settings.checkRequestForCanary || Settings.injectIntoHeaders) { if (Settings.urlEncodeHeaderMatches) { t = new Token(HttpUtility.UrlEncode(t.Identifier)); } sessions.AddRange(ResultProcessingEngine.ProcessHeaderResults(s, mc.GetMatchesInHeaders(), t)); } if (Settings.injectIntoQueryString) { if (Settings.urlEncodeQueryStringMatches) { //This code encodes the query string param if the value is set to true in the settings. t = new Token(HttpUtility.UrlEncode(t.Identifier)); } sessions.AddRange(ResultProcessingEngine.ProcessQueryStringResults(s, mc.GetMatchesInQueryString(), t, this.Settings.urlEncodeQueryStringMatches)); } return sessions; }
/// <summary> /// Returns a list of session objects.. These session objects contain the *Replaced* matches.. This is where overlong logic occurs.. (if(tc==overlong)create new token as overlong) /// </summary> /// <param name="mc"></param> private List<Session> GetRequestsToInject(Session s, MatchCollection mc) { List<Session> sessions = new List<Session>(); foreach(UnicodeTestCase tc in this.Settings.UnicodeTestMappings){ if (tc.Enabled) { Token replaceValue; if (tc.Type == UnicodeTestCaseTypes.Overlong) { byte[] bytes = XNMD.UTF8Encoder.GetOverlongForCodePoint(tc.SourcePoint.CodePoint, 2); string enc = HttpUtility.UrlEncode(bytes); replaceValue = new Token(this.Settings.canary + enc); } else { replaceValue = new Token(this.Settings.canary + tc.SourcePoint.ToString()); } List<Session> tmp = this.GetSessionsForToken(s, mc, replaceValue); foreach (Session sess in tmp) { sess.ContainsCodePoint = true; sess.Chr = tc.SourcePoint; } sessions.AddRange(tmp); } } return sessions; }
public ResponseHeaderMatch(Token t, int offset, int sessionId, string headerName, int index) : base(t, offset, sessionId, headerName) { this.index = index; }
public QueryStringMatch(Token t, int offset, int sessionId) : base(t, offset, sessionId) { }
public BodyMatch(Token t, int offset, int sessionId) : base(t, offset, sessionId) { }
public HeaderMatch(Token t, int offset, int sessionId, string headerName) : base(t, offset, sessionId) { this.headerName = headerName; }
public MatchCollection FindTokenMatchesInResponse(Session s, Token t) { MatchCollection mc = null; foreach (IResponseParser parser in parsers) { mc = parser.InspectResponse(s, t); } return mc; }