Created
December 18, 2014 15:19
-
-
Save zeroSteiner/8f5d525b0c83be3fd094 to your computer and use it in GitHub Desktop.
Suggest local exploit modules
This file contains 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
require "json" | |
require "rex/ui" | |
module Msf | |
class Plugin::ModuleSuggestor < Msf::Plugin | |
class ModuleSuggestorCommandDispatcher | |
include Msf::Ui::Console::CommandDispatcher | |
def name | |
"Module Suggestor" | |
end | |
def commands | |
{ | |
"suggest_local" => "Suggest local exploit modules" | |
} | |
end | |
def get_installed_patches(session) | |
session.core.use("extapi") if not session.ext.aliases.include?("extapi") | |
objects = session.extapi.wmi.query("SELECT HotFixID FROM Win32_QuickFixEngineering") | |
objects[:values].map { |kb| kb[0][2..-1].to_i } | |
end | |
def cmd_suggest_local(*args) | |
opts = Rex::Parser::Arguments.new( | |
"-h" => [ false, "Help menu." ] | |
) | |
session_id = args.pop | |
help = false | |
opts.parse(args) { |opt, idx, val| | |
case opt | |
when "-h" | |
help = true | |
end | |
} | |
if session_id.nil? or help | |
print_line('') | |
print_line('suggest_local [OPTIONS] SESSION') | |
print_line(opts.usage) | |
return | |
end | |
session = framework.sessions.get(session_id) | |
if session.nil? | |
print_error("Invalid session id") | |
return | |
end | |
if not (session.type == "meterpreter" and session.platform =~ /win/) | |
print_error("Invalid session type #{session.platform}") | |
return | |
end | |
print_status("Getting a list of installed patches...") | |
installed_patches = get_installed_patches(session) | |
print_status("#{installed_patches.length} patches have been installed") | |
print_status("Loading local patch data...") | |
patch_data_file = ::File.join(Msf::Config.data_directory, "ms_patch_data.json") | |
patch_data = JSON.parse(File.open(patch_data_file, "r").read) | |
modules = { | |
:vulnerable => [], | |
:appears => [] | |
} | |
framework.exploits.each_module do |name, mod| | |
mod = mod.new | |
next unless mod.is_a?(Msf::Exploit::Local) | |
next unless mod.platform.supports?(::Msf::Module::PlatformList.win32) | |
patched = false | |
mod.references.each do |ref| | |
next unless ref.ctx_id == 'CVE' or ref.ctx_id == 'MSB' | |
next unless patch_data.has_key?(ref.ctx_val) | |
next if (patch_data[ref.ctx_val] & installed_patches).length == 0 | |
patched = true | |
break | |
end | |
next if patched | |
mod = framework.modules.create(name) | |
mod.datastore['SESSION'] = session_id | |
begin | |
check_result = mod.check_simple( | |
'LocalInput' => driver.input, | |
'LocalOutput' => Rex::Ui::Text::Output::None.new | |
) | |
rescue OptionValidateError | |
next | |
end | |
next if check_result == Exploit::CheckCode::Safe | |
next if check_result == Exploit::CheckCode::Unknown | |
next if check_result == Exploit::CheckCode::Unsupported | |
if check_result == Exploit::CheckCode::Vulnerable | |
print_good("Exploit #{name} is unpatched and the module reports that the target is vulnerable") | |
modules[:vulnerable].push(mod) | |
elsif check_result == Exploit::CheckCode::Appears | |
print_status("Exploit #{name} is unpatched and the module reports that the target might be vulnerable") | |
modules[:appears].push(mod) | |
end | |
end | |
if modules[:vulnerable].empty? and modules[:appears].empty? | |
print_error("No modules found") | |
return | |
end | |
unless modules[:vulnerable].empty? | |
print_good("Modules claiming the target is vulnerable:") | |
vuln_mods = modules[:vulnerable].sort { |m1, m2| m1.rank <=> m2.rank }.reverse | |
vuln_mods.each do |mod| | |
print_good("Module: #{mod.fullname} Rank: #{RankingName[mod.rank].capitalize}") | |
end | |
end | |
unless modules[:appears].empty? | |
print_status("Modules claiming the target might be vulnerable:") | |
appe_mods = modules[:appears].sort { |m1, m2| m1.rank <=> m2.rank }.reverse | |
appe_mods.each do |mod| | |
print_status("Module: #{mod.fullname} Rank: #{RankingName[mod.rank].capitalize}") | |
end | |
end | |
end | |
end | |
def initialize(framework, opts) | |
super | |
self.framework.events.add_session_subscriber(self) | |
add_console_dispatcher(ModuleSuggestorCommandDispatcher) | |
end | |
def cleanup | |
self.framework.events.remove_session_subscriber(self) | |
remove_console_dispatcher('ModuleSuggestor') | |
end | |
def name | |
"Module Suggestor" | |
end | |
def desc | |
"Recommend different exploit modules" | |
end | |
protected | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment