diff --git a/fuzzer/Fuzzer.java b/fuzzer/Fuzzer.java index 9394bf8fd81a260984d87d9fe1aa3f3ef35fd4de..7ee264b0c8ec7aaab92aca83dc3e2efc5d15015e 100644 --- a/fuzzer/Fuzzer.java +++ b/fuzzer/Fuzzer.java @@ -1,17 +1,31 @@ import java.io.IOException; import java.io.FileOutputStream; import java.io.PrintWriter; - +import java.util.ArrayList; +import java.util.Random; /* a stub for your team's fuzzer */ 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 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 + public static void main(String[] args) throws IOException { 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); @@ -19,7 +33,20 @@ public class Fuzzer { /* We just print one instruction. Hint: you might want to make use of the instruction grammar which is effectively encoded in Instruction.java */ - pw.println("list"); + + /**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); + } + } }catch (Exception e){ e.printStackTrace(System.err); @@ -34,5 +61,112 @@ public class Fuzzer { } } + + /**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; + } + + /**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]; + } + + /**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) { + if (maxlength < 1) throw new IllegalArgumentException(); + 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; + }else if(chance == 2) { + length = minLength; + }else { + length = random.nextInt(maxlength)+1; + } + + + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i++) { + + // 0-62 (exclusive), random returns 0-61 + int rndCharAt = random.nextInt(DATA_FOR_RANDOM_STRING.length()); + char rndChar = DATA_FOR_RANDOM_STRING.charAt(rndCharAt); + + sb.append(rndChar); + + } + + 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; + } + + /**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); + } + } }