Skip to content

Commit a549afd

Browse files
authored
Merge pull request #543 from RUB-NDS/paddingrelease
Paddingrelease
2 parents fa188a6 + 7cc303f commit a549afd

File tree

17 files changed

+163
-40
lines changed

17 files changed

+163
-40
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* TLS-Attacker - A Modular Penetration Testing Framework for TLS
3+
*
4+
* Copyright 2014-2017 Ruhr University Bochum / Hackmanit GmbH
5+
*
6+
* Licensed under Apache License 2.0
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
package de.rub.nds.tlsattacker.attacks.exception;
10+
11+
/**
12+
*
13+
* @author ic0ns
14+
*/
15+
public class FingerprintExtractionException extends RuntimeException {
16+
17+
public FingerprintExtractionException() {
18+
}
19+
20+
public FingerprintExtractionException(String string) {
21+
super(string);
22+
}
23+
24+
public FingerprintExtractionException(String string, Throwable thrwbl) {
25+
super(string, thrwbl);
26+
}
27+
28+
public FingerprintExtractionException(Throwable thrwbl) {
29+
super(thrwbl);
30+
}
31+
32+
public FingerprintExtractionException(String string, Throwable thrwbl, boolean bln, boolean bln1) {
33+
super(string, thrwbl, bln, bln1);
34+
}
35+
36+
}

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

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ public class PaddingOracleAttacker extends Attacker<PaddingOracleCommandConfig>
4848

4949
private boolean groupRecords = true;
5050

51+
private boolean increasingTimeout = true;
52+
53+
private long additionalTimeout = 1000;
54+
5155
private List<VectorResponse> vectorResponseList;
5256
private List<VectorResponse> vectorResponseListTwo;
5357
private List<VectorResponse> vectorResponseListThree;
@@ -209,34 +213,33 @@ public List<VectorResponse> createVectorResponseList() {
209213
for (PaddingVector vector : vectorGenerator.getVectors(tlsConfig.getDefaultSelectedCipherSuite(),
210214
tlsConfig.getDefaultHighestClientProtocolVersion())) {
211215
State state = new State(tlsConfig, generator.getPaddingOracleWorkflowTrace(tlsConfig, vector));
212-
FingerPrintTask fingerPrintTask = new FingerPrintTask(state, 6);
216+
FingerPrintTask fingerPrintTask = new FingerPrintTask(state, additionalTimeout, increasingTimeout, 6);
213217
taskList.add(fingerPrintTask);
214218
stateVectorPairList.add(new FingerprintTaskVectorPair(fingerPrintTask, vector));
215219
}
216220
List<VectorResponse> tempResponseVectorList = new LinkedList<>();
217221
executor.bulkExecuteTasks(taskList);
218222
for (FingerprintTaskVectorPair pair : stateVectorPairList) {
219223
ResponseFingerprint fingerprint = null;
220-
if (pair.getFingerPrintTask().getState().getWorkflowTrace().allActionsExecuted()) {
224+
if (pair.getFingerPrintTask().isHasError()) {
225+
errornousScans = true;
226+
LOGGER.error("Could not extract fingerprint for " + pair.toString());
227+
VectorResponse vectorResponse = new VectorResponse(pair.getVector(), null, testedVersion, testedSuite,
228+
tlsConfig.getDefaultApplicationMessageData().getBytes().length);
229+
vectorResponse.setErrorDuringHandshake(true);
230+
tempResponseVectorList.add(vectorResponse);
231+
LOGGER.error("Could not execute whole workflow: " + testedSuite + " - " + testedVersion);
232+
233+
} else {
221234
testedSuite = pair.getFingerPrintTask().getState().getTlsContext().getSelectedCipherSuite();
222235
testedVersion = pair.getFingerPrintTask().getState().getTlsContext().getSelectedProtocolVersion();
223236
if (testedSuite == null || testedVersion == null) {
224-
// Did not receive ServerHello?!
225-
LOGGER.error("Could not find ServerHello" + testedSuite + " - " + testedVersion);
226-
errornousScans = true;
237+
LOGGER.fatal("Could not find ServerHello after successful extraction");
238+
throw new PaddingOracleUnstableException("Fatal Extraction error");
227239
}
228240
fingerprint = pair.getFingerPrintTask().getFingerprint();
229241
tempResponseVectorList.add(new VectorResponse(pair.getVector(), fingerprint, testedVersion,
230242
testedSuite, tlsConfig.getDefaultApplicationMessageData().getBytes().length));
231-
} else {
232-
233-
LOGGER.warn("Could not execute Workflow. Something went wrong... Check the debug output for more information");
234-
VectorResponse vectorResponse = new VectorResponse(pair.getVector(), null, testedVersion, testedSuite,
235-
tlsConfig.getDefaultApplicationMessageData().getBytes().length);
236-
vectorResponse.setErrorDuringHandshake(true);
237-
tempResponseVectorList.add(vectorResponse);
238-
LOGGER.error("Could not execute whole workflow" + testedSuite + " - " + testedVersion);
239-
errornousScans = true;
240243
}
241244
}
242245
return tempResponseVectorList;
@@ -336,4 +339,20 @@ public boolean isShakyScans() {
336339
public boolean isErrornousScans() {
337340
return errornousScans;
338341
}
342+
343+
public boolean isIncreasingTimeout() {
344+
return increasingTimeout;
345+
}
346+
347+
public void setIncreasingTimeout(boolean increasingTimeout) {
348+
this.increasingTimeout = increasingTimeout;
349+
}
350+
351+
public long getAdditionalTimeout() {
352+
return additionalTimeout;
353+
}
354+
355+
public void setAdditionalTimeout(long additionalTimeout) {
356+
this.additionalTimeout = additionalTimeout;
357+
}
339358
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/padding/vector/FingerprintTaskVectorPair.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,10 @@ public FingerPrintTask getFingerPrintTask() {
3131
public PaddingVector getVector() {
3232
return vector;
3333
}
34+
35+
@Override
36+
public String toString() {
37+
return "FingerprintTaskVectorPair{" + "fingerPrintTask=" + fingerPrintTask + ", vector=" + vector + '}';
38+
}
39+
3440
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/task/FingerPrintTask.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
*/
99
package de.rub.nds.tlsattacker.attacks.task;
1010

11-
import de.rub.nds.tlsattacker.attacks.exception.PaddingOracleUnstableException;
11+
import de.rub.nds.tlsattacker.attacks.exception.FingerprintExtractionException;
1212
import de.rub.nds.tlsattacker.attacks.util.response.ResponseExtractor;
1313
import de.rub.nds.tlsattacker.attacks.util.response.ResponseFingerprint;
14-
import de.rub.nds.tlsattacker.core.constants.ProtocolMessageType;
1514
import de.rub.nds.tlsattacker.core.state.State;
1615
import de.rub.nds.tlsattacker.core.workflow.DefaultWorkflowExecutor;
1716
import de.rub.nds.tlsattacker.core.workflow.WorkflowExecutor;
18-
import de.rub.nds.tlsattacker.core.workflow.WorkflowTraceUtil;
1917
import de.rub.nds.tlsattacker.core.workflow.task.TlsTask;
2018
import java.io.IOException;
2119
import org.apache.logging.log4j.LogManager;
@@ -25,7 +23,7 @@ public class FingerPrintTask extends TlsTask {
2523

2624
private static final Logger LOGGER = LogManager.getLogger();
2725

28-
private State state;
26+
private final State state;
2927

3028
private ResponseFingerprint fingerprint;
3129

@@ -34,15 +32,23 @@ public FingerPrintTask(State state, int reexecutions) {
3432
this.state = state;
3533
}
3634

35+
public FingerPrintTask(State state, long additionalTimeout, boolean increasingTimeout, int reexecutions) {
36+
super(reexecutions, additionalTimeout, increasingTimeout);
37+
this.state = state;
38+
}
39+
3740
@Override
3841
public void execute() {
3942
try {
4043
WorkflowExecutor executor = new DefaultWorkflowExecutor(state);
4144
executor.executeWorkflow();
45+
if (!state.getWorkflowTrace().executedAsPlanned()) {
46+
throw new FingerprintExtractionException("Could not extract fingerprint.");
47+
}
4248
fingerprint = ResponseExtractor.getFingerprint(state);
43-
if (fingerprint == null
44-
&& !WorkflowTraceUtil.didReceiveMessage(ProtocolMessageType.ALERT, state.getWorkflowTrace())) {
45-
throw new PaddingOracleUnstableException("Could not extract fingerprint, rescanning");
49+
50+
if (fingerprint == null) {
51+
throw new FingerprintExtractionException("Could not extract fingerprint.");
4652
}
4753
} finally {
4854
try {
@@ -60,4 +66,10 @@ public State getState() {
6066
public ResponseFingerprint getFingerprint() {
6167
return fingerprint;
6268
}
69+
70+
@Override
71+
public void reset() {
72+
state.reset();
73+
}
74+
6375
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/util/response/ResponseExtractor.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import de.rub.nds.tlsattacker.core.record.AbstractRecord;
1414
import de.rub.nds.tlsattacker.core.record.Record;
1515
import de.rub.nds.tlsattacker.core.state.State;
16-
import de.rub.nds.tlsattacker.core.state.TlsContext;
1716
import de.rub.nds.tlsattacker.core.workflow.action.ReceivingAction;
1817
import de.rub.nds.tlsattacker.transport.exception.InvalidTransportHandlerStateException;
1918
import de.rub.nds.tlsattacker.transport.socket.SocketState;
@@ -58,7 +57,6 @@ public static ResponseFingerprint getFingerprint(State state, ReceivingAction ac
5857
* @return
5958
*/
6059
public static ResponseFingerprint getFingerprint(State state) {
61-
TlsContext context = state.getTlsContext();
6260
ReceivingAction action = state.getWorkflowTrace().getLastReceivingAction();
6361
return getFingerprint(state, action);
6462
}

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/state/State.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ public State(Config config, WorkflowTrace workflowTrace) {
9191
initState();
9292
}
9393

94+
public void reset() {
95+
contextContainer.clear();
96+
workflowTrace.reset();
97+
initState();
98+
}
99+
94100
/**
95101
* Normalize trace and initialize TLS contexts.
96102
*/

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/workflow/task/StateExecutionTask.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,8 @@ public State getState() {
3434
return state;
3535
}
3636

37+
@Override
38+
public void reset() {
39+
state.reset();
40+
}
3741
}

TLS-Core/src/main/java/de/rub/nds/tlsattacker/core/workflow/task/TlsTask.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,22 @@ public abstract class TlsTask implements ITask, Callable<ITask> {
1818

1919
private boolean hasError = false;
2020

21-
private int reexecutions = 0;
21+
private final int reexecutions;
22+
23+
private final long additionalSleepTime;
24+
25+
private final boolean increasingSleepTimes;
2226

2327
public TlsTask(int reexecutions) {
2428
this.reexecutions = reexecutions;
29+
additionalSleepTime = 1000;
30+
increasingSleepTimes = true;
31+
}
32+
33+
public TlsTask(int reexecutions, long additionalSleepTime, boolean increasingSleepTimes) {
34+
this.reexecutions = reexecutions;
35+
this.additionalSleepTime = additionalSleepTime;
36+
this.increasingSleepTimes = increasingSleepTimes;
2537
}
2638

2739
@Override
@@ -39,7 +51,9 @@ public ITask call() {
3951
} catch (Exception E) {
4052
LOGGER.debug("Encountered an exception during the execution", E);
4153
hasError = true;
42-
sleepTime += 1000;
54+
if (increasingSleepTimes) {
55+
sleepTime += additionalSleepTime;
56+
}
4357
exception = E;
4458
}
4559
}
@@ -52,4 +66,6 @@ public ITask call() {
5266
public boolean isHasError() {
5367
return hasError;
5468
}
69+
70+
public abstract void reset();
5571
}

Transport/src/main/java/de/rub/nds/tlsattacker/transport/TransportHandler.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import java.io.IOException;
1313
import java.io.InputStream;
1414
import java.io.OutputStream;
15+
import java.io.PushbackInputStream;
16+
import java.net.SocketException;
17+
import java.net.SocketTimeoutException;
1518
import org.apache.logging.log4j.LogManager;
1619
import org.apache.logging.log4j.Logger;
1720

@@ -23,7 +26,7 @@ public abstract class TransportHandler {
2326

2427
protected OutputStream outStream;
2528

26-
protected InputStream inStream;
29+
protected PushbackInputStream inStream;
2730

2831
private boolean initialized = false;
2932

@@ -49,12 +52,22 @@ public byte[] fetchData() throws IOException {
4952
}
5053
} else {
5154
try {
52-
Thread.sleep(1);
53-
} catch (InterruptedException ex) {
54-
throw new RuntimeException("Got Interrupted while waiting for Data");
55+
// dont ask - the java api does not allow this otherwise...
56+
Thread.currentThread().sleep(1);
57+
int read = inStream.read();
58+
if (read == -1) {
59+
// TCP FIN
60+
return stream.toByteArray();
61+
}
62+
inStream.unread(read);
63+
64+
} catch (SocketException E) {
65+
// TCP RST received
66+
return stream.toByteArray();
67+
} catch (Exception E) {
5568
}
56-
}
5769

70+
}
5871
}
5972
return stream.toByteArray();
6073
}
@@ -67,7 +80,7 @@ public void sendData(byte[] data) throws IOException {
6780
outStream.flush();
6881
}
6982

70-
protected final void setStreams(InputStream inStream, OutputStream outStream) {
83+
protected final void setStreams(PushbackInputStream inStream, OutputStream outStream) {
7184
this.outStream = outStream;
7285
this.inStream = inStream;
7386
initialized = true;

Transport/src/main/java/de/rub/nds/tlsattacker/transport/nonblocking/ServerTCPNonBlockingTransportHandler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import de.rub.nds.tlsattacker.transport.ConnectionEndType;
1212
import de.rub.nds.tlsattacker.transport.TransportHandler;
1313
import java.io.IOException;
14+
import java.io.PushbackInputStream;
1415
import java.net.ServerSocket;
1516
import java.net.Socket;
1617
import java.util.concurrent.ExecutionException;
@@ -66,7 +67,7 @@ public void recheck() throws IOException {
6667
if (task.isDone()) {
6768
try {
6869
clientSocket = task.get();
69-
setStreams(clientSocket.getInputStream(), clientSocket.getOutputStream());
70+
setStreams(new PushbackInputStream(clientSocket.getInputStream()), clientSocket.getOutputStream());
7071
} catch (InterruptedException | ExecutionException ex) {
7172
LOGGER.warn("Could not retrieve clientSocket");
7273
LOGGER.debug(ex);
@@ -84,7 +85,7 @@ public void recheck(long timeout) throws IOException {
8485
if (task != null) {
8586
clientSocket = task.get(timeout, TimeUnit.MILLISECONDS);
8687
if (clientSocket != null) {
87-
setStreams(clientSocket.getInputStream(), clientSocket.getOutputStream());
88+
setStreams(new PushbackInputStream(clientSocket.getInputStream()), clientSocket.getOutputStream());
8889
}
8990
}
9091
} catch (InterruptedException | ExecutionException | TimeoutException ex) {

0 commit comments

Comments
 (0)