Package org.owasp.webscarab.plugin.fuzz

Source Code of org.owasp.webscarab.plugin.fuzz.Fuzzer

/***********************************************************************
*
* $CVSHeader$
*
* This file is part of WebScarab, an Open Web Application Security
* Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2004 Rogan Dawes
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* Getting Source
* ==============
*
* Source for this application is maintained at Sourceforge.net, a
* repository for free software projects.
*
* For details, please see http://www.sourceforge.net/projects/owasp
*
*/

/*
* $Id: Fuzzer.java,v 1.8 2005/09/21 22:06:33 rogan Exp $
*/

package org.owasp.webscarab.plugin.fuzz;

import org.owasp.webscarab.httpclient.ConversationHandler;
import org.owasp.webscarab.httpclient.FetcherQueue;

import org.owasp.webscarab.model.Preferences;
import org.owasp.webscarab.model.ConversationID;
import org.owasp.webscarab.model.HttpUrl;
import org.owasp.webscarab.model.Request;
import org.owasp.webscarab.model.Response;
import org.owasp.webscarab.model.StoreException;
import org.owasp.webscarab.model.NamedValue;

import org.owasp.webscarab.plugin.Framework;
import org.owasp.webscarab.plugin.Plugin;
import org.owasp.webscarab.plugin.Hook;

import org.owasp.webscarab.util.Encoding;

import java.util.logging.Logger;

import java.net.URL;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;

public class Fuzzer implements Plugin, ConversationHandler {
   
    private FuzzerModel _model = null;
    private Framework _framework = null;
    private FuzzFactory _fuzzFactory = new FuzzFactory();
   
    private FetcherQueue _fetcherQueue = null;
    private int _threads = 4;
   
    private Logger _logger = Logger.getLogger(getClass().getName());
   
    public Fuzzer(Framework framework) {
        _framework = framework;
        _model = new FuzzerModel(_framework.getModel());
        loadFuzzStrings();
        _fetcherQueue = new FetcherQueue("Fuzzer", this, _threads, 0);
    }
   
    private void loadFuzzStrings() {
        int i = 0;
        String description;
        while ((description = Preferences.getPreference("Fuzz." + i + ".description")) != null) {
            String location = Preferences.getPreference("Fuzz." + i + ".location");
            if (location != null && !description.equals("")) {
                try {
                    URL url = new URL(location);
                    _fuzzFactory.loadFuzzStrings(description, url.openStream());
                } catch (IOException ioe) {
                    _logger.warning("Error loading \"" + description + "\" from " + location + " : " + ioe.getMessage());
                }
            }
            i++;
        }
    }
   
    public FuzzFactory getFuzzFactory() {
        return _fuzzFactory;
    }
   
    public FuzzerModel getModel() {
        return _model;
    }
   
    /** The plugin name
     * @return The name of the plugin
     *
     */
    public String getPluginName() {
        return new String("Fuzzer");
    }
   
