All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.owasp.jbrofuzz3.message.Request Maven / Gradle / Ivy

/**
 * JbroFuzz 2.5
 *
 * JBroFuzz - A stateless network protocol fuzzer for web applications.
 * 
 * Copyright (C) 2007 - 2010 [email protected]
 *
 * This file is part of JBroFuzz.
 * 
 * JBroFuzz is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * JBroFuzz is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with JBroFuzz.  If not, see .
 * Alternatively, write to the Free Software Foundation, Inc., 51 
 * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * Verbatim copying and distribution of this entire program file is 
 * permitted in any medium without royalty provided this notice 
 * is preserved. 
 * 
 */
package org.owasp.jbrofuzz3.message;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;

/**
 * 

An HTTP Request (regardless of version) can be created * from a java String.

* *

It can be broken down to a number of constant * sub-strings, called elements and a number of different * types.

* *

Thus the process of obtaining the message as it to * be put on the wire, becomes the process of iterating * through the different types and 'padding' the * respective values of elements where it is required. * * @author [email protected] * @version 2.5 * @since 2.5 * */ public class Request { private ArrayList types; private ArrayList elements; private static byte CRLF = 1; private static byte PLAINTEXT = 2; private final int messageBodyLocation; private final int contentLengthHeaderLocation; /** * Simple test method, to be removed later on * * @param args */ public static void main(String [] args) { String [] messages = { "", "\n\n\n\n\n\n\n\n", "GET /ig/extern_js/f/CgJlbB/2qJTcRRHu10.js HTTP/1.1\n" + "Host: www.google.com\n" + "Referer: http://www.google.com/ig?refresh=1" + "\n" + "\n", "GET /index.html", "POST /someURL.jsp?user=one HTTP/1.0\n" + "Host: localhost\n" + "Content-Length: 61\n" + "\n" + "project=WIP&surname=last&firstName=first&language=en", "POST /SomeLoc/SWService HTTP/1.1\n" + "Host: somelocation.com\n" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n" + "Accept-Language: en-gb,en;q=0.5\n" + "Accept-Encoding: gzip,deflate\n" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n" + "Keep-Alive: 115\n" + "Connection: keep-alive" + "Referer: https://www.theref.com\n" + "Content-type: text/xml; charset=utf-8\n" + "SOAPAction: \"\"\n" + "Content-Length: 413\n" + "\n" + "\n" + "\n" + "\n" + "asdf\n" + "asd\n" + "\n" + "\n" + "\n" + "\n" + "\n" }; for(String message : messages) { Request r = new Request(message); System.out.println(">>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Start -->"); System.out.println("Message:\n"+r.getRequestForDisplayPurposes()); debug(r); System.out.println("Type size is: " + r.getTypes().size()); System.out.println("Has message body: " + r.isMessageBodyPresent()); System.out.println("Adding a header: Header: MyHeaderOne!"); r.addHeader("Header: MyHeaderOne!"); debug(r); System.out.println("New Message:\n"+r.getRequestForDisplayPurposes()); System.out.println("<-- End <<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); } System.out.println("Done!"); } public void addHeader(String header) { if(messageBodyLocation > 0) { final int lastHeaderType = types.size() - 2; types.add(lastHeaderType, Request.CRLF); types.add(lastHeaderType, Request.PLAINTEXT); final int lastHeaderElement = elements.size() - 1; elements.add(lastHeaderElement, header); } else { if(types.size() > 0) { types.add(Request.CRLF); } types.add(Request.PLAINTEXT); elements.add(header); } } /** *

Method to check if a content-length header exists * within the list of types and elements.

* * @return The index within types where the content-length * header is; -1 otherwise. * * @author [email protected] * @version 2.5 * @since 2.5 * */ public int hasContentHeader() { Iterator itrTypes = types.iterator(); Iterator itrData = elements.iterator(); int counter = 0; while(itrTypes.hasNext()) { byte currentType = itrTypes.next(); if(currentType != CRLF) { final String currentString = itrData.next().toLowerCase(); if(currentString.startsWith("content-length:")) { return counter; } } counter++; } return -1; } /** *

Method to check if the request has a message body.

* *

The check is based upon the following pattern, ending * the types array: * PLAINTEXT CRLF CRLF PLAINTEXT * * @author [email protected] * @version 2.5 * @since 2.5 * */ public boolean isMessageBodyPresent() { return (messageBodyLocation > 0); } /** *

Method for checking if a content-length header is * present within the request.

* * @return true if present, false otherwise. * * @author [email protected] * @version 2.5 * @since 2.5 * */ public boolean isContentLengthHeaderPresent() { return (contentLengthHeaderLocation > 0); } /** *

Constructor responsible for passing a plain message, * into a Request that can be placed on the wire.

* * @param message e.g. * * "POST /someURL.jsp?user=one HTTP/1.0\n" + * "Host: localhost\n" + * "\n\n" * * * @author [email protected] * @version 2.5 * @since 2.5 * */ public Request(final String message) { // Initialise types = new ArrayList(); elements = new ArrayList(); // Break down the message into types & elements loadMessage(message, types, elements); // Remove any CRLFs from the end of the message removeEndCRLFs(types); // Check for message type and define it if present messageBodyLocation = findMessageBodyLocation(); // Set the location of the content-length header; // -1 if not present contentLengthHeaderLocation = hasContentHeader(); } /** *

This method removes up to 16 end of line types (i.e. CRLF * characters) from the end of the types array.

* * @param types The array of types * * @author [email protected] * @version 2.5 * @since 2.5 * */ private static void removeEndCRLFs(ArrayList types) { byte count = 0; while(count < 16) { int lastType = types.size() - 1; if(lastType < 0) { return; } else { if(types.get(lastType) == CRLF) { types.remove(lastType); } else { return; } } count++; } } /** *

Method that checks to see if the last element in the * types array is a message body.

* *

The check is based upon the following pattern, ending * the types array: * PLAINTEXT CRLF CRLF PLAINTEXT * * @param types * @return true if the above pattern is present * * @author [email protected] * @version 2.5 * @since 2.5 * */ private int findMessageBodyLocation() { Iterator itrTypes = types.iterator(); int returnValue = -1; byte pattern1 = PLAINTEXT; byte pattern2 = CRLF; byte pattern3 = CRLF; byte pattern4 = PLAINTEXT; Stack messageBodyPattern = new Stack(); while(itrTypes.hasNext()) { if(messageBodyPattern.size() == 4) { } messageBodyPattern.push(itrTypes.next()); } return returnValue; } /** *

Take a message and break it to two arrays: * one of types and one of elements.

* *

Thus the following message: * * "POST /someURL.jsp?user=one HTTP/1.0\n" + * "Host: localhost\n" + * "\n\n" * * would result in an array of types (bytes): * * [ PLAINTEXT, CRLF, PLAINTEXT, CRLF, CRLF, CRLF] * * and an array of elements (strings): * * [ "POST /someURL.jsp?user=one HTTP/1.0" * "Host: localhost" ] * * * @param message Note that only '\n' is read for CRLF * @param types The array to be populated * @param elements The array to be populated * * @author [email protected] * @version 2.5 * @since 2.5 * */ private static void loadMessage(final String message, ArrayList types, ArrayList elements) { char[] charArray = message.toCharArray(); StringBuffer sb = new StringBuffer(); for(char c : charArray) { if(c == '\n') { int dataLength = sb.length(); if(dataLength > 0) { elements.add(sb.toString()); sb.delete(0, dataLength); types.add(PLAINTEXT); } types.add(CRLF); } else { sb.append(c); } } int dataLength = sb.length(); if(dataLength > 0) { elements.add(sb.toString()); sb.delete(0, dataLength); types.add(PLAINTEXT); } } /** * Debug method to be commented out. * * @param r */ private static void debug(Request r) { Iterator itrTypes = r.getTypes().iterator(); Iterator itrData = r.getElements().iterator(); System.out.println("Types Array: "); while (itrTypes.hasNext()) { System.out.print(itrTypes.next() + " "); } System.out.println(""); System.out.println("Types Data: "); while (itrData.hasNext()) { System.out.print("[" + itrData.next() + "] "); } System.out.println(""); } private ArrayList getElements() { // TODO Auto-generated method stub return elements; } private ArrayList getTypes() { // TODO Auto-generated method stub return types; } public String getRequest() { StringBuffer output = new StringBuffer(); Iterator itrTypes = types.iterator(); Iterator itrData = elements.iterator(); while(itrTypes.hasNext()) { byte currentType = itrTypes.next(); switch (currentType) { case 1: output.append('\r'); output.append('\n'); break; case 2: output.append(itrData.next()); break; } } if( (types.size() > 0) && (!isMessageBodyPresent()) ) { output.append('\r'); output.append('\n'); output.append('\r'); output.append('\n'); } return output.toString(); } public String getRequestForDisplayPurposes() { StringBuffer output = new StringBuffer(); Iterator itrTypes = types.iterator(); Iterator itrData = elements.iterator(); while(itrTypes.hasNext()) { byte currentType = itrTypes.next(); switch (currentType) { case 1: output.append("CRLF"); output.append('\n'); break; case 2: output.append(itrData.next()); break; } } if( (types.size() > 0) && (!isMessageBodyPresent()) ) { output.append("CRLF"); output.append('\n'); output.append("CRLF"); output.append('\n'); } return output.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy