Skip to content

Commit 3a999b4

Browse files
committed
Fixed a false positve in the PaddingOracleAttacker
1 parent 06a0909 commit 3a999b4

File tree

2 files changed

+78
-11
lines changed

2 files changed

+78
-11
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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 Robert Merget <robert.merget@rub.de>
14+
*/
15+
public class PaddingOracleUnstableException extends RuntimeException {
16+
17+
public PaddingOracleUnstableException(String string) {
18+
super(string);
19+
}
20+
21+
}

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

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray;
1414
import de.rub.nds.modifiablevariable.util.ArrayConverter;
1515
import de.rub.nds.tlsattacker.attacks.config.PaddingOracleCommandConfig;
16+
import de.rub.nds.tlsattacker.attacks.exception.PaddingOracleUnstableException;
1617
import de.rub.nds.tlsattacker.attacks.util.response.EqualityError;
1718
import de.rub.nds.tlsattacker.attacks.util.response.EqualityErrorTranslator;
1819
import de.rub.nds.tlsattacker.attacks.util.response.FingerPrintChecker;
@@ -40,6 +41,7 @@
4041
import java.util.HashMap;
4142
import java.util.LinkedList;
4243
import java.util.List;
44+
import java.util.Set;
4345

4446
/**
4547
* Executes a padding oracle attack check. It logs an error in case the tested
@@ -159,6 +161,56 @@ private byte[] createPaddingBytes(int padding) {
159161

160162
@Override
161163
public Boolean isVulnerable() {
164+
165+
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
166+
"A server is considered vulnerable to this attack if it responds differently to the test vectors.");
167+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "A server is considered secure if it always responds the same way.");
168+
HashMap<Integer, List<ResponseFingerprint>> responseMap = createResponseMap();
169+
170+
EqualityError error = getEqualityError(responseMap);
171+
if (error == EqualityError.SOCKET_EXCEPTION || error == EqualityError.SOCKET_STATE) {
172+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Found a candidate for a Socket difference performing rescan");
173+
HashMap<Integer, List<ResponseFingerprint>> responseMapTwo = createResponseMap();
174+
EqualityError errorTwo = getEqualityError(responseMapTwo);
175+
if (error == errorTwo && lookEqual(responseMap, responseMapTwo)) {
176+
HashMap<Integer, List<ResponseFingerprint>> responseMapThree = createResponseMap();
177+
EqualityError errorThree = getEqualityError(responseMapThree);
178+
if (error == errorThree && lookEqual(responseMap, responseMapThree)) {
179+
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
180+
"Found an equality Error in a SocketState, performed to rescans and it still presisted");
181+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "The Server is very likely vulnerabble");
182+
} else {
183+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Rescan revealed a false positive");
184+
return false;
185+
}
186+
} else {
187+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Rescan revealed a false positive");
188+
return false;
189+
}
190+
}
191+
LOGGER.log(LogLevel.CONSOLE_OUTPUT, EqualityErrorTranslator.translation(error, null, null));
192+
return error != EqualityError.NONE;
193+
}
194+
195+
public boolean lookEqual(HashMap<Integer, List<ResponseFingerprint>> responseMapOne,
196+
HashMap<Integer, List<ResponseFingerprint>> responseMapTwo) {
197+
for (Integer key : responseMapOne.keySet()) {
198+
List<ResponseFingerprint> listOne = responseMapOne.get(key);
199+
List<ResponseFingerprint> listTwo = responseMapTwo.get(key);
200+
if (listOne.size() != listTwo.size()) {
201+
throw new PaddingOracleUnstableException(
202+
"The padding Oracle seems to be unstable - there is something going terrible wrong. We recommend manual analysis");
203+
}
204+
for (int i = 0; i < listOne.size(); i++) {
205+
if (FingerPrintChecker.checkEquality(listOne.get(i), listTwo.get(i), false) != EqualityError.NONE) {
206+
return false;
207+
}
208+
}
209+
}
210+
return true;
211+
}
212+
213+
public HashMap<Integer, List<ResponseFingerprint>> createResponseMap() {
162214
int macSize = AlgorithmResolver.getMacAlgorithm(tlsConfig.getDefaultSelectedProtocolVersion(),
163215
tlsConfig.getDefaultSelectedCipherSuite()).getSize();
164216
int blockSize = AlgorithmResolver.getCipher(tlsConfig.getDefaultSelectedCipherSuite())
@@ -173,7 +225,6 @@ public Boolean isVulnerable() {
173225
State state;
174226
try {
175227
state = executeTlsFlow(record);
176-
177228
} catch (WorkflowExecutionException | ConfigurationException E) {
178229
LOGGER.warn(E);
179230
LOGGER.warn("TLS-Attacker failed execute a Handshake. Skipping to next record");
@@ -194,29 +245,24 @@ public Boolean isVulnerable() {
194245
} else {
195246
LOGGER.warn("Could not execute Workflow. Something went wrong... Check the debug output for more information");
196247
}
197-
198248
}
199-
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
200-
"A server is considered vulnerable to this attack if it responds differently to the test vectors.");
201-
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "A server is considered secure if it always responds the same way.");
249+
return responseMap;
250+
}
202251

252+
public EqualityError getEqualityError(HashMap<Integer, List<ResponseFingerprint>> responseMap) {
203253
for (List<ResponseFingerprint> list : responseMap.values()) {
204254
ResponseFingerprint fingerprint = list.get(0);
205255
for (int i = 1; i < list.size(); i++) {
206256
EqualityError error = FingerPrintChecker.checkEquality(fingerprint, list.get(i), true);
207257
if (error != EqualityError.NONE) {
208258
LOGGER.log(LogLevel.CONSOLE_OUTPUT, "Found an equality Error: " + error);
209-
LOGGER.debug("Fingerprint1: " + fingerprint.toString());
210-
LOGGER.debug("Fingerprint2: " + list.get(i).toString());
211259
LOGGER.log(LogLevel.CONSOLE_OUTPUT,
212260
EqualityErrorTranslator.translation(error, fingerprint, list.get(i)));
213-
return true;
261+
return error;
214262
}
215-
216263
}
217264
}
218-
LOGGER.log(LogLevel.CONSOLE_OUTPUT, EqualityErrorTranslator.translation(EqualityError.NONE, null, null));
219-
return false;
265+
return EqualityError.NONE;
220266
}
221267

222268
private void clearConnections(State state) {

0 commit comments

Comments
 (0)