@本文原创,转载请注明
0X00: 序言
fuzz测试作为安全测试的一个基本策略,被越来越多的引入整个测试过程,来避免一些简单的可能引发的安全问题. 如何将fuzzing测试引入软件自动化测试过程是本文将要阐述的主题。
0X01: 测试流程
使用JBroFuzz API来根据需求生成需要的测试数据, 这些数据来源与FuzzDB
然后将FuzzDB基于需要注入TestNG的DataProvider, 接口测试用例就可以调用DataProvider
0X02: JBroFuzz API
需要使用到的jar包
一个简单的例子:根据fuzz_id获取到注入数据
f_id:是需要使用到的fuzz类型的编号
f_len: fuzz数据的长度
public void fuzzDbZone(String f_ID,int f_len){ // You have to construct an instance of the fuzzers database Database fuzzDB = new Database(); try { Fuzzer f = fuzzDB.createFuzzer(f_ID, f_len); while(f.hasNext()) { f.next(); System.out.println(" The maximum value is: " + f.getMaximumValue()); System.out.println(" The current value is: " + f.getCurrentValue()); } } catch (NoSuchFuzzerException e) { System.out.println("Could not find fuzzer " + e.getMessage()); } }
查看所有fuzz的序列号和类型:
public void fuzzDbList() { Database fuzzDB = new Database(); // Get a list of all the fuzzer IDs from the database String[] fuzzer_IDs = fuzzDB.getAllPrototypeIDs(); System.out.println("The fuzzer IDs found are:"); for(String fuzzerID : fuzzer_IDs) { System.out.println("The fuzzer ID is: " + fuzzerID); // We pass of length of 1, irrelevant if we are // just going to access the first payload // of the fuzzer Fuzzer fuzzer; try { fuzzer = fuzzDB.createFuzzer(fuzzerID, 1); // Normally you should check for fuzzer.hasNext() String payload = fuzzer.next(); System.out.println("\tThe name of the fuzzer is:\t\t\t" + fuzzer.getName() ); System.out.println("\tThe id of the fuzzer is:\t\t\t" + fuzzer.getId() ); System.out.println("\tThe of payloads it carries (it's alphabet) is:\t" + fuzzDB.getSize(fuzzerID)); System.out.println("\tIt has as 1st payload:\n\t\t" + payload ); } catch (NoSuchFuzzerException e) { System.out.println("Could not find the specified fuzzer!"); System.out.println("Going to print all the fuzzer IDs I know:"); // old vs new for loop :) // in case of an error, print just the // fuzzer IDs, accessed from the DB for(int j = 0; j < fuzzer_IDs.length; j++) { System.out.println("The fuzzer ID is: " + fuzzer_IDs[j]); } } } }
使用powerFuzzAPI来进行数据组合测试,根据power的值大小来输出多少个值
我当前是输出一个ArrayList<ArrayList<String>>
public ArrayList<ArrayList<String>> powerFuzzer (String f_ID,int f_len,int power) throws NoSuchFuzzerException { Database fuzzDB = new Database(); ArrayList<ArrayList<String>> listArray = new ArrayList<ArrayList<String>>(); for(PowerFuzzer f = fuzzDB.createPowerFuzzer(f_ID, f_len, power); f.hasNext();) { String[] identicalElements = f.nextPower(); ArrayList<String> myList = Lists.newArrayList(identicalElements); listArray.add(myList); } return listArray; }
结果类似这样:
.... I have 5 elements: 4817 4817 4817 4817 4817 I have 5 elements: 4818 4818 4818 4818 4818 I have 5 elements: 4819 4819 4819 4819 4819 I have 5 elements: 481a 481a 481a 481a 481a I have 5 elements: 481b 481b 481b 481b 481b I have 5 elements: 481c 481c 481c 481c 481c I have 5 elements: 481d 481d 481d 481d 481d I have 5 elements: 481e 481e 481e 481e 481e I have 5 elements: 481f 481f 481f 481f 481f I have 5 elements: 4820 4820 4820 4820 4820 I have 5 elements: 4821 4821 4821 4821 4821 I have 5 elements: 4822 4822 4822 4822 4822 I have 5 elements: 4823 4823 4823 4823 4823 I have 5 elements: 4824 4824 4824 4824 4824 I have 5 elements: 4825 4825 4825 4825 4825 I have 5 elements: 4826 4826 4826 4826 4826 ....
使用Using the Double Fuzzer API来生成2个数据组合
//初始化
public DoubleFuzzer createDoubleFuzzer(String id1, int length1, String id2, int length2) throws NoSuchFuzzerException {
注入的数据
String fuzzID1 = "031-B16-HEX"; String fuzzID2 = "031-B16-HEX"; int length1 = 4; int length2 = 2;
结果:
I have 2 elements: fefb fb I have 2 elements: fefc fc I have 2 elements: fefd fd I have 2 elements: fefe fe I have 2 elements: feff ff I have 2 elements: ff00 00 I have 2 elements: ff01 01 I have 2 elements: ff02 02 I have 2 elements: ff03 03
FuzzerCross.java和FuzzerBigInteger.java暂时不写了,与上面类似可以参考官方文档.
0X03: FuzzDB注入到testng dataprovider
直接上干货,这是一个对登陆接口的注入测试数据集
TestNG就不细讲了,dataprovder会想单元测试用例提供2个类型的数据,一个是Object[][],另一个是Iterator<Object[]>
@DataProvider(name = "UserLoginFuzzing") public static Object[][] UserLoginFuzzing() throws NoSuchFuzzerException{ FuzzDB fuzzdb = new FuzzDB(); ArrayList<String> fuzzDb = fuzzdb.fuzzDbFind("015-XSS-101", 24); //新建一个JSONObject JSONObject[] valueList = new JSONObject[fuzzDb.size()]; for(int i =0;i < fuzzDb.size(); i++){ valueList[i] = new JSONObject(); valueList[i].put("LoginName", "admin"); valueList[i].put("Password", fuzzDb.get(i)); valueList[i].put("URI", "/UserLogin"); } //将JSONObject[]转为Object[][] Object[][] obj = new Object[valueList.length][1]; for(int i=0;i<valueList.length;i++){ obj[i][0]=valueList[i]; } return obj; }
0X04 参考文档
https://www.owasp.org/index.php/OWASP_JBroFuzz_Tutorial#How_to_Use_JBroFuzz_as_a_Fuzzing_Library