Skip to content

Commit

Permalink
Add tests for resigning of Intruder payloads during fuzzing.
Browse files Browse the repository at this point in the history
  • Loading branch information
DolphFlynn committed Feb 25, 2024
1 parent 34661eb commit 0d108d7
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 15 deletions.
25 changes: 13 additions & 12 deletions src/main/java/burp/intruder/JWSPayloadProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,18 @@ public String displayName() {

// Creates a JWS object from the given attributes. Signs the JWS if possible (i.e., available key selected in Intruder settings)
private JWS createJWS(Base64URL header, Base64URL payload, Base64URL originalSignature) {
return this.loadKey().flatMap(key -> {
Optional<JWS> result = Optional.empty();

try {
// TODO - update alg within header
result = Optional.of(JWSFactory.sign(key, intruderConfig.signingAlgorithm(), header, payload));
} catch (SigningException ex) {
logging.logToError("Failed to sign JWS: " + ex);
}

return result;
}).orElseGet(() -> JWSFactory.jwsFromParts(header, payload, originalSignature));
return loadKey()
.flatMap(key -> {
try {
// TODO - update alg within header
return Optional.of(JWSFactory.sign(key, intruderConfig.signingAlgorithm(), header, payload));
} catch (SigningException ex) {
logging.logToError("Failed to sign JWS: " + ex);
return Optional.empty();
}
})
.orElseGet(
() -> JWSFactory.jwsFromParts(header, payload, originalSignature)
);
}
}
17 changes: 17 additions & 0 deletions src/test/java/burp/intruder/IntruderConfigBuilder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package burp.intruder;

import com.nimbusds.jose.JWSAlgorithm;

