Skip to content

Commit 2b540ac

Browse files
authored
Merge pull request #556 from RUB-NDS/starttlsofthefuture
Starttls Improvements & Attribution
2 parents 61cd0e9 + 27ae23f commit 2b540ac

File tree

64 files changed

+618
-257
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+618
-257
lines changed

Attacks/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>de.rub.nds.tlsattacker</groupId>
66
<artifactId>TLS-Attacker</artifactId>
7-
<version>2.8</version>
7+
<version>2.9</version>
88
</parent>
99
<artifactId>Attacks</artifactId>
1010
<packaging>jar</packaging>

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/actions/EarlyCcsAction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public EarlyCcsAction(Boolean targetsOpenssl1_0_0) {
6262
* ClientKeyExchange message
6363
*/
6464
@Override
65-
public void execute(State state) throws IOException {
65+
public void execute(State state) {
6666
WorkflowConfigurationFactory factory = new WorkflowConfigurationFactory(state.getConfig());
6767
ClientKeyExchangeMessage message = factory.createClientKeyExchangeMessage(AlgorithmResolver
6868
.getKeyExchangeAlgorithm(state.getTlsContext().getChooser().getSelectedCipherSuite()));
@@ -86,7 +86,7 @@ public void execute(State state) throws IOException {
8686
try {
8787
state.getTlsContext().getTransportHandler().sendData(prepareRecords);
8888
executedAsPlanned = true;
89-
} catch (SocketException E) {
89+
} catch (IOException E) {
9090
LOGGER.debug("Could not write Data to stream", E);
9191
executedAsPlanned = false;
9292
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/config/BleichenbacherCommandConfig.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.beust.jcommander.Parameter;
1212
import com.beust.jcommander.ParametersDelegate;
1313
import de.rub.nds.tlsattacker.attacks.config.delegate.AttackDelegate;
14+
import de.rub.nds.tlsattacker.attacks.pkcs1.BleichenbacherWorkflowType;
1415
import de.rub.nds.tlsattacker.core.config.Config;
1516
import de.rub.nds.tlsattacker.core.config.delegate.CiphersuiteDelegate;
1617
import de.rub.nds.tlsattacker.core.config.delegate.ClientDelegate;
@@ -57,6 +58,11 @@ public class BleichenbacherCommandConfig extends AttackConfig {
5758
@ParametersDelegate
5859
private StarttlsDelegate starttlsDelegate;
5960

61+
@Parameter(names = "-workflowType", description = "Which workflow traces should be tested with")
62+
private BleichenbacherWorkflowType workflowType = BleichenbacherWorkflowType.CKE_CCS_FIN;
63+
64+
;
65+
6066
/**
6167
*
6268
* @param delegate
@@ -157,11 +163,17 @@ public enum Type {
157163
*
158164
*/
159165
FULL,
160-
161166
/**
162167
*
163168
*/
164169
FAST
165170
}
166171

172+
public BleichenbacherWorkflowType getWorkflowType() {
173+
return workflowType;
174+
}
175+
176+
public void setWorkflowType(BleichenbacherWorkflowType workflowType) {
177+
this.workflowType = workflowType;
178+
}
167179
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/config/DrownCommandConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import de.rub.nds.tlsattacker.core.config.Config;
1313
import de.rub.nds.tlsattacker.core.config.delegate.ClientDelegate;
1414
import de.rub.nds.tlsattacker.core.config.delegate.GeneralDelegate;
15+
import de.rub.nds.tlsattacker.core.config.delegate.StarttlsDelegate;
1516
import de.rub.nds.tlsattacker.core.constants.ProtocolVersion;
1617
import de.rub.nds.tlsattacker.core.record.layer.RecordLayerType;
1718

@@ -28,14 +29,19 @@ public class DrownCommandConfig extends AttackConfig {
2829
@ParametersDelegate
2930
private ClientDelegate clientDelegate;
3031

32+
@ParametersDelegate
33+
private StarttlsDelegate starttlsDelegate;
34+
3135
/**
3236
*
3337
* @param delegate
3438
*/
3539
public DrownCommandConfig(GeneralDelegate delegate) {
3640
super(delegate);
3741
clientDelegate = new ClientDelegate();
42+
starttlsDelegate = new StarttlsDelegate();
3843
addDelegate(clientDelegate);
44+
addDelegate(starttlsDelegate);
3945
}
4046

4147
/**

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/config/EarlyCCSCommandConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import de.rub.nds.tlsattacker.core.config.delegate.GeneralDelegate;
1616
import de.rub.nds.tlsattacker.core.config.delegate.HostnameExtensionDelegate;
1717
import de.rub.nds.tlsattacker.core.config.delegate.ProtocolVersionDelegate;
18+
import de.rub.nds.tlsattacker.core.config.delegate.StarttlsDelegate;
1819
import de.rub.nds.tlsattacker.core.constants.AlgorithmResolver;
1920
import de.rub.nds.tlsattacker.core.constants.CipherSuite;
2021
import de.rub.nds.tlsattacker.core.constants.KeyExchangeAlgorithm;
@@ -37,6 +38,8 @@ public class EarlyCCSCommandConfig extends AttackConfig {
3738
private CiphersuiteDelegate ciphersuiteDelegate;
3839
@ParametersDelegate
3940
private ProtocolVersionDelegate protocolVersionDelegate;
41+
@ParametersDelegate
42+
private StarttlsDelegate starttlsDelegate;
4043

4144
/**
4245
*
@@ -48,10 +51,12 @@ public EarlyCCSCommandConfig(GeneralDelegate delegate) {
4851
hostnameExtensionDelegate = new HostnameExtensionDelegate();
4952
ciphersuiteDelegate = new CiphersuiteDelegate();
5053
protocolVersionDelegate = new ProtocolVersionDelegate();
54+
starttlsDelegate = new StarttlsDelegate();
5155
addDelegate(clientDelegate);
5256
addDelegate(hostnameExtensionDelegate);
5357
addDelegate(ciphersuiteDelegate);
5458
addDelegate(protocolVersionDelegate);
59+
addDelegate(starttlsDelegate);
5560
}
5661

5762
/**

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/config/PaddingOracleCommandConfig.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@ public class PaddingOracleCommandConfig extends AttackConfig {
5353
@ParametersDelegate
5454
private StarttlsDelegate starttlsDelegate;
5555

56+
/**
57+
* How many rescans should be done to confirm vulnerabilities
58+
*/
59+
private int mapListDepth = 3;
60+
61+
/**
62+
* When a false positive or shaky scan orrcurs stop the evaluation
63+
*/
64+
private boolean rescanNotVulnerable = true;
65+
66+
/**
67+
* Do not rescan servers which appear not vulnerable on first try
68+
*/
69+
private boolean abortRescansOnFailure = true;
70+
5671
/**
5772
*
5873
* @param delegate
@@ -159,4 +174,29 @@ public Config createConfig(Config config) {
159174

160175
return config;
161176
}
177+
178+
public int getMapListDepth() {
179+
return mapListDepth;
180+
}
181+
182+
public void setMapListDepth(int mapListDepth) {
183+
this.mapListDepth = mapListDepth;
184+
}
185+
186+
public boolean isAbortRescansOnFailure() {
187+
return rescanNotVulnerable;
188+
}
189+
190+
public void setAbortRescansOnFailure(boolean abortRescansOnFailure) {
191+
this.rescanNotVulnerable = abortRescansOnFailure;
192+
}
193+
194+
public boolean isRescanNotVulnerable() {
195+
return rescanNotVulnerable;
196+
}
197+
198+
public void setRescanNotVulnerable(boolean rescanNotVulnerable) {
199+
this.rescanNotVulnerable = rescanNotVulnerable;
200+
}
201+
162202
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/connectivity/ConnectivityChecker.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,29 @@
99
package de.rub.nds.tlsattacker.attacks.connectivity;
1010

1111
import de.rub.nds.tlsattacker.core.config.Config;
12-
import de.rub.nds.tlsattacker.core.protocol.message.ClientHelloMessage;
12+
import de.rub.nds.tlsattacker.core.constants.RunningModeType;
1313
import de.rub.nds.tlsattacker.core.protocol.message.ProtocolMessage;
1414
import de.rub.nds.tlsattacker.core.protocol.message.SSL2ServerHelloMessage;
1515
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloDoneMessage;
1616
import de.rub.nds.tlsattacker.core.protocol.message.ServerHelloMessage;
17-
import de.rub.nds.tlsattacker.core.record.AbstractRecord;
1817
import de.rub.nds.tlsattacker.core.record.Record;
1918
import de.rub.nds.tlsattacker.core.state.State;
2019
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor;
2120
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutorFactory;
2221
import de.rub.nds.tlsattacker.core.workflow.WorkflowTrace;
23-
import de.rub.nds.tlsattacker.core.workflow.action.ReceiveAction;
22+
import de.rub.nds.tlsattacker.core.workflow.action.AsciiAction;
2423
import de.rub.nds.tlsattacker.core.workflow.action.ReceiveTillAction;
25-
import de.rub.nds.tlsattacker.core.workflow.action.SendAction;
24+
import de.rub.nds.tlsattacker.core.workflow.action.SendAsciiAction;
25+
import de.rub.nds.tlsattacker.core.workflow.action.TlsAction;
2626
import de.rub.nds.tlsattacker.core.workflow.action.executor.WorkflowExecutorType;
27+
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowConfigurationFactory;
28+
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowTraceType;
2729
import de.rub.nds.tlsattacker.transport.Connection;
2830
import de.rub.nds.tlsattacker.transport.TransportHandler;
2931
import de.rub.nds.tlsattacker.transport.TransportHandlerFactory;
3032
import de.rub.nds.tlsattacker.transport.TransportHandlerType;
3133
import java.io.IOException;
34+
import java.util.Objects;
3235
import org.apache.logging.log4j.LogManager;
3336
import org.apache.logging.log4j.Logger;
3437

@@ -80,9 +83,9 @@ public boolean isConnectable() {
8083
}
8184

8285
public boolean speaksTls(Config config) {
83-
config.setHttpsParsingEnabled(Boolean.TRUE);
84-
WorkflowTrace trace = new WorkflowTrace();
85-
trace.addTlsAction(new SendAction(new ClientHelloMessage(config)));
86+
WorkflowConfigurationFactory factory = new WorkflowConfigurationFactory(config);
87+
WorkflowTrace trace = factory.createWorkflowTrace(WorkflowTraceType.HELLO, RunningModeType.CLIENT);
88+
trace.removeTlsAction(trace.getTlsActions().size() - 1);
8689
ReceiveTillAction receiveTillAction = new ReceiveTillAction(new ServerHelloDoneMessage());
8790
trace.addTlsAction(receiveTillAction);
8891
State state = new State(config, trace);
@@ -104,4 +107,25 @@ public boolean speaksTls(Config config) {
104107
return false;
105108
}
106109
}
110+
111+
public boolean speaksStartTls(Config config) {
112+
WorkflowConfigurationFactory factory = new WorkflowConfigurationFactory(config);
113+
WorkflowTrace trace = factory.createTlsEntryWorkflowtrace(config.getDefaultClientConnection());
114+
State state = new State(config, trace);
115+
WorkflowExecutor executor = WorkflowExecutorFactory.createWorkflowExecutor(WorkflowExecutorType.DEFAULT, state);
116+
executor.executeWorkflow();
117+
if (trace.allActionsExecuted()) {
118+
for (TlsAction action : trace.getTlsActions()) {
119+
if (action instanceof AsciiAction || !(action instanceof SendAsciiAction)) {
120+
AsciiAction asciiAction = (AsciiAction) action;
121+
if (asciiAction.getAsciiText() != null) {
122+
if (asciiAction.getAsciiText().toLowerCase().contains("TLS negotiation".toLowerCase())) {
123+
return true;
124+
}
125+
}
126+
}
127+
}
128+
}
129+
return false;
130+
}
107131
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/impl/BleichenbacherAttacker.java

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ public class BleichenbacherAttacker extends Attacker<BleichenbacherCommandConfig
5050

5151
private static final Logger LOGGER = LogManager.getLogger();
5252

53-
private Config tlsConfig;
54-
5553
private BleichenbacherWorkflowType vulnerableType;
5654

5755
private EqualityError errorType;
@@ -70,7 +68,6 @@ public class BleichenbacherAttacker extends Attacker<BleichenbacherCommandConfig
7068
public BleichenbacherAttacker(BleichenbacherCommandConfig bleichenbacherConfig, Config baseConfig) {
7169
super(bleichenbacherConfig, baseConfig);
7270
executor = new ParallelExecutor(1, 3);
73-
this.tlsConfig = getTlsConfig();
7471
}
7572

7673
/**
@@ -83,7 +80,6 @@ public BleichenbacherAttacker(BleichenbacherCommandConfig bleichenbacherConfig,
8380
ParallelExecutor executor) {
8481
super(bleichenbacherConfig, baseConfig);
8582
this.executor = executor;
86-
this.tlsConfig = getTlsConfig();
8783
}
8884

8985
/**
@@ -93,6 +89,7 @@ public BleichenbacherAttacker(BleichenbacherCommandConfig bleichenbacherConfig,
9389
* @return
9490
*/
9591
public State executeTlsFlow(BleichenbacherWorkflowType type, byte[] encryptedPMS) {
92+
Config tlsConfig = getTlsConfig();
9693
WorkflowTrace trace = BleichenbacherWorkflowGenerator.generateWorkflow(tlsConfig, type, encryptedPMS);
9794
State state = new State(tlsConfig, trace);
9895
tlsConfig.setWorkflowExecutorShouldClose(false);
@@ -108,35 +105,35 @@ public State executeTlsFlow(BleichenbacherWorkflowType type, byte[] encryptedPMS
108105
*/
109106
@Override
110107
public Boolean isVulnerable() {
111-
tlsConfig = getTlsConfig();
108+
errorType = getEqualityError();
109+
if (errorType != EqualityError.NONE) {
110+
vulnerableType = config.getWorkflowType();
111+
return true;
112+
}
113+
return false;
114+
}
115+
116+
public EqualityError getEqualityError() {
117+
Config tlsConfig = getTlsConfig();
112118
RSAPublicKey publicKey = (RSAPublicKey) CertificateFetcher.fetchServerPublicKey(tlsConfig);
113119
if (publicKey == null) {
114120
LOGGER.info("Could not retrieve PublicKey from Server - is the Server running?");
115121
return null;
116122
}
117123
LOGGER.info("Fetched the following server public key: " + publicKey);
118-
119124
List<Pkcs1Vector> pkcs1Vectors = Pkcs1VectorGenerator.generatePkcs1Vectors(publicKey, config.getType(),
120125
tlsConfig.getDefaultHighestClientProtocolVersion());
121-
122126
// we execute the attack with different protocol flows and
123127
// return true as soon as we find the first inconsistency
124128
CONSOLE.info("A server is considered vulnerable to this attack if it responds differently to the test vectors.");
125129
CONSOLE.info("A server is considered secure if it always responds the same way.");
126-
for (BleichenbacherWorkflowType bbWorkflowType : BleichenbacherWorkflowType.values()) {
127-
LOGGER.debug("Testing: " + bbWorkflowType);
128-
errorType = isVulnerable(bbWorkflowType, pkcs1Vectors);
129-
if (errorType != EqualityError.NONE) {
130-
vulnerableType = bbWorkflowType;
131-
return true;
132-
133-
}
134-
}
135-
return false;
130+
LOGGER.debug("Testing: " + config.getWorkflowType());
131+
errorType = isVulnerable(pkcs1Vectors);
132+
return errorType;
136133
}
137134

138-
public EqualityError isVulnerable(BleichenbacherWorkflowType bbWorkflowType, List<Pkcs1Vector> pkcs1Vectors) {
139-
fingerprintPairList = getBleichenbacherMap(bbWorkflowType, pkcs1Vectors);
135+
public EqualityError isVulnerable(List<Pkcs1Vector> pkcs1Vectors) {
136+
fingerprintPairList = getBleichenbacherMap(config.getWorkflowType(), pkcs1Vectors);
140137
if (fingerprintPairList.isEmpty()) {
141138
LOGGER.warn("Could not extract Fingerprints");
142139
return null;
@@ -148,15 +145,15 @@ public EqualityError isVulnerable(BleichenbacherWorkflowType bbWorkflowType, Lis
148145
// Socket Equality Errors can be caused by problems on on the
149146
// network. In this case we do a rescan
150147
// and check if we find the exact same answer behaviour (twice)
151-
List<VectorFingerprintPair> secondBleichenbacherVectorMap = getBleichenbacherMap(bbWorkflowType,
148+
List<VectorFingerprintPair> secondBleichenbacherVectorMap = getBleichenbacherMap(config.getWorkflowType(),
152149
pkcs1Vectors);
153150
EqualityError error2 = getEqualityError(secondBleichenbacherVectorMap);
154151
BleichenbacherVulnerabilityMap mapOne = new BleichenbacherVulnerabilityMap(fingerprintPairList, error);
155152
BleichenbacherVulnerabilityMap mapTwo = new BleichenbacherVulnerabilityMap(secondBleichenbacherVectorMap,
156153
error2);
157154
if (mapOne.looksIdentical(mapTwo)) {
158-
List<VectorFingerprintPair> thirdBleichenbacherVectorMap = getBleichenbacherMap(bbWorkflowType,
159-
pkcs1Vectors);
155+
List<VectorFingerprintPair> thirdBleichenbacherVectorMap = getBleichenbacherMap(
156+
config.getWorkflowType(), pkcs1Vectors);
160157
EqualityError error3 = getEqualityError(secondBleichenbacherVectorMap);
161158
BleichenbacherVulnerabilityMap mapThree = new BleichenbacherVulnerabilityMap(
162159
thirdBleichenbacherVectorMap, error3);
@@ -172,7 +169,7 @@ public EqualityError isVulnerable(BleichenbacherWorkflowType bbWorkflowType, Lis
172169
}
173170
}
174171
if (error != EqualityError.NONE) {
175-
CONSOLE.info("Found a vulnerability with " + bbWorkflowType.getDescription());
172+
CONSOLE.info("Found a vulnerability with " + config.getWorkflowType().getDescription());
176173
}
177174
return error;
178175
}
@@ -206,6 +203,7 @@ private void printBleichenbacherVectormap(List<VectorFingerprintPair> bleichenba
206203

207204
private List<VectorFingerprintPair> getBleichenbacherMap(BleichenbacherWorkflowType bbWorkflowType,
208205
List<Pkcs1Vector> pkcs1Vectors) {
206+
Config tlsConfig = getTlsConfig();
209207
List<VectorFingerprintPair> bleichenbacherVectorMap = new LinkedList<>();
210208
List<State> stateList = new LinkedList<>();
211209
List<StateVectorPair> stateVectorPairList = new LinkedList<>();
@@ -233,11 +231,11 @@ private List<VectorFingerprintPair> getBleichenbacherMap(BleichenbacherWorkflowT
233231

234232
private void processFinishedStateVectorPair(StateVectorPair stateVectorPair,
235233
List<VectorFingerprintPair> bleichenbacherVectorMap) {
236-
if (stateVectorPair.getState().getWorkflowTrace().allActionsExecuted()) {
234+
if (stateVectorPair.getState().getWorkflowTrace().executedAsPlanned()) {
237235
ResponseFingerprint fingerprint = ResponseExtractor.getFingerprint(stateVectorPair.getState());
238236
bleichenbacherVectorMap.add(new VectorFingerprintPair(fingerprint, stateVectorPair.getVector()));
239237
} else {
240-
LOGGER.warn("Could not execute Workflow. Something went wrong... Check the debug output for more information");
238+
LOGGER.error("Could not execute Workflow. Something went wrong... Check the debug output for more information");
241239
}
242240
clearConnections(stateVectorPair.getState());
243241

@@ -267,6 +265,7 @@ public void executeAttack() {
267265
LOGGER.warn("The server is not vulnerable to the Bleichenbacher attack");
268266
return;
269267
}
268+
Config tlsConfig = getTlsConfig();
270269
RSAPublicKey publicKey = (RSAPublicKey) CertificateFetcher.fetchServerPublicKey(tlsConfig);
271270
if (publicKey == null) {
272271
LOGGER.info("Could not retrieve PublicKey from Server - is the Server running?");

0 commit comments

Comments
 (0)