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

Java tutorial

Introduction

Here is the source code for org.owasp.jbrofuzz.core.FuzzerBigInteger.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.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.apache.commons.lang.StringUtils;

/**
 * <p>
 * FuzzerBigInteger implements a fuzzer iterator using BigInteger; as a 
 * result, iterations are not limited to LONG.MAX_VALUE < 16^16. 
 * </p>
 * <p>
 * As this class uses BigInteger, it is much heaver on the memory constraints
 * then the Fuzzer class.
 * <p>
 * A fuzzer is an iterator that is constructed based on a prototype, carrying
 * the payloads and the fuzzer type information.
 * </p>
 * 
 * 
 * @author subere@uncon.org
 * @version 1.9
 * @since 1.9
 */
public class FuzzerBigInteger implements Iterator<String> {

    private final transient int len;

    private final transient Prototype prototype;

    private transient List<String> payloads;

    private transient BigInteger cValue, maxValue;

    /**
     * <p>This constructor is available through the factory method, 
     * createFuzzerBigInteger(), 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.createFuzzerBigInteger(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 2.4
     * @since 1.2
     */
    protected FuzzerBigInteger(final Prototype prototype, final int len) throws NoSuchFuzzerException {

        this.prototype = prototype;

        if (prototype == null) {

            maxValue = BigInteger.ZERO;

        } else {

            payloads = this.prototype.getPayloads();

            if (this.prototype.isRecursive()) {

                maxValue = BigInteger.valueOf(payloads.size());
                maxValue = maxValue.pow(len < 0 ? 0 : len);

            } else {
                maxValue = BigInteger.valueOf(payloads.size());

            }
        }

        cValue = BigInteger.ZERO;
        this.len = len;

    }

    /**
     * <p>Get the current String value that the fuzzer is on.</p>
     * 
     * <p>Say that you have the hexadecimal fuzzer with ID 
     * '031-B16-HEX' of length 10. This implies that there 
     * will be 16^10 = 2^40 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 String, the numeric value, e.g. "1099511627776"
     * 
     * @author subere@uncon.org
     * @version 2.4
     * @since 2.4
     */
    public String getCurrectValue() {

        return cValue.toString();

    }

    /**
     * <p>Returns the Fuzzer unique ID, in the format of, say, "030-XSS-BRK".</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 2.4
     * @since 2.4
     */
    public String getId() {

        return prototype.getId();

    }

    /**
     * <p>Return the maximum value of the iteration as a String.</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 String, the numeric value, e.g. '1048576'
     * 
     * @author subere@uncon.org
     * @version 2.4
     * @since 2.4
     */
    public String getMaximumValue() {

        return maxValue.toString();

    }

    /**
     * <p>Returns the Fuzzer name, as a String, say, 'Hexadecimal Fuzzer'.</p>
     * 
     * @return the fuzzer name as String
     * 
     * @author subere@uncon.org
     * @version 2.4
     * @since 2.4
     */
    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.4
     * @since 1.2
     */
    public boolean hasNext() {

        return cValue.compareTo(maxValue) < 0;

    }

    /**
     * <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.4
     * @since 1.2
     */
    public String next() {

        final StringBuffer output = new StringBuffer("");

        // Replacive Prototype
        if (maxValue.compareTo(BigInteger.valueOf(payloads.size())) == 0) {

            output.append(payloads.get(cValue.intValue()));
            cValue = cValue.add(BigInteger.ONE);

        }
        // Recursive Prototype
        else {

            BigInteger val = cValue;
            // Perform division on a stack
            final Stack<BigInteger> stack = new Stack<BigInteger>();
            while (val.compareTo(BigInteger.valueOf(payloads.size())) >= 0) {

                stack.push(val.mod(BigInteger.valueOf(payloads.size())));
                val = val.divide(BigInteger.valueOf(payloads.size()));

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

            cValue = cValue.add(BigInteger.ONE);

        }

        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 = cValue.subtract(BigInteger.ONE);

    }

}