Merge pull request #35 from jvazquez-r7/review_6030

Merge code changes from Juan
bug/bundler_fix
sinn3r 2015-10-02 12:29:53 -05:00
commit cffb0f85fd
2 changed files with 63 additions and 46 deletions

View File

@ -3,7 +3,7 @@ load Metasploit::Framework.root.join('tools/msu_finder.rb').to_path
require 'nokogiri'
require 'uri'
describe MicrosoftPatch do
describe MicrosoftPatchFinder do
before(:each) do
cli = Rex::Proto::Http::Client.new('127.0.0.1')
@ -14,18 +14,18 @@ describe MicrosoftPatch do
end
let(:technet) do
MicrosoftPatch::SiteInfo::TECHNET
MicrosoftPatchFinder::SiteInfo::TECHNET
end
let(:microsoft) do
MicrosoftPatch::SiteInfo::MICROSOFT
MicrosoftPatchFinder::SiteInfo::MICROSOFT
end
let(:googleapis) do
MicrosoftPatch::SiteInfo::GOOGLEAPIS
MicrosoftPatchFinder::SiteInfo::GOOGLEAPIS
end
describe MicrosoftPatch::SiteInfo do
describe MicrosoftPatchFinder::SiteInfo do
context 'Constants' do
context 'TECHNET' do
it 'returns 157.56.148.23 as the IP' do
@ -59,7 +59,7 @@ describe MicrosoftPatch do
end
end
describe MicrosoftPatch::Base do
describe MicrosoftPatchFinder::Helper do
def get_stdout(&block)
out = $stdout
@ -84,7 +84,9 @@ describe MicrosoftPatch do
end
subject do
MicrosoftPatch::Base.new
mod = Object.new
mod.extend MicrosoftPatchFinder::Helper
mod
end
describe '#print_debug' do
@ -119,14 +121,14 @@ describe MicrosoftPatch do
describe '#send_http_request' do
it 'returns a Rex::Proto::Http::Response object' do
allow(subject).to receive(:print_debug)
res = subject.send_http_request(MicrosoftPatch::SiteInfo::TECHNET)
res = subject.send_http_request(MicrosoftPatchFinder::SiteInfo::TECHNET)
expect(res).to be_kind_of(Rex::Proto::Http::Response)
end
end
end
describe MicrosoftPatch::PatchLinkCollector do
describe MicrosoftPatchFinder::PatchLinkCollector do
let(:ms15_100_html) do
%Q|
@ -199,7 +201,7 @@ describe MicrosoftPatch do
end
subject do
MicrosoftPatch::PatchLinkCollector.new
MicrosoftPatchFinder::PatchLinkCollector.new
end
before(:each) do
@ -361,15 +363,15 @@ describe MicrosoftPatch do
end
describe MicrosoftPatch::TechnetMsbSearch do
describe MicrosoftPatchFinder::TechnetMsbSearch do
subject do
MicrosoftPatch::TechnetMsbSearch.new
MicrosoftPatchFinder::TechnetMsbSearch.new
end
before(:each) do
allow_any_instance_of(MicrosoftPatch::Base).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatch::Base).to receive(:send_http_request) { |info_obj, info_opts, opts|
allow_any_instance_of(MicrosoftPatchFinder::TechnetMsbSearch).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatchFinder::TechnetMsbSearch).to receive(:send_http_request) { |info_obj, info_opts, opts|
case opts['uri']
when /\/en\-us\/security\/bulletin\/dn602597\.aspx/
html = %Q|
@ -465,10 +467,10 @@ describe MicrosoftPatch do
end
describe MicrosoftPatch::GoogleMsbSearch do
describe MicrosoftPatchFinder::GoogleMsbSearch do
subject do
MicrosoftPatch::GoogleMsbSearch.new
MicrosoftPatchFinder::GoogleMsbSearch.new
end
let(:json_data) do
@ -555,8 +557,8 @@ describe MicrosoftPatch do
end
before(:each) do
allow_any_instance_of(MicrosoftPatch::Base).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatch::Base).to receive(:send_http_request) { |info_obj, info_opts, opts|
allow_any_instance_of(MicrosoftPatchFinder::GoogleMsbSearch).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatchFinder::GoogleMsbSearch).to receive(:send_http_request) { |info_obj, info_opts, opts|
res = Rex::Proto::Http::Response.new
allow(res).to receive(:body).and_return(json_data)
res
@ -608,7 +610,7 @@ describe MicrosoftPatch do
end
describe MicrosoftPatch::Module do
describe MicrosoftPatchFinder::Driver do
let(:msb) do
'ms15-100'
@ -620,17 +622,19 @@ describe MicrosoftPatch do
before(:each) do
opts = { keyword: msb }
allow(MicrosoftPatch::OptsConsole).to receive(:get_parsed_options).and_return(opts)
allow_any_instance_of(MicrosoftPatch::PatchLinkCollector).to receive(:download_advisory).and_return(Rex::Proto::Http::Response.new)
allow_any_instance_of(MicrosoftPatch::PatchLinkCollector).to receive(:get_details_aspx).and_return([expected_link])
allow_any_instance_of(MicrosoftPatch::PatchLinkCollector).to receive(:get_download_page).and_return(Rex::Proto::Http::Response.new)
allow_any_instance_of(MicrosoftPatch::PatchLinkCollector).to receive(:get_download_links).and_return([expected_link])
allow_any_instance_of(MicrosoftPatch::Base).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatch::Base).to receive(:print_error)
allow(MicrosoftPatchFinder::OptsConsole).to receive(:get_parsed_options).and_return(opts)
allow_any_instance_of(MicrosoftPatchFinder::PatchLinkCollector).to receive(:download_advisory).and_return(Rex::Proto::Http::Response.new)
allow_any_instance_of(MicrosoftPatchFinder::PatchLinkCollector).to receive(:get_details_aspx).and_return([expected_link])
allow_any_instance_of(MicrosoftPatchFinder::PatchLinkCollector).to receive(:get_download_page).and_return(Rex::Proto::Http::Response.new)
allow_any_instance_of(MicrosoftPatchFinder::PatchLinkCollector).to receive(:get_download_links).and_return([expected_link])
allow_any_instance_of(MicrosoftPatchFinder::Driver).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatchFinder::Driver).to receive(:print_error)
allow_any_instance_of(MicrosoftPatchFinder::PatchLinkCollector).to receive(:print_debug)
allow_any_instance_of(MicrosoftPatchFinder::PatchLinkCollector).to receive(:print_error)
end
subject do
MicrosoftPatch::Module.new
MicrosoftPatchFinder::Driver.new
end
describe '#get_download_links' do
@ -643,13 +647,13 @@ describe MicrosoftPatch do
describe '#google_search' do
it 'returns search results' do
skip('See rspec for MicrosoftPatch::GoogleMsbSearch#find_msb_numbers')
skip('See rspec for MicrosoftPatchFinder::GoogleMsbSearch#find_msb_numbers')
end
end
describe '#technet_search' do
it 'returns search results' do
skip('See rspec for MicrosoftPatch::TechnetMsbSearch#find_msb_numbers')
skip('See rspec for MicrosoftPatchFinder::TechnetMsbSearch#find_msb_numbers')
end
end

