Skip to content

Commit 8019b62

Browse files
author
Chris Forsythe
committed
More minemeld changes
Second take on minemeld integration. Found a lot I missed from the previous push. - Added lookup functions for domain and ip list. - Added documentation. - Modified the ThreatIntelPluginConfig for the spaumhaus plugin to rename from tor_enabled to spaumhaus_enabled. - Modified the content pack to include minemeld.
1 parent 5564e12 commit 8019b62

14 files changed

+360
-3
lines changed

src/main/java/org/graylog/plugins/threatintel/PluginConfigService.java

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ public void handleUpdatedClusterConfig(ClusterConfigChangedEvent clusterConfigCh
7070
if (previous.abusechRansomEnabled() != currentVersion.abusechRansomEnabled()) {
7171
adaptersToLoad.add("abuse-ch-ransomware-domains", "abuse-ch-ransomware-ip");
7272
}
73+
if (previous.minemeldEnabled() != currentVersion.minemeldEnabled()) {
74+
adaptersToLoad.add("minemeld-domains", "minemeld-ip");
75+
}
7376
if (previous.torEnabled() != currentVersion.torEnabled()) {
7477
adaptersToLoad.add("tor-exit-node");
7578
}

src/main/java/org/graylog/plugins/threatintel/ThreatIntelPluginConfiguration.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,24 @@ public abstract class ThreatIntelPluginConfiguration {
3030

3131
@JsonProperty("abusech_ransom_enabled")
3232
public abstract boolean abusechRansomEnabled();
33+
34+
@JsonProperty("minemeld_enabled")
35+
public abstract boolean minemeldEnabled();
3336

3437
@JsonCreator
3538
public static ThreatIntelPluginConfiguration create(@JsonProperty("otx_enabled") boolean otxEnabled,
3639
@JsonProperty("otx_api_key") @Nullable String otxApiKey,
3740
@JsonProperty("tor_enabled") boolean torEnabled,
3841
@JsonProperty("spamhaus_enabled") boolean spamhausEnabled,
39-
@JsonProperty("abusech_ransom_enabled") boolean abusechRansomEnabled) {
42+
@JsonProperty("abusech_ransom_enabled") boolean abusechRansomEnabled,
43+
@JsonProperty("minemeld_enabled") boolean ) {
4044
return builder()
4145
.otxEnabled(otxEnabled)
4246
.otxApiKey(otxApiKey)
4347
.torEnabled(torEnabled)
4448
.spamhausEnabled(spamhausEnabled)
4549
.abusechRansomEnabled(abusechRansomEnabled)
50+
.minemeldEnabled(minemeldEnabled)
4651
.build();
4752
}
4853

@@ -56,6 +61,7 @@ public static ThreatIntelPluginConfiguration defaults() {
5661
.torEnabled(false)
5762
.spamhausEnabled(false)
5863
.abusechRansomEnabled(false)
64+
.minemeldEnabled(false)
5965
.build();
6066
}
6167

@@ -72,6 +78,8 @@ public static abstract class Builder {
7278
public abstract Builder spamhausEnabled(boolean spamhausEnabled);
7379

7480
public abstract Builder abusechRansomEnabled(boolean abusechRansomEnabled);
81+
82+
public abstract Builder minemeldEnabled(boolean minemeldEnabled);
7583

7684
public abstract ThreatIntelPluginConfiguration build();
7785
}

src/main/java/org/graylog/plugins/threatintel/ThreatIntelPluginModule.java

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.google.inject.multibindings.MapBinder;
77
import org.graylog.plugins.pipelineprocessor.ast.functions.Function;
88
import org.graylog.plugins.threatintel.adapters.abusech.AbuseChRansomAdapter;
9+
import org.graylog.plugins.threatintel.adapters.minemeld.MineMeldBlockListAdapter;
910
import org.graylog.plugins.threatintel.adapters.otx.OTXDataAdapter;
1011
import org.graylog.plugins.threatintel.functions.DomainFunctions;
1112
import org.graylog.plugins.threatintel.functions.IPFunctions;
@@ -15,6 +16,8 @@
1516
import org.graylog.plugins.threatintel.functions.GenericLookupResult;
1617
import org.graylog.plugins.threatintel.functions.abusech.AbuseChRansomDomainLookupFunction;
1718
import org.graylog.plugins.threatintel.functions.abusech.AbuseChRansomIpLookupFunction;
19+
import org.graylog.plugins.threatintel.functions.minemeld.MineMeldDomainLookupFunction;
20+
import org.graylog.plugins.threatintel.functions.minemeld.MineMeldIpLookupFunction;
1821
import org.graylog.plugins.threatintel.functions.global.GlobalDomainLookupFunction;
1922
import org.graylog.plugins.threatintel.functions.global.GlobalIpLookupFunction;
2023
import org.graylog.plugins.threatintel.functions.otx.OTXDomainLookupFunction;
@@ -57,6 +60,11 @@ protected void configure() {
5760
// abuse.ch Ransomware
5861
addMessageProcessorFunction(AbuseChRansomDomainLookupFunction.NAME, AbuseChRansomDomainLookupFunction.class);
5962
addMessageProcessorFunction(AbuseChRansomIpLookupFunction.NAME, AbuseChRansomIpLookupFunction.class);
63+
64+
65+
// MineMeld Threat Feeds
66+
addMessageProcessorFunction(MineMeldDomainLookupFunction.NAME, MineMeldDomainLookupFunction.class);
67+
addMessageProcessorFunction(MineMeldIpLookupFunction.NAME, MineMeldIpLookupFunction.class);
6068

6169
// Global/combined lookup
6270
addMessageProcessorFunction(GlobalIpLookupFunction.NAME, GlobalIpLookupFunction.class);
@@ -69,6 +77,7 @@ protected void configure() {
6977
addMessageProcessorFunction(PrivateNetLookupFunction.NAME, PrivateNetLookupFunction.class);
7078

7179
installLookupDataAdapter(AbuseChRansomAdapter.NAME, AbuseChRansomAdapter.class, AbuseChRansomAdapter.Factory.class, AbuseChRansomAdapter.Config.class);
80+
installLookupDataAdapter(MineMeldBlockListAdapter.NAME, MineMeldBlockListAdapter.class, MineMeldAdapter.Factory.class, MineMeldBlockListAdapter.Config.class);
7281
installLookupDataAdapter(SpamhausEDROPDataAdapter.NAME, SpamhausEDROPDataAdapter.class, SpamhausEDROPDataAdapter.Factory.class, SpamhausEDROPDataAdapter.Config.class);
7382
installLookupDataAdapter(TorExitNodeDataAdapter.NAME, TorExitNodeDataAdapter.class, TorExitNodeDataAdapter.Factory.class, TorExitNodeDataAdapter.Config.class);
7483
installLookupDataAdapter(WhoisDataAdapter.NAME, WhoisDataAdapter.class, WhoisDataAdapter.Factory.class, WhoisDataAdapter.Config.class);
@@ -79,6 +88,8 @@ protected void configure() {
7988

8089
addDomainFunction("abusech_ransomware", AbuseChRansomDomainLookupFunction.class);
8190
addIPFunction("abusech_ransomware", AbuseChRansomIpLookupFunction.class);
91+
addDomainFunction("minemeld", MineMeldDomainLookupFunction.class);
92+
addIPFunction("minemeld", MineMeldIpLookupFunction.class);
8293
addIPFunction("spamhaus", SpamhausIpLookupFunction.class);
8394
addIPFunction("tor", TorExitNodeLookupFunction.class);
8495
}

src/main/java/org/graylog/plugins/threatintel/functions/global/GlobalDomainLookupFunction.java

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.graylog.plugins.threatintel.functions.DomainFunctions;
1010
import org.graylog.plugins.threatintel.functions.GenericLookupResult;
1111
import org.graylog.plugins.threatintel.functions.abusech.AbuseChRansomDomainLookupFunction;
12+
import org.graylog.plugins.threatintel.functions.minemeld.MineMeldDomainLookupFunction;
1213
import org.graylog.plugins.threatintel.functions.misc.LookupTableFunction;
1314
import org.graylog2.plugin.cluster.ClusterConfigService;
1415
import org.slf4j.Logger;
@@ -67,6 +68,15 @@ boolean isEnabled(LookupTableFunction<? extends GenericLookupResult> function) {
6768
return true;
6869
}
6970

71+
@Override
72+
boolean isEnabled(LookupTableFunction<? extends GenericLookupResult> function) {
73+
final ThreatIntelPluginConfiguration configuration = this.threatIntelPluginConfiguration();
74+
if (function.getClass().equals(MineMeldDomainLookupFunction.class)) {
75+
return configuration.minemeldEnabled();
76+
}
77+
return true;
78+
}
79+
7080
@Override
7181
public FunctionDescriptor<GlobalLookupResult> descriptor() {
7282
return FunctionDescriptor.<GlobalLookupResult>builder()

src/main/java/org/graylog/plugins/threatintel/functions/global/GlobalIpLookupFunction.java

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.graylog.plugins.threatintel.functions.GenericLookupResult;
1010
import org.graylog.plugins.threatintel.functions.IPFunctions;
1111
import org.graylog.plugins.threatintel.functions.abusech.AbuseChRansomIpLookupFunction;
12+
import org.graylog.plugins.threatintel.functions.minemeld.MineMeldIpLookupFunction;
1213
import org.graylog.plugins.threatintel.functions.misc.LookupTableFunction;
1314
import org.graylog.plugins.threatintel.functions.otx.OTXIPLookupFunction;
1415
import org.graylog.plugins.threatintel.functions.spamhaus.SpamhausIpLookupFunction;
@@ -73,6 +74,9 @@ boolean isEnabled(LookupTableFunction<? extends GenericLookupResult> function) {
7374
if (function.getClass().equals(AbuseChRansomIpLookupFunction.class)) {
7475
return configuration.abusechRansomEnabled();
7576
}
77+
if (function.getClass().equals(MineMeldIpLookupFunction.class)) {
78+
return configuration.minemeldEnabled();
79+
}
7680
if (function.getClass().equals(OTXIPLookupFunction.class)) {
7781
return configuration.otxEnabled();
7882
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.graylog.plugins.threatintel.functions.minemeld;
2+
3+
import org.graylog.plugins.pipelineprocessor.EvaluationContext;
4+
import org.graylog.plugins.pipelineprocessor.ast.functions.FunctionArgs;
5+
import org.graylog.plugins.pipelineprocessor.ast.functions.FunctionDescriptor;
6+
import org.graylog.plugins.pipelineprocessor.ast.functions.ParameterDescriptor;
7+
import org.graylog.plugins.threatintel.functions.misc.LookupTableFunction;
8+
import org.graylog.plugins.threatintel.functions.GenericLookupResult;
9+
import org.graylog.plugins.threatintel.tools.Domain;
10+
import org.graylog2.lookup.LookupTableService;
11+
import org.graylog2.plugin.lookup.LookupResult;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
15+
import javax.inject.Inject;
16+
17+
public class MineMeldDomainLookupFunction extends LookupTableFunction<GenericLookupResult> {
18+
19+
private static final Logger LOG = LoggerFactory.getLogger(MineMeldDomainLookupFunction.class);
20+
21+
public static final String NAME = "minemeld_lookup_domain";
22+
private static final String VALUE = "domain_name";
23+
private static final String LOOKUP_TABLE_NAME = "minemeld-domains";
24+
25+
private final ParameterDescriptor<String, String> valueParam = ParameterDescriptor.string(VALUE).description("The domain to look up. Example: foo.example.org (A trailing dot ('.') will be ignored.)").build();
26+
27+
private final LookupTableService.Function lookupFunction;
28+
29+
@Inject
30+
public MineMeldDomainLookupFunction(final LookupTableService lookupTableService) {
31+
this.lookupFunction = lookupTableService.newBuilder().lookupTable(LOOKUP_TABLE_NAME).build();
32+
}
33+
34+
@Override
35+
public GenericLookupResult evaluate(FunctionArgs args, EvaluationContext context) {
36+
String domain = valueParam.required(args, context);
37+
if (domain == null) {
38+
LOG.error("NULL parameter passed to abuse.ch Ransomware domain lookup.");
39+
return null;
40+
}
41+
42+
domain = Domain.prepareDomain(domain);
43+
44+
LOG.debug("Running abuse.ch Ransomware lookup for domain [{}].", domain);
45+
46+
final LookupResult lookupResult = this.lookupFunction.lookup(domain.trim());
47+
if (lookupResult != null && !lookupResult.isEmpty() && lookupResult.singleValue() != null) {
48+
if (lookupResult.singleValue() instanceof Boolean) {
49+
return (Boolean)lookupResult.singleValue() ? GenericLookupResult.TRUE : GenericLookupResult.FALSE;
50+
}
51+
if (lookupResult.singleValue() instanceof String) {
52+
return Boolean.valueOf((String) lookupResult.singleValue()) ? GenericLookupResult.TRUE : GenericLookupResult.FALSE;
53+
}
54+
}
55+
56+
return GenericLookupResult.FALSE;
57+
}
58+
59+
@Override
60+
public FunctionDescriptor<GenericLookupResult> descriptor() {
61+
return FunctionDescriptor.<GenericLookupResult>builder()
62+
.name(NAME)
63+
.description("Match a domain name against the abuse.ch Ransomware Domain Blocklist. (RW_DOMBL)")
64+
.params(valueParam)
65+
.returnType(GenericLookupResult.class)
66+
.build();
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.graylog.plugins.threatintel.functions.minemeld;
2+
3+
import org.graylog.plugins.pipelineprocessor.EvaluationContext;
4+
import org.graylog.plugins.pipelineprocessor.ast.functions.FunctionArgs;
5+
import org.graylog.plugins.pipelineprocessor.ast.functions.FunctionDescriptor;
6+
import org.graylog.plugins.pipelineprocessor.ast.functions.ParameterDescriptor;
7+
import org.graylog.plugins.threatintel.functions.misc.LookupTableFunction;
8+
import org.graylog.plugins.threatintel.functions.GenericLookupResult;
9+
import org.graylog2.lookup.LookupTableService;
10+
import org.graylog2.plugin.lookup.LookupResult;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
import javax.inject.Inject;
15+
16+
public class MineMeldIpLookupFunction extends LookupTableFunction<GenericLookupResult> {
17+
18+
private static final Logger LOG = LoggerFactory.getLogger(MineMeldIpLookupFunction.class);
19+
20+
public static final String NAME = "minemeld_lookup_ip";
21+
private static final String VALUE = "ip_address";
22+
private static final String LOOKUP_TABLE_NAME = "minemeld-ip";
23+
24+
private final ParameterDescriptor<String, String> valueParam = ParameterDescriptor.string(VALUE).description("The IPv4 or IPv6 address to look up. Example: 198.51.100.1 or 2001:0db8:85a3:0000:0000:8a2e:0370:7334").build();
25+
26+
private final LookupTableService.Function lookupFunction;
27+
28+
@Inject
29+
public MineMeldmIpLookupFunction(final LookupTableService lookupTableService) {
30+
this.lookupFunction = lookupTableService.newBuilder().lookupTable(LOOKUP_TABLE_NAME).build();
31+
}
32+
33+
@Override
34+
public GenericLookupResult evaluate(FunctionArgs args, EvaluationContext context) {
35+
String ip = valueParam.required(args, context);
36+
if (ip == null) {
37+
LOG.error("NULL parameter passed to abuse.ch Ransomware IP lookup.");
38+
return null;
39+
}
40+
41+
LOG.debug("Running abuse.ch Ransomware lookup for IP [{}].", ip);
42+
43+
final LookupResult lookupResult = this.lookupFunction.lookup(ip.trim());
44+
if (lookupResult != null && !lookupResult.isEmpty() && lookupResult.singleValue() != null) {
45+
if (lookupResult.singleValue() instanceof Boolean) {
46+
return (Boolean)lookupResult.singleValue() ? GenericLookupResult.TRUE : GenericLookupResult.FALSE;
47+
}
48+
if (lookupResult.singleValue() instanceof String) {
49+
return Boolean.valueOf((String) lookupResult.singleValue()) ? GenericLookupResult.TRUE : GenericLookupResult.FALSE;
50+
}
51+
}
52+
53+
return GenericLookupResult.FALSE;
54+
}
55+
56+
@Override
57+
public FunctionDescriptor<GenericLookupResult> descriptor() {
58+
return FunctionDescriptor.<GenericLookupResult>builder()
59+
.name(NAME)
60+
.description("Match a IPv4 or IPv6 address against the abuse.ch Ransomware IP Blocklist. (RW_IPBL)")
61+
.params(valueParam)
62+
.returnType(GenericLookupResult.class)
63+
.build();
64+
}
65+
66+
}

src/main/resources/org/graylog/plugins/threatintel/migrations/V20170815111700_CreateThreatIntelLookupTables-content_pack.json

+46-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
"default_multi_value": "",
4242
"default_multi_value_type": "NULL"
4343
},
44+
{
45+
"title": "MineMeld Domains",
46+
"description": "This is the lookup table for the MineMeld Domain list, listing infrastructure by domain names which are used for ransomware. For more information see https://ransomwaretracker.abuse.ch. This lookup table is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
47+
"name": "minemeld-domains",
48+
"cache_name": "threat-intel-uncached-adapters",
49+
"data_adapter_name": "minemeld-domains",
50+
"default_single_value": "",
51+
"default_single_value_type": "NULL",
52+
"default_multi_value": "",
53+
"default_multi_value_type": "NULL"
54+
},
4455
{
4556
"title": "Whois",
4657
"description": "This is the lookup table for the WHOIS database, listing registered users of Internet resources like IPs, Netblocks or Domain Names. This lookup table is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
@@ -63,6 +74,17 @@
6374
"default_multi_value": "",
6475
"default_multi_value_type": "NULL"
6576
},
77+
{
78+
"title": "MineMeld IP List",
79+
"description": "This is the lookup table for the MineMeld IP List, listing infrastructure by IP which is used for nefarious reasons based on your threat feed configuration within MineMeld. This lookup table is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
80+
"name": "minemeld-ip",
81+
"cache_name": "threat-intel-uncached-adapters",
82+
"data_adapter_name": "minemeld-ip",
83+
"default_single_value": "",
84+
"default_single_value_type": "NULL",
85+
"default_multi_value": "",
86+
"default_multi_value_type": "NULL"
87+
},
6688
{
6789
"title": "Spamhaus DROP",
6890
"description": "This is the lookup table for Spamhaus' DROP (Don't Route Or Peer) list, containing netblocks which are \"hijacked\" or leased by professional spam or cyber-crime operations. For more information see https://www.spamhaus.org/drop. This lookup table is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
@@ -189,6 +211,17 @@
189211
"registry": "ARIN"
190212
}
191213
},
214+
{
215+
"title": "MineMeld Domains",
216+
"description": "This is the lookup table for the MineMeld Domain list, listing infrastructure by domain names which are used for ransomware. For more information see https://ransomwaretracker.abuse.ch. This lookup table is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
217+
"name": "minemeld-domains",
218+
"config": {
219+
"type": "minemeld",
220+
"blocklist_type": "DOMAINS",
221+
"refresh_interval": 150,
222+
"refresh_interval_unit": "SECONDS"
223+
}
224+
},
192225
{
193226
"title": "abuse.ch ransomware Domains",
194227
"description": "This is the data adapter for the abuse.ch ransomware Domain Tracker, listing infrastructure by domain names which are used for ransomware. For more information see https://ransomwaretracker.abuse.ch. This adapter is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
@@ -217,7 +250,19 @@
217250
"blocklist_type": "IPS",
218251
"refresh_interval": 150,
219252
"refresh_interval_unit": "SECONDS"
220-
}
253+
},
254+
{
255+
"title": "MineMeld IP List",
256+
"description": "This is the data adapter for the MineMeld IP List, listing infrastructure by IP which is used for nefarious reasons based on your threat feed configuration within MineMeld. This adapter is used internally by Graylog's Threat Intel Plugin. Do not delete it manually.",
257+
"name": "minemeld-ip",
258+
"config": {
259+
"type": "minemeld",
260+
"blocklist_type": "IPS",
261+
"refresh_interval": 150,
262+
"refresh_interval_unit": "SECONDS"
263+
},
264+
265+
221266
}
222267
]
223268
}

0 commit comments

Comments
 (0)