1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-10-29 18:07:27 +01:00

Land #5292, WordPress custom file version check

This commit is contained in:
William Vu 2015-05-05 11:21:18 -05:00
commit 013781fb9c
No known key found for this signature in database
GPG Key ID: 68BD00CE25866743
2 changed files with 113 additions and 1 deletions

View File

@ -82,6 +82,28 @@ module Msf::HTTP::Wordpress::Version
check_version_from_readme(:theme, theme_name, fixed_version, vuln_introduced_version)
end
# Checks a custom file for a vulnerable version
#
# @param [String] uripath The relative path of the file
# @param [Regexp] regex The regular expression to extract the version. The first captured group must contain the version.
# @param [String] fixed_version Optional, the version the vulnerability was fixed in
# @param [String] vuln_introduced_version Optional, the version the vulnerability was introduced
#
# @return [ Msf::Exploit::CheckCode ]
def check_version_from_custom_file(uripath, regex, fixed_version = nil, vuln_introduced_version = nil)
res = send_request_cgi(
'uri' => uripath,
'method' => 'GET'
)
# file not found
unless res && res.code == 200
return Msf::Exploit::CheckCode::Unknown
end
extract_and_check_version(res.body.to_s, :custom, 'custom file', fixed_version, vuln_introduced_version, regex)
end
private
def wordpress_version_helper(url, regex)
@ -137,7 +159,7 @@ module Msf::HTTP::Wordpress::Version
end
end
def extract_and_check_version(body, type, item_type, fixed_version = nil, vuln_introduced_version = nil)
def extract_and_check_version(body, type, item_type, fixed_version = nil, vuln_introduced_version = nil, regex = nil)
case type
when :readme
# Try to extract version from readme
@ -149,6 +171,8 @@ module Msf::HTTP::Wordpress::Version
# Example line:
# Version: 1.5.2
version = body[/(?:Version):\s*([0-9a-z.-]+)/i, 1]
when :custom
version = body[regex, 1]
else
fail("Unknown file type #{type}")
end

View File

@ -238,4 +238,92 @@ describe Msf::HTTP::Wordpress::Version do
end
end
describe '#check_version_from_custom_file' do
before :each do
allow(subject).to receive(:send_request_cgi) do |opts|
res = Rex::Proto::Http::Response.new
res.code = wp_code
res.body = wp_body
res
end
end
let(:wp_code) { 200 }
let(:wp_body) { nil }
let(:wp_path) { '/test/' }
let(:wp_fixed_version) { nil }
let(:wp_regex) { /(?:Version):\s*([0-9a-z.-]+)/i }
context 'when no file is found' do
let(:wp_code) { 404 }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Unknown) }
end
context 'when no version can be extracted from style' do
let(:wp_code) { 200 }
let(:wp_body) { 'invalid content' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Detected) }
end
context 'when version from style has arbitrary leading whitespace' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.0.1' }
let(:wp_body) { 'Version: 1.0.0' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Appears) }
let(:wp_body) { 'Version:1.0.0' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Appears) }
end
context 'when installed version is vulnerable' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.0.1' }
let(:wp_body) { 'Version: 1.0.0' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Appears) }
end
context 'when installed version is not vulnerable' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.0.1' }
let(:wp_body) { 'Version: 1.0.2' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Safe) }
end
context 'when installed version is vulnerable (version range)' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.0.2' }
let(:wp_introd_version) { '1.0.0' }
let(:wp_body) { 'Version: 1.0.1' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version, wp_introd_version)).to be(Msf::Exploit::CheckCode::Appears) }
end
context 'when installed version is older (version range)' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.0.1' }
let(:wp_introd_version) { '1.0.0' }
let(:wp_body) { 'Version: 0.0.9' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version, wp_introd_version)).to be(Msf::Exploit::CheckCode::Safe) }
end
context 'when installed version is newer (version range)' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.0.1' }
let(:wp_introd_version) { '1.0.0' }
let(:wp_body) { 'Version: 1.0.2' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version, wp_introd_version)).to be(Msf::Exploit::CheckCode::Safe) }
end
context 'when installed version is newer (text in version number)' do
let(:wp_code) { 200 }
let(:wp_fixed_version) { '1.5.3' }
let(:wp_body) { 'Version: 2.0.0-beta1' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex, wp_fixed_version)).to be(Msf::Exploit::CheckCode::Safe) }
end
context 'when all versions are vulnerable' do
let(:wp_code) { 200 }
let(:wp_body) { 'Version: 1.0.0' }
it { expect(subject.send(:check_version_from_custom_file, wp_path, wp_regex)).to be(Msf::Exploit::CheckCode::Appears) }
end
end
end