/**
* 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.fuzzer.impl;
import com.beust.jcommander.JCommander;
import de.rub.nds.tlsattacker.fuzzer.config.SimpleFuzzerConfig;
import de.rub.nds.tlsattacker.fuzzer.config.MultiFuzzerConfig;
import de.rub.nds.tlsattacker.fuzzer.config.StartupCommand;
import de.rub.nds.tlsattacker.fuzzer.config.StartupCommandsHolder;
import de.rub.nds.tlsattacker.tls.config.GeneralConfig;
import de.rub.nds.tlsattacker.tls.exceptions.ConfigurationException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
*
* @author Juraj Somorovsky - juraj.somorovsky@rub.de
*/
public class MultiFuzzer extends Fuzzer {
public static Logger LOGGER = LogManager.getLogger(MultiFuzzer.class);
private final MultiFuzzerConfig fuzzerConfig;
public MultiFuzzer(MultiFuzzerConfig config, GeneralConfig generalConfig) {
super(generalConfig);
this.fuzzerConfig = config;
}
@Override
public void startFuzzer() {
String file = fuzzerConfig.getStartupCommandFile();
try {
StartupCommandsHolder holder = unmarshalStartupCommands(file);
int port = holder.getServerPort();
String types = holder.getModifiedVariableTypes();
for (StartupCommand command : holder.getStartupCommands()) {
String fullServerCommand = null;
if (holder.getServerCommand() != null && !holder.getServerCommand().isEmpty()) {
fullServerCommand = holder.getServerCommand() + " " + command.getServerCommandParameters();
fullServerCommand = fullServerCommand.replace("$PORT", Integer.toString(port));
}
String fuzzerCommand = command.getFuzzerCommand().replace("$PORT", Integer.toString(port));
if (types != null && !types.isEmpty()) {
fuzzerCommand = fuzzerCommand + " -modified_variable_types " + types;
}
if (holder.getOutputFolder() != null && !holder.getOutputFolder().isEmpty()) {
fuzzerCommand = fuzzerCommand + " -output_folder " + holder.getOutputFolder();
}
if (holder.getWorkflowFolder() != null && !holder.getWorkflowFolder().isEmpty()) {
fuzzerCommand = fuzzerCommand + " -workflow_folder " + holder.getWorkflowFolder();
}
LOGGER.info("Starting new fuzzer with the following parameters");
LOGGER.info(" Name: {}", command.getShortName());
LOGGER.info(" Server command: {}", fullServerCommand);
LOGGER.info(" Fuzzer config: {}", fuzzerCommand);
command.setFuzzerCommand(fuzzerCommand);
SimpleFuzzerConfig simpleConfig = parseSimpleFuzzerConfig(command);
simpleConfig.setServerCommand(fullServerCommand);
SimpleFuzzer fuzzer = new SimpleFuzzer(simpleConfig, generalConfig);
fuzzer.setFuzzingName(command.getShortName());
new FuzzerStarter(fuzzer, command.getShortName()).start();
port++;
}
} catch (FileNotFoundException | JAXBException | XMLStreamException ex) {
throw new ConfigurationException("Unmarshaling failed", ex);
}
}
/**
* Parses the simple fuzzer configuration, typically used from the main
* class.
*
* @param command
* @return
*/
private SimpleFuzzerConfig parseSimpleFuzzerConfig(StartupCommand command) {
JCommander jc = new JCommander();
SimpleFuzzerConfig simpleConfig = new SimpleFuzzerConfig();
jc.addCommand(SimpleFuzzerConfig.ATTACK_COMMAND, simpleConfig);
jc.parse(command.getFuzzerCommand().split(" "));
return simpleConfig;
}
/**
* Unmarshals the startup commands (for server and fuzzer) from an XML file
*
* @param file
* @return
* @throws JAXBException
* @throws FileNotFoundException
*/
private StartupCommandsHolder unmarshalStartupCommands(String file) throws JAXBException, FileNotFoundException,
XMLStreamException {
JAXBContext context = JAXBContext.newInstance(StartupCommandsHolder.class);
Unmarshaller um = context.createUnmarshaller();
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream(file));
return (StartupCommandsHolder) um.unmarshal(xsr);
}
class FuzzerStarter extends Thread {
private final SimpleFuzzer fuzzer;
public FuzzerStarter(SimpleFuzzer fuzzer, String name) {
super(name);
this.fuzzer = fuzzer;
}
@Override
public void run() {
fuzzer.startFuzzer();
}
}
}