/** * TLS-Attacker - A Modular Penetration Testing Framework for TLS * * Copyright 2014-2016 Ruhr University Bochum / Hackmanit GmbH * * Licensed under Apache License 2.0 * http://www.apache.org/licenses/LICENSE-2.0 */ package de.rub.nds.tlsattacker.modifiablevariable.bytearray; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.List; import java.util.Random; import de.rub.nds.tlsattacker.modifiablevariable.FileConfigurationException; import de.rub.nds.tlsattacker.modifiablevariable.VariableModification; import de.rub.nds.tlsattacker.util.ArrayConverter; import de.rub.nds.tlsattacker.util.RandomHelper; final public class ByteArrayModificationFactory { private static final int BYTE_ARRAY_SHUFFLE_MODIFICATION = 6; private static final int BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION_FROM_FILE = 5; private static final int BYTE_ARRAY_DUPLICATE_MODIFICATION = 4; private static final int BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION = 3; private static final int BYTE_ARRAY_DELETE_MODIFICATION = 2; private static final int BYTE_ARRAY_INSERT_MODIFICATION = 1; private static final int BYTE_ARRAY_XOR_MODIFICATION = 0; private static final int MODIFICATION_COUNT = 7; private static final int MAX_CONFIG_PARAMETER = 200; private static final int EXPLICIT_VALUE_RANDOM = 1000; private static final int MODIFIED_ARRAY_LENGTH_ESTIMATION = 50; private static List<VariableModification<byte[]>> modificationsFromFile; public static final String FILE_NAME = "array.vec"; private ByteArrayModificationFactory() { } /** * * * * @param xor * bytes to xor * @param startPosition * , negative numbers mean that the position is taken from the * end * @return */ public static VariableModification<byte[]> xor(final byte[] xor, final int startPosition) { return new ByteArrayXorModification(xor, startPosition); } /** * * * * @param bytesToInsert * bytes to xor * @param startPosition * , negative numbers mean that the position is taken from the * end * @return */ public static VariableModification<byte[]> insert(final byte[] bytesToInsert, final int startPosition) { return new ByteArrayInsertModification(bytesToInsert, startPosition); } /** * * Deletes $count bytes from the input array beginning at $startPosition * * @param startPosition * , negative numbers mean that the position is taken from the * end * @param count * @return */ public static VariableModification<byte[]> delete(final int startPosition, final int count) { return new ByteArrayDeleteModification(startPosition, count); } /** * Duplicates the byte array * * @return */ public static VariableModification<byte[]> duplicate() { return new ByteArrayDuplicateModification(); } public static VariableModification<byte[]> explicitValue(final byte[] explicitValue) { return new ByteArrayExplicitValueModification(explicitValue); } public static VariableModification<byte[]> explicitValueFromFile(int value) { List<VariableModification<byte[]>> modifications = modificationsFromFile(); int pos = value % modifications.size(); return modifications.get(pos); } /** * Shuffles the bytes in the array, given a specified array of positions. * * @param shuffle * @return */ public static VariableModification<byte[]> shuffle(final byte[] shuffle) { return new ByteArrayShuffleModification(shuffle); } public static synchronized List<VariableModification<byte[]>> modificationsFromFile() { try { if (modificationsFromFile == null) { modificationsFromFile = new LinkedList<>(); ClassLoader classLoader = ByteArrayModificationFactory.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream(FILE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { line = line.replaceAll("\\s+",""); byte[] value = ArrayConverter.hexStringToByteArray(line); modificationsFromFile.add(explicitValue(value)); } } return modificationsFromFile; } catch (IOException ex) { throw new FileConfigurationException("Modifiable variable file name could not have been found.", ex); } } public static VariableModification<byte[]> createRandomModification(byte[] originalValue) { Random random = RandomHelper.getRandom(); int r = random.nextInt(MODIFICATION_COUNT); VariableModification<byte[]> vm = null; int modifiedArrayLength; if (originalValue == null) { modifiedArrayLength = MODIFIED_ARRAY_LENGTH_ESTIMATION; } else { modifiedArrayLength = originalValue.length; if (originalValue.length == 0 || originalValue.length == 1) { r = BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION; } } switch (r) { case BYTE_ARRAY_XOR_MODIFICATION: int modificationArrayLength = random.nextInt(modifiedArrayLength); byte[] xor = new byte[modificationArrayLength]; random.nextBytes(xor); int startPosition = random.nextInt(modifiedArrayLength - modificationArrayLength); vm = new ByteArrayXorModification(xor, startPosition); return vm; case BYTE_ARRAY_INSERT_MODIFICATION: modificationArrayLength = random.nextInt(MAX_CONFIG_PARAMETER); byte[] bytesToInsert = new byte[modificationArrayLength]; random.nextBytes(bytesToInsert); int insertPosition = random.nextInt(modifiedArrayLength); vm = new ByteArrayInsertModification(bytesToInsert, insertPosition); return vm; case BYTE_ARRAY_DELETE_MODIFICATION: startPosition = random.nextInt(modifiedArrayLength - 1); int count = random.nextInt(modifiedArrayLength - startPosition); count++; vm = new ByteArrayDeleteModification(startPosition, count); return vm; case BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION: modificationArrayLength = random.nextInt(MAX_CONFIG_PARAMETER); byte[] explicitValue = new byte[modificationArrayLength]; random.nextBytes(explicitValue); vm = new ByteArrayExplicitValueModification(explicitValue); return vm; case BYTE_ARRAY_DUPLICATE_MODIFICATION: vm = new ByteArrayDuplicateModification(); return vm; case BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION_FROM_FILE: vm = explicitValueFromFile(random.nextInt(EXPLICIT_VALUE_RANDOM)); return vm; case BYTE_ARRAY_SHUFFLE_MODIFICATION: int shuffleSize = random.nextInt(MAX_CONFIG_PARAMETER); byte[] shuffle = new byte[shuffleSize]; random.nextBytes(shuffle); vm = shuffle(shuffle); return vm; } return vm; } }