From 1449003d4faf9534b283c0854ecbe5d5c8d473a6 Mon Sep 17 00:00:00 2001 From: StephenOTT Date: Mon, 11 Mar 2019 21:44:44 -0400 Subject: [PATCH] Update with STIX JAVA 0.7.0 mock data generation with support for COO Extensions --- pom.xml | 4 +- .../stix/faker/StixFakeDataGenerator.groovy | 642 +++++++++++++++++- 2 files changed, 637 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 3bef0bd..4306a71 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.digitalstate.stix.faker stix-faker - 0.5.2 + 0.6.0 jar STIX 2 Faker @@ -54,7 +54,7 @@ com.github.StephenOTT STIX-Java - 0.6.1 + 0.7.0 diff --git a/src/main/groovy/io/digitalstate/stix/faker/StixFakeDataGenerator.groovy b/src/main/groovy/io/digitalstate/stix/faker/StixFakeDataGenerator.groovy index 9976f07..a13a0ca 100644 --- a/src/main/groovy/io/digitalstate/stix/faker/StixFakeDataGenerator.groovy +++ b/src/main/groovy/io/digitalstate/stix/faker/StixFakeDataGenerator.groovy @@ -1,9 +1,9 @@ package io.digitalstate.stix.faker import io.digitalstate.stix.bundle.Bundle +import io.digitalstate.stix.coo.extension.types.* import io.digitalstate.stix.coo.objects.* -import io.digitalstate.stix.coo.types.MimePartType -import io.digitalstate.stix.coo.types.WindowsRegistryValue +import io.digitalstate.stix.coo.types.* import io.digitalstate.stix.datamarkings.GranularMarking import io.digitalstate.stix.datamarkings.MarkingDefinition import io.digitalstate.stix.datamarkings.Statement @@ -20,7 +20,7 @@ import net.andreinc.mockneat.MockNeat import java.time.Instant import java.time.ZoneOffset -public class StixFakeDataGenerator { +class StixFakeDataGenerator { // MockNeat object MockNeat mock = MockNeat.threadLocal() @@ -902,7 +902,37 @@ public class StixFakeDataGenerator { File mockFileCoo() { File.Builder builder = File.builder() - //@TODO Add Extensions support for `ntfs-ext, raster-image-ext, pdf-ext, archive-ext, windows-pebinary-ext` + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockNtfsFileExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockRasterImageFileExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockPdfFileExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockArchiveFileExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockWindowsPeBinaryFileExtensionCooExt()) + } + } + } if (mock.bools().probability(50).get()) { if (mock.bools().probability(20).get()) { @@ -1035,6 +1065,34 @@ public class StixFakeDataGenerator { NetworkTraffic mockNetworkTrafficCoo() { NetworkTraffic.Builder builder = NetworkTraffic.builder() + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockHttpRequestExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockTcpExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockIcmpExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockNetworkSocketExtensionCooExt()) + } + } + } + + + if (mock.bools().probability(50).get()) { builder.start(Instant.from(mock.localDates().get().atStartOfDay().toInstant(ZoneOffset.UTC))) } @@ -1138,6 +1196,20 @@ public class StixFakeDataGenerator { Process mockProcessCoo() { Process.Builder builder = Process.builder() + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockWindowsProcessExtensionCooExt()) + } + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockWindowsServiceExtensionCooExt()) + } + } + } + if (mock.bools().probability(33).get()) { builder.isHidden(true) } else { @@ -1238,6 +1310,14 @@ public class StixFakeDataGenerator { UserAccount mockUserAccount() { UserAccount.Builder builder = UserAccount.builder() + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addExtension(mockUnixAccountExtensionCooExt()) + } + } + } + builder.userId(mock.uuids().get()) if (mock.bools().probability(50).get()) { @@ -2127,7 +2207,7 @@ public class StixFakeDataGenerator { return builder.build() } - Sighting mockSighting(){ + Sighting mockSighting() { Sighting.Builder builder = Sighting.builder() if (mock.bools().probability(50).get()) { @@ -2173,10 +2253,10 @@ public class StixFakeDataGenerator { "threat-actor", "tool", "vulnerability"] - if (manualType == null){ + if (manualType == null) { manualType = mock.fromStrings(types).get() } else { - if (!types.contains(manualType)){ + if (!types.contains(manualType)) { throw new IllegalArgumentException("invalid manualType") } } @@ -2207,4 +2287,552 @@ public class StixFakeDataGenerator { } } + ArchiveFileExtension mockArchiveFileExtensionCooExt() { + ArchiveFileExtension.Builder builder = ArchiveFileExtension.builder() + + if (mock.bools().probability(33).get()) { + mock.ints().range(1, 2).get().times { + builder.addContainsRef(mockFileCoo().getObservableObjectKey()) + } + } + + if (mock.bools().probability(50).get()) { + builder.version("${mock.ints().range(0, 5).get()}.${mock.ints().range(0, 5).get()}.${mock.ints().range(0, 5).get()}") + } + + if (mock.bools().probability(50).get()) { + builder.comment(mock.words().accumulate(mock.ints().range(1, 20).get(), " ").get()) + } + + return builder.build() + } + + HttpRequestExtension mockHttpRequestExtensionCooExt() { + HttpRequestExtension.Builder builder = HttpRequestExtension.builder() + + builder.requestMethod(mock.fromStrings("GET", "PUT", "POST", "PATCH", "DELETE").get()) + + builder.requestValue(mock.words().accumulate(mock.ints().range(1, 30).get(), " ").get().toString()) + + builder.requestVersion(mock.fromStrings("1.0", "1.1", "2.0").get()) + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 10).get().times { + String key = mock.words().accumulate(mock.ints().range(2, 3).get(), "").get() + String value = mock.words().accumulate(mock.ints().range(1, 5).get(), "-").get() + builder.putRequestHeader(key, value) + } + } + + if (mock.bools().probability(50).get()) { + builder.messageBodyLength(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.messageBodyDataRef(mockArtifactCoo().getObservableObjectKey()) + } + + return builder.build() + } + + IcmpExtension mockIcmpExtensionCooExt() { + IcmpExtension.Builder builder = IcmpExtension.builder() + + builder.icmpCodeHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + + builder.ocmpTypeHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + + return builder.build() + } + + + NetworkSocketExtension mockNetworkSocketExtensionCooExt() { + NetworkSocketExtension.Builder builder = NetworkSocketExtension.builder() + + builder.addressFamily(mock.fromStrings(new NetworkSocketAddressFamilies().getAllTerms().toList()).get()) + + if (mock.bools().probability(50).get()) { + builder.blocking(true) + } + + if (mock.bools().probability(50).get()) { + builder.listening(true) + } + + if (mock.bools().probability(50).get()) { + builder.protocolFamily(mock.fromStrings(new NetworkSocketProtocolFamilies().getAllTerms().toList()).get()) + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 10).get().times { + String key = mock.words().accumulate(mock.ints().range(2, 3).get(), "").get() + String value = mock.words().accumulate(mock.ints().range(1, 5).get(), "-").get() + builder.putOption("SO_${key}", value) + } + } + + if (mock.bools().probability(50).get()) { + builder.socketType(mock.fromStrings(new NetworkSocketTypes().getAllTerms().toList()).get()) + } + + if (mock.bools().probability(50).get()) { + builder.socketDescriptor(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.socketHandle(mock.longs().range(0, 999999999999).get()) + } + + return builder.build() + } + + NtfsFileExtenstion mockNtfsFileExtensionCooExt() { + NtfsFileExtenstion.Builder builder = NtfsFileExtenstion.builder() + + if (mock.bools().probability(50).get()) { + builder.sid(mock.words().get()) + } else { + if (mock.bools().probability(50).get()) { + builder.sid(mock.words().get()) + } + mock.ints().range(1, 5).get().times { + builder.addAlternateDataStream(mockNtfsAlternateDataStreamCooExtObj()) + } + } + return builder.build() + } + + NtfsAlternateDataStream mockNtfsAlternateDataStreamCooExtObj() { + NtfsAlternateDataStream.Builder builder = NtfsAlternateDataStream.builder() + + builder.name(mock.words().get()) + + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(20).get()) { + builder.putHash("MD5", mock.hashes().md5().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-256", mock.hashes().sha256().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-512", mock.hashes().sha512().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-1", mock.hashes().sha1().get()) + } + } + + if (mock.bools().probability(50).get()) { + builder.size(mock.longs().range(0, 999999999999).get()) + } + + return builder.build() + } + + PdfFileExtension mockPdfFileExtensionCooExt() { + PdfFileExtension.Builder builder = PdfFileExtension.builder() + + if (mock.bools().probability(50).get()) { + builder.version("${mock.ints().range(0, 5).get()}.${mock.ints().range(0, 5).get()}.${mock.ints().range(0, 5).get()}") + } + + builder.isOptimized(mock.bools().probability(50).get()) + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 10).get().times { + String key = mock.words().accumulate(mock.ints().range(2, 3).get(), "").get() + String value = mock.words().accumulate(mock.ints().range(1, 5).get(), " ").get() + builder.putDocumentInfoDict(key, value) + } + } + + if (mock.bools().probability(50).get()) { + builder.pdfId0(mock.words().accumulate(mock.ints().range(1, 2).get(), "-").get()) + } + + if (mock.bools().probability(50).get()) { + builder.pdfId1(mock.words().accumulate(mock.ints().range(1, 2).get(), "-").get()) + } + + return builder.build() + } + + RasterImageFileExtension mockRasterImageFileExtensionCooExt() { + RasterImageFileExtension.Builder builder = RasterImageFileExtension.builder() + + builder.imageHeight(mock.longs().range(0, 999999999999).get()) + + if (mock.bools().probability(50).get()) { + builder.imageWidth(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.bitsPerPixel(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.imageCompressionAlgorithm(mock.words().accumulate(mock.ints().range(1, 2).get(), "-").get()) + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 10).get().times { + String key = mock.words().accumulate(mock.ints().range(2, 3).get(), "-").get() + String value = mock.words().accumulate(mock.ints().range(1, 5).get(), " ").get() + builder.putExifTag(key, value) + } + } + + return builder.build() + } + + TcpExtension mockTcpExtensionCooExt() { + TcpExtension.Builder builder = TcpExtension.builder() + + builder.srcFlagsHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + + builder.dstFlagsHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + + return builder.build() + } + + UnixAccountExtension mockUnixAccountExtensionCooExt() { + UnixAccountExtension.Builder builder = UnixAccountExtension.builder() + + builder.gid(mock.longs().range(0, 999999999999).get()) + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addGroup(mock.words().get()) + } + } + + if (mock.bools().probability(50).get()) { + builder.homeDir("./${mock.words().accumulate(mock.ints().range(1, 5).get(), "/").get()}") + } + + if (mock.bools().probability(50).get()) { + builder.shell("${mock.words().get()} ${mock.words().accumulate(mock.ints().range(1, 5).get(), " ").get()}") + } + + return builder.build() + } + + WindowsPeBinaryFileExtension mockWindowsPeBinaryFileExtensionCooExt() { + WindowsPeBinaryFileExtension.Builder builder = WindowsPeBinaryFileExtension.builder() + + builder.peType(mock.fromStrings(new WindowsPeBinaryTypes().getAllTerms().toList()).get()) + + if (mock.bools().probability(50).get()) { + builder.imphash(mock.hashes().md5().get()) + } + + if (mock.bools().probability(50).get()) { + builder.machineHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.numberOfSections(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.timeDateStamp(Instant.from(mock.localDates().get().atStartOfDay().toInstant(ZoneOffset.UTC))) + } + + if (mock.bools().probability(50).get()) { + builder.pointerToSymbolTableHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.numberOfSymbols(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfOptionalHeader(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.characteristicsHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(20).get()) { + builder.putFileHeaderHash("MD5", mock.hashes().md5().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putFileHeaderHash("SHA-256", mock.hashes().sha256().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putFileHeaderHash("SHA-512", mock.hashes().sha512().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putFileHeaderHash("SHA-1", mock.hashes().sha1().get()) + } + } + + if (mock.bools().probability(50).get()) { + builder.optionalHeader(mockWindowsPeOptionalHeaderCooExtObj()) + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addSection(mockWindowsPeSectionCooExtObj()) + } + } + + return builder.build() + } + + WindowsPeOptionalHeader mockWindowsPeOptionalHeaderCooExtObj() { + WindowsPeOptionalHeader.Builder builder = WindowsPeOptionalHeader.builder() + + builder.magicHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + + if (mock.bools().probability(50).get()) { + builder.majorLinkerVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.minorLinkerVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfCode(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfInitializedData(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.addressOfEntryPoint(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.baseOfCode(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.baseOfData(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.imageBase(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sectionAlignment(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.fileAlignment(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.majorOsVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.minorOsVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.majorImageVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.minorImageVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.majorSubsystemVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.minorSubsystemVersion(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.win32VersionValueHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfImage(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfHeaders(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.checksumHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.subsystemHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.dllCharacteristicsHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfStackReserve(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfStackCommit(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfHeapReserve(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.sizeOfHeapCommit(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.loaderFlagsHex(mock.chars().hex().get().toString() + mock.chars().hex().get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.numberOfRvaAndSizes(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(20).get()) { + builder.putHash("MD5", mock.hashes().md5().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-256", mock.hashes().sha256().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-512", mock.hashes().sha512().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-1", mock.hashes().sha1().get()) + } + } + + return builder.build() + } + + WindowsPeSection mockWindowsPeSectionCooExtObj() { + WindowsPeSection.Builder builder = WindowsPeSection.builder() + + if (mock.bools().probability(50).get()) { + builder.name(mock.words().accumulate(mock.ints().range(1, 5).get(), "-").get()) + } + + if (mock.bools().probability(50).get()) { + builder.size(mock.longs().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + builder.entropy(mock.floats().range(0, 999999999999).get()) + } + + if (mock.bools().probability(50).get()) { + if (mock.bools().probability(20).get()) { + builder.putHash("MD5", mock.hashes().md5().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-256", mock.hashes().sha256().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-512", mock.hashes().sha512().get()) + } + + if (mock.bools().probability(20).get()) { + builder.putHash("SHA-1", mock.hashes().sha1().get()) + } + } + + return builder.build() + } + + WindowsProcessExtension mockWindowsProcessExtensionCooExt() { + WindowsProcessExtension.Builder builder = WindowsProcessExtension.builder() + + if (mock.bools().probability(50).get()) { + builder.isAslrEnabled(true) + } else { + builder.isAslrEnabled(false) + builder.isDepEnabled(mock.bools().probability(50).get()) + } + + if (mock.bools().probability(50).get()) { + builder.priority(mock.words().accumulate(mock.ints().range(1, 3).get(), "_").get()) + } + + if (mock.bools().probability(50).get()) { + builder.ownerSid(mock.ints().range(1, 999999).get().toString()) + } + + if (mock.bools().probability(50).get()) { + builder.windowTitle(mock.words().accumulate(mock.ints().range(1, 5).get(), " ").get()) + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 10).get().times { + String key = mock.words().accumulate(mock.ints().range(2, 3).get(), "-").get() + String value = mock.words().accumulate(mock.ints().range(1, 5).get(), " ").get() + builder.putStartupInfo(key, value) + } + } + + return builder.build() + } + + WindowsServiceExtension mockWindowsServiceExtensionCooExt() { + WindowsServiceExtension.Builder builder = WindowsServiceExtension.builder() + + builder.serviceName(mock.words().accumulate(mock.ints().range(1, 3).get(), "-").get()) + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 5).get().times { + builder.addDescription(mock.words().accumulate(mock.ints().range(1, 10).get(), " ").get()) + } + } + + if (mock.bools().probability(50).get()) { + builder.displayName(mock.words().accumulate(mock.ints().range(1, 2).get(), "-").get()) + } + + if (mock.bools().probability(50).get()) { + builder.groupName(mock.words().accumulate(mock.ints().range(1, 2).get(), "-").get()) + } + + if (mock.bools().probability(50).get()) { + builder.serviceStartType(mock.fromStrings(new WindowsServiceStartTypes().getAllTerms().toList()).get()) + } + + if (mock.bools().probability(50).get()) { + mock.ints().range(1, 10).get().times { + builder.addServiceDllRef(mock.words().accumulate(mock.ints().range(1, 3).get(), "-").get()) + } + } + + if (mock.bools().probability(50).get()) { + builder.serviceType(mock.fromStrings(new WindowsServiceTypes().getAllTerms().toList()).get()) + } + + if (mock.bools().probability(50).get()) { + builder.serviceStatus(mock.fromStrings(new WindowsServiceStatuses().getAllTerms().toList()).get()) + } + + return builder.build() + } + } \ No newline at end of file