From 1c8d003fc6f7e732dd750697648657cb0c552e98 Mon Sep 17 00:00:00 2001
From: Robert Sharp <rmsharp@student.unimelb.edu.au>
Date: Fri, 18 Oct 2019 17:13:28 +1100
Subject: [PATCH] Created a Brownian Motion Fuzzer.

---
 fuzzer/Fuzzer.java | 388 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 304 insertions(+), 84 deletions(-)

diff --git a/fuzzer/Fuzzer.java b/fuzzer/Fuzzer.java
index 7ee264b..792ffb3 100644
--- a/fuzzer/Fuzzer.java
+++ b/fuzzer/Fuzzer.java
@@ -1,3 +1,8 @@
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.*;
+
 import java.io.IOException;
 import java.io.FileOutputStream;
 import java.io.PrintWriter;
@@ -8,46 +13,90 @@ import java.util.Random;
 public class Fuzzer {
 
     private static final String OUTPUT_FILE = "fuzz.txt";
-    
+
     private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz";
     private static final String CHAR_UPPER = CHAR_LOWER.toUpperCase();
     private static final String NUMBER = "0123456789";
-    
+
     private static final int MAX_LINE_LENGTH = 1022;
-	private static final int MAX_URL_LENGTH = 300;
+    private static final int MAX_URL_LENGTH = 300;
     private static final int numInputLines = 1024; //Indicates the number of inputs we wish to generate in one file
     private static ArrayList<String> savedURLs = new ArrayList<String>(); //save put urls here for get and rem
 
     private static final String DATA_FOR_RANDOM_STRING = CHAR_LOWER + CHAR_UPPER + NUMBER; //specifies which characters can be in a string
-    
+
+    //Brownian values
+    private static boolean USEBROWNIAN = true;
+
+    private static final double PUT_START = 100;
+    private static final double GET_START = 10;
+    private static final double REM_START = 10;
+    private static final double SAVE_START = 10;
+    private static final double LIST_START = 10;
+
+    private static final double PUT_VAR = 20;
+    private static final double GET_VAR = 5;
+    private static final double REM_VAR = 5;
+    private static final double SAVE_VAR = 5;
+    private static final double LIST_VAR = 5;
+
+    //public static void Fuzzer() throws IOException {
     public static void main(String[] args) throws IOException {
+
+        //Rob's code
+        Double[] freqValues = null;
+        Double[] varValues = null;
+
+        //System.out.println("Generated frequency values");
+
+        freqValues = createBrownianList();
+
+        //System.out.println("Generated variance values");
+
+        varValues = createVarianceList();
+
         System.out.println(Instruction.getBNF());
         FileOutputStream out = null;
         PrintWriter pw = null;
         ArrayList<String> inputs = new ArrayList<String>();
-        
+
         try {
             out = new FileOutputStream(OUTPUT_FILE);
             pw = new PrintWriter(out);
-            
+
             /* We just print one instruction.
                Hint: you might want to make use of the instruction
                grammar which is effectively encoded in Instruction.java */
-            
-            /**Using generation-based fuzzing and Instruction.java, 
+
+            /**Using generation-based fuzzing and Instruction.java,
              * create random, valid inputs*/
-            
+
             for(int i=0; i<numInputLines; i++) {
-            	String input = generateValidInputs();
-            	//only add the input if it hasn't already been generated
-            	if(inputAlreadyGenerated(input, inputs)) {
-            		i--;
-            	}else {
-            		inputs.add(input);
-            		pw.println(input);
-            	}
+
+                String input = null;
+
+                if (USEBROWNIAN) {
+                    freqValues = updateBrownianList(freqValues, varValues);
+                    input = generateValidBrownianInputs(freqValues);
+                }
+
+                else {
+
+                    input = generateValidInputs();
+
+                }
+
+                System.out.println(input);
+
+                //only add the input if it hasn't already been generated
+                if(inputAlreadyGenerated(input, inputs)) {
+                    i--;
+                }else {
+                    inputs.add(input);
+                    pw.println(input);
+                }
             }
-            
+
         }catch (Exception e){
             e.printStackTrace(System.err);
             System.exit(1);
@@ -61,59 +110,230 @@ public class Fuzzer {
         }
 
     }
-    
+
+
+
+
+    /**Generates random, valid inputs based on Instruction.java*/
+    public static String generateValidBrownianInputs(Double[] freqValues) {
+
+        Instruction inst = getRandomBrownianInstruction(freqValues);
+
+        String input = inst.getOpcode();
+
+        //add the operands
+        int index =0;
+        for (OperandType op : inst.getOperands()){
+
+            if(index==0 && inst == Instruction.PUT) {
+                //generate a string with URL length for first arg
+                String url = generateRandomString(MAX_URL_LENGTH);
+                //store urls in a list of "saved urls"
+                savedURLs.add(url);
+                input += " "+url;
+
+            }else if(inst == Instruction.GET){
+                //use a saved url if one exists
+                input += " "+ getRandomSavedURL();
+
+            }else if(inst == Instruction.REM){
+                //use and remove a saved url if one exists
+                String url = getRandomSavedURL();
+                if(savedURLs.contains(url)) {
+                    savedURLs.remove(url);
+                }
+                input += " "+ url;
+
+            }else if(op.equals(OperandType.STRING)) {
+                int maxStringLength = MAX_LINE_LENGTH - input.length() - ((inst.getOperands().length-index)*2);
+                input += " "+generateRandomString(maxStringLength);
+            }
+            index++;
+        }
+        //debug
+        //System.out.println(input);
+
+        return input;
+    }
+
     /**Generates random, valid inputs based on Instruction.java*/
     public static String generateValidInputs() {
-    	
-    	//add the instruction string
-    	Instruction inst = getRandomInstruction();
-    	String input = inst.getOpcode();
-    	
-    	//add the operands
-    	int index =0;
-    	for (OperandType op : inst.getOperands()){
-    		
-    		if(index==0 && inst == Instruction.PUT) {
-    			//generate a string with URL length for first arg
-    			String url = generateRandomString(MAX_URL_LENGTH);
-    			//store urls in a list of "saved urls"
-    			savedURLs.add(url);
-    			input += " "+url;
-    			
-    		}else if(inst == Instruction.GET){
-    			//use a saved url if one exists
-    			input += " "+ getRandomSavedURL();
-    			
-    		}else if(inst == Instruction.REM){
-    			//use and remove a saved url if one exists
-    			String url = getRandomSavedURL();
-    			if(savedURLs.contains(url)) {
-    				savedURLs.remove(url);
-    			}
-    			input += " "+ url;
-    			
-    		}else if(op.equals(OperandType.STRING)) {
-    			int maxStringLength = MAX_LINE_LENGTH - input.length() - ((inst.getOperands().length-index)*2);
-    			input += " "+generateRandomString(maxStringLength);
-    		}
-    		index++;
-        }    	
-    	//debug
-    	//System.out.println(input);
-    	
-    	return input;
+
+        Instruction inst = getRandomInstruction();
+
+        String input = inst.getOpcode();
+
+        //add the operands
+        int index =0;
+        for (OperandType op : inst.getOperands()){
+
+            if(index==0 && inst == Instruction.PUT) {
+                //generate a string with URL length for first arg
+                String url = generateRandomString(MAX_URL_LENGTH);
+                //store urls in a list of "saved urls"
+                savedURLs.add(url);
+                input += " "+url;
+
+            }else if(inst == Instruction.GET){
+                //use a saved url if one exists
+                input += " "+ getRandomSavedURL();
+
+            }else if(inst == Instruction.REM){
+                //use and remove a saved url if one exists
+                String url = getRandomSavedURL();
+                if(savedURLs.contains(url)) {
+                    savedURLs.remove(url);
+                }
+                input += " "+ url;
+
+            }else if(op.equals(OperandType.STRING)) {
+                int maxStringLength = MAX_LINE_LENGTH - input.length() - ((inst.getOperands().length-index)*2);
+                input += " "+generateRandomString(maxStringLength);
+            }
+            index++;
+        }
+        //debug
+        //System.out.println(input);
+
+        return input;
     }
-    
+
     /**Selects a random instruction
      * Returns any instruction except for masterpassword
      * */
     public static Instruction getRandomInstruction() {
-    	Instruction[] INSTS = Instruction.values();
-    	int index = new Random().nextInt(INSTS.length-1);
-    	return INSTS[index];
+        Instruction[] INSTS = Instruction.values();
+        int index = new Random().nextInt(INSTS.length-1);
+        return INSTS[index];
+    }
+
+
+    /**Creates a List with different variance values
+     *
+     */
+
+    public static Double[] createVarianceList() {
+
+        /*
+        double PUT_VAR = 20;
+        double GET_VAR = 5;
+        double REM_VAR = 5;
+        double SAVE_VAR = 5;
+        double LIST_VAR = 5;
+         */
+
+        Double[] varValues = new Double[5];
+        varValues[0]=PUT_VAR;
+        varValues[1]=GET_VAR;
+        varValues[2]=REM_VAR;
+        varValues[3]=SAVE_VAR;
+        varValues[4]=LIST_VAR;
+
+        return(varValues);
+
+    }
+
+    /**Update the frequency values based on
+     *
+     */
+
+    public static Double[] updateBrownianList(Double[] freqValues, Double[] varValues) {
+
+        int i;
+
+        Instruction[] INSTS = Instruction.values();
+
+        Random random = new Random();
+
+        for (i = 0; i < INSTS.length-1; i++) {
+
+            freqValues[i] = freqValues[i] + ((random.nextDouble() * 2) -1) * varValues[i];
+            //System.out.println("The index of: "+i + "has the frequency values of: "+freqValues[i]);
+
+        }
+
+        return(freqValues);
+
     }
-    
-    /**Generates a random string. 
+
+    /**Creates a List with different freq values
+     *
+     */
+    public static Double[] createBrownianList() {
+
+        /*
+        double PUT_START = 100;
+        double GET_START = 10;
+        double REM_START = 10;
+        double SAVE_START = 10;
+        double LIST_START = 10;
+         */
+
+        Double[] freqValues = new Double[5];
+        freqValues[0]=PUT_START;
+        freqValues[1]=GET_START;
+        freqValues[2]=REM_START;
+        freqValues[3]=SAVE_START;
+        freqValues[4]=LIST_START;
+
+        return(freqValues);
+
+    }
+
+    /**Returns an int between range of number of instructions less 1
+     *
+     */
+    public static int getTopInstruction(Double[] freqValues) {
+
+        int i;
+
+        Random random = new Random();
+
+        double max = 0;
+
+        double temp;
+
+        int max_index = 0;
+
+
+        Instruction[] INSTS = Instruction.values();
+
+        for (i = 0; i < INSTS.length-1; i++) {
+
+            temp = Math.abs(freqValues[i] * random.nextDouble());
+
+            if (temp > max) {
+
+                max_index = i;
+                max = temp;
+
+            }
+
+        }
+
+        return(max_index);
+
+    }
+
+
+    /**Returns any instruction except for masterpassword
+     * Generates based on array of random walks
+     */
+    public static Instruction getRandomBrownianInstruction(Double[] freqValues) {
+
+        Instruction[] INSTS = Instruction.values();
+        int index = getTopInstruction(freqValues);
+
+        //System.out.println("Returned the index of: "+index);
+        //System.out.println("Corresponding to: "+INSTS[index]);
+
+        return INSTS[index];
+
+    }
+
+
+
+    /**Generates a random string.
      * Sourced from: https://www.mkyong.com/java/java-how-to-generate-a-random-string/
      * and modified*/
     public static String generateRandomString(int maxlength) {
@@ -121,22 +341,22 @@ public class Fuzzer {
         Random random = new Random();
         int minLength = 1;
         int length;
-        
+
         //make a 1/4 chance of picking the max length and a 1/4 chance of picking the min length
         int chance = random.nextInt(4);
         if(chance == 1) {
-        	length = maxlength;
+            length = maxlength;
         }else if(chance == 2) {
-        	length = minLength;
+            length = minLength;
         }else {
-        	length = random.nextInt(maxlength)+1;
+            length = random.nextInt(maxlength)+1;
         }
-        
+
 
         StringBuilder sb = new StringBuilder(length);
         for (int i = 0; i < length; i++) {
 
-			// 0-62 (exclusive), random returns 0-61
+            // 0-62 (exclusive), random returns 0-61
             int rndCharAt = random.nextInt(DATA_FOR_RANDOM_STRING.length());
             char rndChar = DATA_FOR_RANDOM_STRING.charAt(rndCharAt);
 
@@ -147,26 +367,26 @@ public class Fuzzer {
         return sb.toString();
 
     }
-    
+
     /**Checks whether the input has already been generated*/
     public static boolean inputAlreadyGenerated(String newInput, ArrayList<String> inputs) {
-    	for(String input:inputs) {
-    		if(input.equals(newInput)) {
-    			return true;
-    		}
-    	}
-    	
-    	return false;
+        for(String input:inputs) {
+            if(input.equals(newInput)) {
+                return true;
+            }
+        }
+
+        return false;
     }
-    
+
     /**Selects a random saved URL*/
     public static String getRandomSavedURL(){
-    	if(savedURLs.size()>0) {
-	    	int index = new Random().nextInt(savedURLs.size());
-	    	return savedURLs.get(index);
-    	}else {
-    		return generateRandomString(MAX_URL_LENGTH);
-    	}
+        if(savedURLs.size()>0) {
+            int index = new Random().nextInt(savedURLs.size());
+            return savedURLs.get(index);
+        }else {
+            return generateRandomString(MAX_URL_LENGTH);
+        }
     }
 
 }
-- 
GitLab