class IntruderConfigBuilder {
private final IntruderConfig config;

Expand All @@ -17,6 +19,21 @@ IntruderConfigBuilder withFuzzParameter(String parameterName) {
return this;
}

IntruderConfigBuilder withSigningKeyId(String signingId) {
config.setSigningKeyId(signingId);
return this;
}

IntruderConfigBuilder withSigningAlgorithm(JWSAlgorithm algorithm) {
config.setSigningAlgorithm(algorithm);
return this;
}

IntruderConfigBuilder withResigning(boolean resign) {
config.setResign(resign);
return this;
}

IntruderConfig build() {
return config;
}
Expand Down
62 changes: 62 additions & 0 deletions src/test/java/burp/intruder/JWSPayloadProcessorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import static burp.intruder.FuzzLocation.PAYLOAD;
import static burp.intruder.IntruderConfigBuilder.intruderConfig;
import static com.blackberry.jwteditor.KeysModelBuilder.keysModel;
import static com.nimbusds.jose.JWSAlgorithm.RS512;
import static data.PemData.RSA1024Private;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
Expand All @@ -29,6 +31,7 @@
@ExtendWith(MontoyaExtension.class)
class JWSPayloadProcessorTest {
private static final KeysModel EMPTY_KEYS_MODEL = keysModel().build();
private static final String KEY_ID = "id";

@BeforeEach
void configureMocks() {
Expand Down Expand Up @@ -105,4 +108,63 @@ void givenBaseValueJWSAndFuzzParameterPresentInPayload_whenPayloadProcessed_then
assertThat(result.action()).isEqualTo(USE_PAYLOAD);
assertThat(result.processedPayload().toString()).isEqualTo("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImVtYW5vbiIsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
}

@Test
void givenBaseValueJWSAndFuzzParameterPresentInPayload_whenSigningKeyLoadedButResignOff_thenPayloadModifiedButNotResigned() {
String baseValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
PayloadData payloadData = payloadData().withBaseValue(baseValue).withCurrentPayload("emanon").build();
KeysModel keysModel = keysModel().withRSAKey(RSA1024Private, KEY_ID).build();
IntruderConfig intruderConfig = intruderConfig()
.withFuzzParameter("name")
.withFuzzLocation(PAYLOAD)
.withSigningKeyId(KEY_ID)
.withSigningAlgorithm(RS512)
.build();

JWSPayloadProcessor processor = new JWSPayloadProcessor(intruderConfig, LOGGING, keysModel);
PayloadProcessingResult result = processor.processPayload(payloadData);

assertThat(result.action()).isEqualTo(USE_PAYLOAD);
assertThat(result.processedPayload().toString()).isEqualTo("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImVtYW5vbiIsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
}

@Test
void givenBaseValueJWSAndFuzzParameterPresentInPayload_whenResignOnButUnknownSigningKeyConfigured_thenPayloadModifiedButNotResigned() {
String baseValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
PayloadData payloadData = payloadData().withBaseValue(baseValue).withCurrentPayload("emanon").build();
KeysModel keysModel = keysModel().withRSAKey(RSA1024Private, KEY_ID).build();
IntruderConfig intruderConfig = intruderConfig()
.withFuzzParameter("name")
.withFuzzLocation(PAYLOAD)
.withSigningKeyId("rogue")
.withSigningAlgorithm(RS512)
.withResigning(true)
.build();

JWSPayloadProcessor processor = new JWSPayloadProcessor(intruderConfig, LOGGING, keysModel);
PayloadProcessingResult result = processor.processPayload(payloadData);

assertThat(result.action()).isEqualTo(USE_PAYLOAD);
assertThat(result.processedPayload().toString()).isEqualTo("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImVtYW5vbiIsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
}

@Test
void givenBaseValueJWSAndFuzzParameterPresentInPayload_whenResignOnAndSigningKeyPresentAndAlgorithmUnchanged_thenPayloadModifiedAndResignedButAlgUnchanged() {
String baseValue = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.LX5A6Hu00jlQ2n8s1SoVL4BEPjMiF1zrEs3qRtV08sbmsqxXV8bc8LarGm8YZj2OuXWL7aOkdBc9ezOBi5bjxsrtiUmwo5VWlU5Y6PXqGwH5v7w0kpRckdd0IA3nbrR2SyLQ1L1pQJk2PzoCvEpspBPMxtIyrK5MTep3Yx1Xn3aiw3aE1cHzOwK0xBIg-RW5qK5PwPa4H8T7eOOSMytS6N4AiZbeiIVHBWxmjrdp8AuC_fmfM1TQA_O8gK_1QkK3jPWkmbbtb48ut6dxz3H_gvPkPzsRE96nQ1qcOlbJjN0URcR2Tc1ACwZO4VpY4gujo_LwTsLiKQcmq0glFA3SIw";
PayloadData payloadData = payloadData().withBaseValue(baseValue).withCurrentPayload("emanon").build();
KeysModel keysModel = keysModel().withRSAKey(RSA1024Private, KEY_ID).build();
IntruderConfig intruderConfig = intruderConfig()
.withFuzzParameter("name")
.withFuzzLocation(PAYLOAD)
.withSigningKeyId(KEY_ID)
.withSigningAlgorithm(RS512)
.withResigning(true)
.build();

JWSPayloadProcessor processor = new JWSPayloadProcessor(intruderConfig, LOGGING, keysModel);
PayloadProcessingResult result = processor.processPayload(payloadData);

assertThat(result.action()).isEqualTo(USE_PAYLOAD);
assertThat(result.processedPayload().toString()).isEqualTo("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImVtYW5vbiIsImlhdCI6MTUxNjIzOTAyMn0.poPOxqjqp-CnC2b7eaf2QvfvAfawzp6k-P1QECIHN7KCTnFIlQbiJC4ZtLPH_0-o3HQcUGZbib3m1CVWeY21FIUTVUmOyjU8XuBohtBXRlXoaKXVWibrm5YiLC3yNQz5uAF-gdBB8ybvsmetK7JIZ8UvQdJ3mdvlAAW-3xFv8fs");
}
}
18 changes: 15 additions & 3 deletions src/test/java/com/blackberry/jwteditor/KeysModelBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,29 @@ public class KeysModelBuilder {
private final KeysModel model = new KeysModel();

public KeysModelBuilder withECKey(String pem) {
model.addKey(loadECKey(pem, nextKeyId()));
return withECKey(pem, nextKeyId());
}

public KeysModelBuilder withECKey(String pem, String keyId) {
model.addKey(loadECKey(pem, keyId));
return this;
}

public KeysModelBuilder withRSAKey(String pem) {
model.addKey(loadRSAKey(pem, nextKeyId()));
return withRSAKey(pem, nextKeyId());
}

public KeysModelBuilder withRSAKey(String pem, String keyId) {
model.addKey(loadRSAKey(pem, keyId));
return this;
}

public KeysModelBuilder withOKPKey(String pem) {
model.addKey(loadOKPKey(pem, nextKeyId()));
return withOKPKey(pem, nextKeyId());
}

public KeysModelBuilder withOKPKey(String pem, String keyId) {
model.addKey(loadOKPKey(pem, keyId));
return this;
}

Expand Down

0 comments on commit 0d108d7

Please sign in to comment.