use of com.google.tsunami.plugins.fingerprinters.web.proto.SoftwareIdentity in project tsunami-security-scanner-plugins by google.
the class FingerprintUpdater method updateFingerprints.
private Fingerprints updateFingerprints(Map<String, Hash> fileHashes, Fingerprints existingFingerprints) {
SoftwareIdentity.Builder softwareIdentityBuilder = SoftwareIdentity.newBuilder().setSoftware(options.softwareName);
if (options.pluginName != null) {
softwareIdentityBuilder.setPlugin(options.pluginName);
}
SoftwareIdentity newSoftwareIdentity = softwareIdentityBuilder.build();
if (!options.init && !newSoftwareIdentity.equals(existingFingerprints.getSoftwareIdentity())) {
throw new AssertionError("Target software is different from existing fingerprint!");
}
Map<String, ContentHash> newContentHashes = Maps.newHashMap(Maps.uniqueIndex(existingFingerprints.getContentHashesList(), ContentHash::getContentPath));
Map<Hash, HashVersion> newHashVersions = Maps.newHashMap(Maps.uniqueIndex(existingFingerprints.getHashVersionsList(), HashVersion::getHash));
Map<String, PathVersion> newPathVersions = Maps.newHashMap(Maps.uniqueIndex(existingFingerprints.getPathVersionsList(), PathVersion::getContentPath));
for (String filePath : fileHashes.keySet()) {
Hash fileHash = fileHashes.get(filePath);
// Update content to hash mapping.
newContentHashes.putIfAbsent(filePath, ContentHash.getDefaultInstance());
newContentHashes.compute(filePath, (path, oldContentHash) -> ContentHash.newBuilder().setContentPath(path).addAllHashes(ImmutableSet.<Hash>builder().addAll(oldContentHash.getHashesList()).add(fileHash).build()).build());
// Update hash to version mapping.
newHashVersions.putIfAbsent(fileHash, HashVersion.getDefaultInstance());
newHashVersions.compute(fileHash, (hash, oldHashVersion) -> HashVersion.newBuilder().setHash(hash).addAllVersions(ImmutableSet.<Version>builder().addAll(oldHashVersion.getVersionsList()).add(Version.newBuilder().setFullName(options.version).build()).build()).build());
// Update path to version mapping.
newPathVersions.putIfAbsent(filePath, PathVersion.getDefaultInstance());
newPathVersions.compute(filePath, (path, oldPathVersion) -> PathVersion.newBuilder().setContentPath(path).addAllVersions(ImmutableSet.<Version>builder().addAll(oldPathVersion.getVersionsList()).add(Version.newBuilder().setFullName(options.version).build()).build()).build());
}
return Fingerprints.newBuilder().setSoftwareIdentity(newSoftwareIdentity).addAllContentHashes(newContentHashes.values()).addAllHashVersions(newHashVersions.values()).addAllPathVersions(newPathVersions.values()).build();
}
use of com.google.tsunami.plugins.fingerprinters.web.proto.SoftwareIdentity in project tsunami-security-scanner-plugins by google.
the class ResourceFingerprintLoader method loadFingerprints.
@Override
public ImmutableMap<SoftwareIdentity, FingerprintData> loadFingerprints() throws IOException {
Stopwatch loadTimeStopwatch = Stopwatch.createStarted();
ResourceList fingerprintsResources = scanResult.getResourcesMatchingPattern(FINGERPRINTS_RESOURCE_PATTERN);
ImmutableMap.Builder<SoftwareIdentity, FingerprintData> fingerprintsBuilder = ImmutableMap.builder();
for (Resource resource : fingerprintsResources) {
logger.atInfo().log("Loading fingerprints from resource %s.", resource.getPath());
Fingerprints fingerprints = Fingerprints.parseFrom(resource.load());
fingerprintsBuilder.put(fingerprints.getSoftwareIdentity(), FingerprintData.fromProto(fingerprints));
}
ImmutableMap<SoftwareIdentity, FingerprintData> fingerprints = fingerprintsBuilder.build();
logger.atInfo().log("Finished loading %s web fingerprints data in %s.", fingerprints.size(), loadTimeStopwatch.stop());
return fingerprints;
}
use of com.google.tsunami.plugins.fingerprinters.web.proto.SoftwareIdentity in project tsunami-security-scanner-plugins by google.
the class SoftwareDetector method findRootPath.
private String findRootPath(SoftwareIdentity softwareIdentity, ImmutableMap<CrawlResult, Hash> crawlResultHashes) {
logger.atInfo().log("Found %d indicators for %s", crawlResultHashes.size(), softwareIdentity.getSoftware());
Optional<FingerprintData> fingerprintData = fingerprintRegistry.getFingerprintData(softwareIdentity);
if (!fingerprintData.isPresent()) {
logger.atWarning().log("Fingerprint data for software %s doesn't exist.", softwareIdentity.getSoftware());
return "";
}
HashMultiset<String> rootUrls = HashMultiset.create();
for (CrawlResult crawlResult : crawlResultHashes.keySet()) {
// For each crawled URL, if one of the known URLs from the fingerprint data is part of the
// crawled URL, then the difference between them is the subfolder that serves the crawled
// content.
String crawledUrl = crawlResult.getCrawlTarget().getUrl();
HttpUrl parsedCrawlUrl = HttpUrl.parse(crawledUrl);
if (parsedCrawlUrl == null) {
logger.atSevere().log("Crawled URL %s cannot be parsed.", crawlResult.getCrawlTarget().getUrl());
continue;
}
fingerprintData.get().contentHashes().keySet().stream().filter(knownPath -> parsedCrawlUrl.encodedPath().endsWith(knownPath)).forEach(knownPath -> {
logger.atInfo().log("Found known path %s that matches crawled URL %s", knownPath, crawlResult.getCrawlTarget().getUrl());
String rootUrl = crawledUrl.substring(0, crawledUrl.indexOf(knownPath));
rootUrls.add(rootUrl);
});
}
logger.atInfo().log("Confirmed %d of %d root path indicators for %s.", rootUrls.size(), crawlResultHashes.size(), softwareIdentity.getSoftware());
if (rootUrls.isEmpty()) {
return "";
}
return determineRootPath(rootUrls);
}
use of com.google.tsunami.plugins.fingerprinters.web.proto.SoftwareIdentity in project tsunami-security-scanner-plugins by google.
the class SoftwareDetector method detectSoftware.
/**
* Detect potential software for a given collection of web crawling results.
*
* <p>This method performs the software detection in the following steps:
*
* <ol>
* <li>Calculate hashes of each crawling result
* <li>Match the crawl result hashes against all known software hashes to guess potential
* software for the given crawl results. This step could generate multiple software matches
* because of common libraries that could potentially be used across software.
* <li>Finally for each identified software, try to locate the root path of the application.
* </ol>
*
* @param crawlResults a collection of web crawling results.
* @return the detected software set based on the crawling results.
*/
public ImmutableSet<DetectedSoftware> detectSoftware(Collection<CrawlResult> crawlResults) {
logger.atInfo().log("Trying to detect potential software for the scan target.");
ImmutableMap<CrawlResult, Hash> crawlResultHashes = crawlResults.stream().collect(toImmutableMap(Function.identity(), FingerprintUtils::hashCrawlResult));
ImmutableSetMultimap<SoftwareIdentity, CrawlResult> crawlResultsBySoftware = matchPotentialSoftware(crawlResultHashes);
if (crawlResultsBySoftware.isEmpty()) {
logger.atWarning().log("No known software found.");
return ImmutableSet.of();
}
ImmutableSet.Builder<DetectedSoftware> detectedSoftwareBuilder = ImmutableSet.builder();
for (SoftwareIdentity softwareIdentity : crawlResultsBySoftware.keySet()) {
ImmutableMap<CrawlResult, Hash> contentHashes = crawlResultsBySoftware.get(softwareIdentity).stream().collect(toImmutableMap(Function.identity(), crawlResultHashes::get));
if (!hasGloballyUniqueHash(contentHashes)) {
logger.atInfo().log("All detected hashes for '%s' are potentially common libs. Ignored.", softwareIdentity.getSoftware());
continue;
}
String rootPath = findRootPath(softwareIdentity, contentHashes);
if (rootPath.isEmpty()) {
logger.atInfo().log("%s likely running somewhere, but root path unknown.", softwareIdentity.getSoftware());
} else {
logger.atInfo().log("Software %s is likely running under path %s", softwareIdentity.getSoftware(), rootPath);
}
detectedSoftwareBuilder.add(DetectedSoftware.builder().setSoftwareIdentity(softwareIdentity).setRootPath(rootPath).setContentHashes(contentHashes).build());
}
return detectedSoftwareBuilder.build();
}
use of com.google.tsunami.plugins.fingerprinters.web.proto.SoftwareIdentity in project tsunami-security-scanner-plugins by google.
the class VersionDetectorTest method setUp.
@Before
public void setUp() {
mockWebServer = new MockWebServer();
fakeNetworkService = NetworkService.getDefaultInstance();
Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
install(new HttpClientModule.Builder().build());
install(new FactoryModuleBuilder().build(VersionDetector.Factory.class));
}
@Provides
ImmutableMap<SoftwareIdentity, FingerprintData> provideFingerprints() {
return ImmutableMap.of(SOFTWARE_IDENTITY_1, FINGERPRINT_DATA_1, SOFTWARE_IDENTITY_2, FINGERPRINT_DATA_2);
}
}).injectMembers(this);
}
Aggregations