Skip to content

Instantly share code, notes, and snippets.

@zeroSteiner
Created December 18, 2014 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeroSteiner/8f5d525b0c83be3fd094 to your computer and use it in GitHub Desktop.
Save zeroSteiner/8f5d525b0c83be3fd094 to your computer and use it in GitHub Desktop.
Suggest local exploit modules
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