47
tools/msu_finder.rb Normal file → Executable file
View File

@ -21,7 +21,7 @@ require 'uri'
require 'json'
require 'optparse'
module MicrosoftPatch
module MicrosoftPatchFinder
module SiteInfo
TECHNET = {
@ -40,8 +40,8 @@ module MicrosoftPatch
}
end
# This class provides whatever other classes need.
class Base
# This provides whatever other classes need.
module Helper
# Prints a debug message.
#
@ -77,7 +77,7 @@ module MicrosoftPatch
# Sends an HTTP request with Rex.
#
# @param rhost [Hash] Information about the target host. Use MicrosoftPatch::SiteInfo.
# @param rhost [Hash] Information about the target host. Use MicrosoftPatchFinder::SiteInfo.
# @option rhost [String] :vhost
# @option rhost [String] :ip IPv4 address
# @param opts [Hash] Information about the Rex request.
@ -114,7 +114,8 @@ module MicrosoftPatch
# Collects MSU download links from Technet.
class PatchLinkCollector < Base
class PatchLinkCollector
include MicrosoftPatchFinder::Helper
# Returns a response of an advisory page.
#
@ -197,7 +198,7 @@ module MicrosoftPatch
# Returns the redirected page.
#
# @param rhost [Hash] From MicrosoftPatch::SiteInfo
# @param rhost [Hash] From MicrosoftPatchFinder::SiteInfo
# @param res [Rex::Proto::Http::Response]
# @return [Rex::Proto::Http::Response]
def follow_redirect(rhost, res)
@ -278,7 +279,9 @@ module MicrosoftPatch
# A class that searches advisories from Technet.
class TechnetMsbSearch < Base
class TechnetMsbSearch
include MicrosoftPatchFinder::Helper
def initialize
opts = {
'method' => 'GET',
@ -387,7 +390,9 @@ module MicrosoftPatch
attr_reader :firstpage
end
class GoogleMsbSearch < Base
class GoogleMsbSearch
include MicrosoftPatchFinder::Helper
# API Doc:
# https://developers.google.com/custom-search/json-api/v1/using_rest
# Known bug:
@ -430,7 +435,7 @@ module MicrosoftPatch
end
rescue RuntimeError => e
print_error(e.message)
return msb_numbers
return msb_numbers.uniq
end
msb_numbers.uniq
@ -634,11 +639,12 @@ module MicrosoftPatch
end
end
class Module < Base
class Driver
include MicrosoftPatchFinder::Helper
def initialize
begin
@args = MicrosoftPatch::OptsConsole.get_parsed_options
@args = MicrosoftPatchFinder::OptsConsole.get_parsed_options
rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
print_error(e.message)
exit
@ -651,7 +657,7 @@ module MicrosoftPatch
# @param regex [String] The regex pattern to use to collect specific download URLs.
# @return [Array<String>] Download links
def get_download_links(msb, regex=nil)
msft = MicrosoftPatch::PatchLinkCollector.new
msft = MicrosoftPatchFinder::PatchLinkCollector.new
unless msft.is_valid_msb?(msb)
print_error "Not a valid MSB format."
@ -695,9 +701,9 @@ module MicrosoftPatch
# @param keyword [String] The keyword to search
# @param api_key [String] Google API key
# @param cx [String] Google Search Engine Key
# @return [Array<String>] See MicrosoftPatch::GoogleMsbSearch#find_msb_numbers
# @return [Array<String>] See MicrosoftPatchFinder::GoogleMsbSearch#find_msb_numbers
def google_search(keyword, api_key, cx)
search = MicrosoftPatch::GoogleMsbSearch.new(api_key: api_key, search_engine_id: cx)
search = MicrosoftPatchFinder::GoogleMsbSearch.new(api_key: api_key, search_engine_id: cx)
search.find_msb_numbers(keyword)
end
@ -705,9 +711,9 @@ module MicrosoftPatch
# Performs a search via Technet
#
# @param keyword [String] The keyword to search
# @return [Array<String>] See MicrosoftPatch::TechnetMsbSearch#find_msb_numbers
# @return [Array<String>] See MicrosoftPatchFinder::TechnetMsbSearch#find_msb_numbers
def technet_search(keyword)
search = MicrosoftPatch::TechnetMsbSearch.new
search = MicrosoftPatchFinder::TechnetMsbSearch.new
search.find_msb_numbers(keyword)
end
@ -750,7 +756,7 @@ end
if __FILE__ == $PROGRAM_NAME
mod = MicrosoftPatch::Module.new
mod = MicrosoftPatchFinder::Driver.new
begin
mod.run
rescue Interrupt
@ -758,3 +764,10 @@ if __FILE__ == $PROGRAM_NAME
$stdout.puts "Good bye"
end
end
=begin
TODO:
* Make a gem
* Make it generic in order to manage different kind of patches and providers
* Multithreading
=end