    public void run() {
        _model.setStatus("Started");
        _model.setStopping(false);
       
        _model.setRunning(true);
        while (!_model.isStopping()) {
            // queue them as fast as they come, sleep a bit otherwise
            boolean submittedRequest = queueRequests();
            if (!submittedRequest) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ie) {}
            }
        }
        _fetcherQueue.clearRequestQueue();
        _model.setRunning(false);
        _model.setStatus("Stopped");
    }
   
    public void startFuzzing() {
        int count = _model.getFuzzParameterCount();
        if (count>0 && _model.getFuzzUrl() != null) {
            _model.setBusyFuzzing(true);
        } else {
            _logger.warning("Can't fuzz if there are no parameters or URL");
        }
    }
   
    private Request constructCurrentFuzzRequest() throws MalformedURLException {
        Request request = new Request();
        request.setMethod(_model.getFuzzMethod());
        request.setVersion(_model.getFuzzVersion());
        int count = _model.getFuzzHeaderCount();
        // _logger.info("Got headers: " + count);
        for (int i=0; i<count; i++) {
            // _logger.info("Header is " + _model.getFuzzHeader(i));
            request.addHeader(_model.getFuzzHeader(i));
        }
//        if (request.getMethod().equals("POST")) {
//            request.setHeader("Content-Type", "application/x-www-form-urlencoded");
//        }
        String url = _model.getFuzzUrl().toString();
        String path = null;
        String fragment = null;
        String query = null;
        String cookie = null;
        ByteArrayOutputStream content = null;
        count = _model.getFuzzParameterCount();
        for (int i=0; i<count; i++) {
            Parameter parameter = _model.getFuzzParameter(i);
            Object value = _model.getFuzzParameterValue(i);
            String location = parameter.getLocation();
            if (location.equals(Parameter.LOCATION_PATH)) {
                if (path == null) {
                    path = (String) value;
                } else {
                    path = path + "/" + (value == null ? "" : (String) value);
                }
            } else if (location.equals(Parameter.LOCATION_FRAGMENT)) {
                String frag = parameter.getName();
                if (frag == null) {
                    frag = (String) value;
                } else if (value == null) {
                    frag = frag + "=" + Encoding.urlEncode((String) value);
                } else {
                    frag = null;
                }
                if (fragment == null) {
                    fragment = frag;
                } else if (frag != null) {
                    fragment = fragment + "&" + frag;
                }
            } else if (location.equals(Parameter.LOCATION_QUERY)) {
                String q = parameter.getName() + "=" + Encoding.urlEncode((String) value);
                if (query == null) {
                    query = q;
                } else {
                    query = query + "&" + q;
                }
            } else if (location.equals(Parameter.LOCATION_COOKIE)) {
                String c = parameter.getName() + "=" + (String) value;
                if (cookie == null) {
                    cookie = c;
                } else {
                    cookie = cookie + "; " + c;
                }
            } else if (location.equals(Parameter.LOCATION_BODY)) {
                // FIXME - Assumes this is normal form data
                String b = parameter.getName() + "=" + Encoding.urlEncode((String) value);
                if (content == null) {
                    content = new ByteArrayOutputStream();
                    try { content.write(b.getBytes()); }
                    catch (IOException ioe) {}
                } else {
                    try { content.write(("&"+b).getBytes()); }
                    catch (IOException ioe) {}
                }
            } else {
                _logger.severe("Skipping unknown parameter location " + location);
            }
        }
        if (path != null) url = url + "/" + path;
        if (fragment != null) url = url + ";" + fragment;
        if (query != null) url = url + "?" + query;
        request.setURL(new HttpUrl(url));
        if (cookie != null) request.addHeader("Cookie", cookie);
        if (content != null) {
            request.setHeader("Content-Length", Integer.toString(content.size()));
            request.setContent(content.toByteArray());
        } else if (request.getMethod().equals("POST")) {
            request.setHeader("Content-Length", "0");
        }
        return request;
    }
   
    public void pauseFuzzing() {
        _model.setBusyFuzzing(false);
    }
   
    public void stopFuzzing() {
        _model.setBusyFuzzing(false);
    }
   
    private boolean queueRequests() {
        if (!_model.isBusyFuzzing()) return false;
        if (_fetcherQueue.getRequestsQueued()>=_threads) return false;
        try {
            Request request = constructCurrentFuzzRequest();
            _fetcherQueue.submit(request);
            if (!_model.incrementFuzzer()) {
                _model.setBusyFuzzing(false);
            }
        } catch (Exception e) {
            _model.setBusyFuzzing(false);
            e.printStackTrace();
            return false;
        }
        return true;
    }
   
    public void requestError(Request request, IOException ioe) {
        _logger.warning("Caught exception : " + ioe.getMessage());
        _model.setBusyFuzzing(false);
    }
   
    public void responseReceived(Response response) {
        if (response.getStatus().equals("400")) {
            _logger.warning("Bad request");
            _model.setBusyFuzzing(false);
            return;
        }
        Request request = response.getRequest();
        if (request == null) {
            _logger.warning("Got a null request from the response!");
            return;
        }
        ConversationID id = _framework.addConversation(request, response, "Fuzzer");
        _model.addConversation(id);
    }
   
    public boolean stop() {
        _model.setStatus("Stopped");
        _model.setRunning(false);
        return ! _model.isRunning();
    }
   
    public void setSession(String type, Object store, String session) throws org.owasp.webscarab.model.StoreException {
    }
   
    public void flush() throws StoreException {
    }
   
    public boolean isBusy() {
        return _model.isBusy();
    }
   
    public boolean isRunning() {
        return _model.isRunning();
    }
   
    public String getStatus() {
        return _model.getStatus();
    }
   
    public boolean isModified() {
        return _model.isModified();
    }
   
    public void analyse(ConversationID id, Request request, Response response, String origin) {
        Signature signature = new Signature(request);
        _model.addSignature(signature);
        if (!response.getStatus().equals("304")) {
            byte[] content = response.getContent();
            if (content == null) content = new byte[0];
            String checksum = Encoding.hashMD5(content);
            _model.addChecksum(signature.getUrl(), checksum);
        }
    }
   
    public void loadTemplateFromConversation(ConversationID id) {
        if (_model.isBusyFuzzing()) {
            stopFuzzing();
        }
        Request request = _framework.getModel().getRequest(id);
        HttpUrl url = request.getURL();
        if (url.getParameters()!=null)
            url = url.getParentUrl();
        _model.setFuzzMethod(request.getMethod());
        _model.setFuzzUrl(url.toString());
        _model.setFuzzVersion(request.getVersion());
        while(_model.getFuzzHeaderCount()>0) {
            _model.removeFuzzHeader(0);
        }
        while(_model.getFuzzParameterCount()>0) {
            _model.removeFuzzParameter(0);
        }
        NamedValue[] headers = request.getHeaders();
        if (headers != null) {
            for (int i=0; i<headers.length; i++) {
                if (headers[i].getName().equals("Cookie"))
                    continue;
                _model.addFuzzHeader(_model.getFuzzHeaderCount(), headers[i]);
            }
        }
        Parameter[] params = Parameter.getParameters(request);
        for (int i=0; i<params.length; i++) {
            _model.addFuzzParameter(i, params[i], null, 0);
        }
    }
   
    public Object getScriptableObject() {
        return null;
    }
   
    public Hook[] getScriptingHooks() {
        return new Hook[0];
    }
   
}
TOP

Related Classes of org.owasp.webscarab.plugin.fuzz.Fuzzer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.