org.owasp.jbrofuzz.core.Fuzzer.java Source code

Java tutorial

Introduction

Here is the source code for org.owasp.jbrofuzz.core.Fuzzer.java

Source

/**
 * JbroFuzz 2.5
 *
 * JBroFuzz - A stateless network protocol fuzzer for web applications.
 * 
 * Copyright (C) 2007 - 2010 subere@uncon.org
 *
 * 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 <http://www.gnu.org/licenses/>.
 * 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.jbrofuzz.core;

import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.apache.commons.lang.StringUtils;

/**
 * <p>
 * A fuzzer is an iterator that is constructed based on a prototype, carrying
 * the payloads and the fuzzer type information.
 * </p>
 * 
 * <p>This class is limited by the long primitive data type, i.e. we can only
 * create Fuzzers that iterate up to the value of a 64-bit signed two's 
 * complement integer. The maximum number of values we can iterate 
 * through are: <b>9,223,372,036,854,775,807</b> (inclusive).</p>
 * 
 * <p>For larger values, you can use the FuzzerBigInteger class.</p>
 * 
 * @author subere@uncon.org
 * @version 2.4
 * @since 1.2
 */
public class Fuzzer implements Iterator<String> {

    final private transient int len;

    final private transient Prototype prototype;

    private transient List<String> payloads;

    private transient long cValue, maxValue;

    /**
     * <p>This constructor is available through the factory method, createFuzzer(), 
     * available in the Database class.</p>
     * 
     * <p>The length specifies the number of digits, in terms of characters that
     * the Fuzzer will be used for. This is required for recursive and zero fuzzers,
     * where an iteration is taking place.</p>
     * 
     * @see Database.createFuzzer(String id, int length)
     * 
     * @param prototype The prototype id, as read from the fuzzers.jbrf file
     *                e.g. "031-B16-HEX" for the hexadecimal alphabet     
     * 
     * @param len      The length of the fuzzer, required for recursive and zero
     *                fuzzers. This should always be a positive integer.
     *       
     * @throws NoSuchFuzzerException
     * 
     * @author subere@uncon.org
     * @version 1.8
     * @since 1.2
     */
    protected Fuzzer(final Prototype prototype, final int len) throws NoSuchFuzzerException {

        this.prototype = prototype;

        if (prototype == null) {

            maxValue = 0L;

        } else {

            payloads = this.prototype.getPayloads();

            if (this.prototype.isRecursive()) {

                maxValue = Fuzzer.pow(payloads.size(), len);

            } else {
                maxValue = payloads.size();

            }

        }

        cValue = 0L;
        this.len = len;

    }

    /**
     * <p>Get the current numeric value as a long that the fuzzer
     * is iterating through.</p>
     * 
     * <p>Say that you have the hexadecimal fuzzer 'HEX-...' of 
     * length 5. This implies that there will be 16^5 = 1048576 of
     * values to iterate through.</p>
     * 
     * <p>This method gives you the ability to know to return on the 
     * current iteration, the numeric value we are currently on.</p>
     * 
     * @return as a long, the numeric value, e.g. '1048576'
     * 
     * @author subere@uncon.org
     * @version 1.8
     * @since 1.2
     */
    public long getCurrentValue() {

        return cValue;

    }

    public long getMaxValue() {
        return maxValue;
    }

    /**
     * <p>Resets the current value back to 0, as the value is set
     * during construction.</p>
     * 
     * @author subere@uncon.org
     * @version 2.0
     * @since 2.0
     */
    public void resetCurrentValue() {

        cValue = 0L;

    }

    /**
     * <p>Returns the Fuzzer unique ID, in the format of, say, '024-XSS-101'.</p>
     * 
     * <p>This is also the unique ID used by the Prototype and the Database.</p>
     * 
     * @return the unique ID as String
     * 
     * @author subere@uncon.org
     * @version 1.5
     * @since 1.2
     */
    public String getId() {

        return prototype.getId();

    }

    /**
     * <p>Return the maximum value of the iteration as a long.</p>
     * 
     * <p>For Zero Fuzzers and Replacive Fuzzers, this value will be
     * the number of payloads that the fuzzer has, i.e. the length of 
     * the alphabet that the fuzzer carries.</p>
     * 
     * @return as long, the numeric value, e.g. '1048576'
     * 
     * @author subere@uncon.org
     * @version 2.4
     * @since 1.2
     */
    public long getMaximumValue() {

        return maxValue;

    }

    /**
     * <p>Returns the Fuzzer name, as a String, say, 'Hexadecimal Fuzzer'.</p>
     * 
     * @return the fuzzer name as String
     * 
     * @author subere@uncon.org
     * @version 1.5
     * @since 1.2
     */
    public String getName() {

        return prototype.getName();

    }

    /**
     * <p>Check whether or not the fuzzer iterator has a next element.</p>
     * 
     * @return true if the fuzzer has more elements to return during its 
     *             iteration
     * 
     * @author subere@uncon.org
     * @version 2.0
     * @since 1.2
     */
    public boolean hasNext() {

        return cValue < maxValue;

    }

    /**
     * <p>Return the next element of the fuzzer during iteration.</p>
     * 
     * <p>This method should be used to access fuzzing payloads, after
     * construction of the fuzzer object.</p>
     * 
     * @return String   The next fuzzer payload, during the iteration 
     *                process
     * 
     * @author subere@uncon.org
     * @version 2.0
     * @since 1.2
     */
    public String next() {

        final StringBuffer output = new StringBuffer();

        // Replacive Prototype
        if (maxValue == payloads.size()) {

            cValue++;
            output.append(payloads.get((int) cValue - 1));

        }
        // Recursive Prototype
        else {

            long val = cValue;
            // Perform division on a stack
            final Stack<Integer> stack = new Stack<Integer>();

            while (val >= payloads.size()) {

                stack.push(Integer.valueOf((int) val % payloads.size()));

                val = val / payloads.size();

            }
            // Append the relevant empty positions with the first element
            // identified
            output.append(StringUtils.leftPad(payloads.get((int) val), len - stack.size(), payloads.get(0)));
            while (!stack.isEmpty()) {
                output.append(payloads.get(stack.pop().intValue()));
            }

            cValue++;

        }

        return output.toString();

    }

    /**
     * <p>This method should not be trusted or used in the conventional
     * way that an iterator requires remove to be implemented.</p>
     * 
     * <p>Instead, during fuzzing, remove() can be called to
     * step back to the previous element.</p>
     * 
     * <p>This need is typical, in replay scenarios where something
     * worth investigating has been discovered and a quick, step
     * back step forward is executed.</p>
     * 
     * @author subere@uncon.org
     * @version 2.4
     * @since 2.4
     */
    public void remove() {
        cValue--;
    }

    /**
     * <p>Static method calculating the result of: alpha^beta</p>
     * <p>If alpha^beta > Long.MAX_VALUE return 0.</p>
     * 
     * @param alpha The base
     * @param beta The power
     * @return alpha^beta as a long value
     */
    private static long pow(final int alpha, final int beta) {

        long gamma = (beta) & 0x00000000ffffffffL;
        long result = 1L;
        long powerN = alpha;

        while (gamma != 0) {
            if ((gamma & 1) != 0) {
                result *= powerN;
            }
            gamma >>>= 1;
            powerN = powerN * powerN;
        }

        return result;
    }

}