From 646ed264149b225693ae9fa26d15014d605f4f51 Mon Sep 17 00:00:00 2001 From: Pierre Precourt Date: Mon, 9 Sep 2024 04:26:09 -0700 Subject: [PATCH] Optimize the `NcrackCredentialTester` module. - Ncrack is not batched anymore: this means that only one `ncrack` process will handle all of the brute-force. Previously, credentials were batched to different ncrack process, making internal optimization impossible (e.g. if an account is cracked on one instance, other instance will continue trying to crack it); - We do not pass credential pairs to ncrack anymore: Instead of providing ncrack with precomuted pairs of login/credentials, we provide it with a username and password list that it can combine internally. This also seem to affect the ability of ncrack to internally optimize attempts. When performing local tests on my setup, this change decrease the overall running time of the module by about 10% (from ~43 to ~39 minutes). PiperOrigin-RevId: 672497135 Change-Id: I0c0816a459674ed0ab3b895aadce414d6304f140 --- .../ncrack/NcrackCredentialTester.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/ncrack/NcrackCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/ncrack/NcrackCredentialTester.java index 6f9ce5302..83247d99b 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/ncrack/NcrackCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/ncrack/NcrackCredentialTester.java @@ -16,11 +16,11 @@ package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ncrack; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableSet.toImmutableSet; -import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Multimap; +import com.google.common.collect.ImmutableSet; import com.google.common.flogger.GoogleLogger; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.tsunami.common.command.CommandExecutionThreadPool; @@ -116,7 +116,7 @@ public boolean canAccept(NetworkService networkService) { @Override public boolean batched() { - return true; + return false; } @Override @@ -127,6 +127,11 @@ public ImmutableList testValidCredentials( return ImmutableList.of(); } + ImmutableSet usernames = + credentials.stream().map(TestCredential::username).collect(toImmutableSet()); + ImmutableSet passwords = + credentials.stream().map(cred -> cred.password().orElse("")).collect(toImmutableSet()); + try { // We use a Provider here to get a new NcrackClient object because this function might be // called multiple times in the client code. @@ -136,8 +141,8 @@ public ImmutableList testValidCredentials( .withTimingTemplate(TimingTemplate.NORMAL) .withQuitCrackingAfterOneFound() .withNetworkEndpoint(networkService.getNetworkEndpoint()) - .usingUsernamePasswordPair( - generateTestCredentialsMapFromListOfCredentials(credentials)) + .usingUsernameList(usernames) + .usingPasswordList(passwords) .onTargetService(getTargetService(networkService)) .run(this.executor); @@ -157,11 +162,4 @@ public ImmutableList testValidCredentials( private static TargetService getTargetService(NetworkService networkService) { return SERVICE_MAP.get(NetworkServiceUtils.getServiceName(networkService)); } - - private static Multimap generateTestCredentialsMapFromListOfCredentials( - List credentials) { - Multimap map = ArrayListMultimap.create(); - credentials.forEach(c -> map.put(c.username(), c.password().orElse(""))); - return map; - } }