require 'spec_helper' require 'ronin/exploits/web_vuln' describe Ronin::Exploits::WebVuln do it "must include Ronin::Exploits::Mixins::HasPayload" do expect(described_class).to include(Ronin::Exploits::Mixins::HasPayload) end describe ".request_method" do subject { exploit_class } context "and when request_method is not set in the class" do module TestWebVuln class WithNoRequestMethodSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoRequestMethodSet } it "must default to :get" do expect(subject.request_method).to eq(:get) end end context "and when request_method is set in the class" do module TestWebVuln class WithRequestMethodSet < Ronin::Exploits::WebVuln request_method :post end end let(:exploit_class) { TestWebVuln::WithRequestMethodSet } it "must return the set request_method" do expect(subject.request_method).to eq(:post) end end context "but when the request_method was set in the superclass" do module TestWebVuln class InheritsItsRequestMethod < WithRequestMethodSet end end let(:exploit_class) { TestWebVuln::InheritsItsRequestMethod } it "must return the request_method set in the superclass" do expect(subject.request_method).to eq(:post) end context "but the request_method is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedRequestMethod < WithRequestMethodSet request_method :put end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedRequestMethod end it "must return the request_method set in the sub-class" do expect(subject.request_method).to eq(:put) end end end end describe ".base_path" do subject { exploit_class } context "and when base_path is not set in the class" do module TestWebVuln class WithNoBasePathSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoBasePathSet } it do expect { subject.base_path }.to raise_error(NotImplementedError,"#{subject} did not set base_path") end end context "and when base_path is set in the class" do module TestWebVuln class WithBasePathSet < Ronin::Exploits::WebVuln base_path '/test' end end let(:exploit_class) { TestWebVuln::WithBasePathSet } it "must return the set base_path" do expect(subject.base_path).to eq("/test") end end context "but when the base_path was set in the superclass" do module TestWebVuln class InheritsItsBasePath < WithBasePathSet end end let(:exploit_class) { TestWebVuln::InheritsItsBasePath } it "must return the base_path set in the superclass" do expect(subject.base_path).to eq("/test") end context "but the base_path is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedBasePath < WithBasePathSet base_path "/test2" end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedBasePath end it "must return the base_path set in the sub-class" do expect(subject.base_path).to eq("/test2") end end end end describe ".query_param" do subject { exploit_class } context "and when query_param is not set in the class" do module TestWebVuln class WithNoQueryParamSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoQueryParamSet } it "must default to nil" do expect(subject.query_param).to be(nil) end end context "and when query_param is set in the class" do module TestWebVuln class WithQueryParamSet < Ronin::Exploits::WebVuln query_param 'test' end end let(:exploit_class) { TestWebVuln::WithQueryParamSet } it "must return the set query_param" do expect(subject.query_param).to eq("test") end end context "but when the query_param was set in the superclass" do module TestWebVuln class InheritsItsQueryParam < WithQueryParamSet end end let(:exploit_class) { TestWebVuln::InheritsItsQueryParam } it "must return the query_param set in the superclass" do expect(subject.query_param).to eq("test") end context "but the query_param is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedQueryParam < WithQueryParamSet query_param "test2" end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedQueryParam end it "must return the query_param set in the sub-class" do expect(subject.query_param).to eq("test2") end end end end describe ".header_name" do subject { exploit_class } context "and when header_name is not set in the class" do module TestWebVuln class WithNoHeaderNameSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoHeaderNameSet } it "must default to nil" do expect(subject.header_name).to be(nil) end end context "and when header_name is set in the class" do module TestWebVuln class WithHeaderNameSet < Ronin::Exploits::WebVuln header_name 'test' end end let(:exploit_class) { TestWebVuln::WithHeaderNameSet } it "must return the set header_name" do expect(subject.header_name).to eq("test") end end context "but when the header_name was set in the superclass" do module TestWebVuln class InheritsItsHeaderName < WithHeaderNameSet end end let(:exploit_class) { TestWebVuln::InheritsItsHeaderName } it "must return the header_name set in the superclass" do expect(subject.header_name).to eq("test") end context "but the header_name is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedHeaderName < WithHeaderNameSet header_name "test2" end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedHeaderName end it "must return the header_name set in the sub-class" do expect(subject.header_name).to eq("test2") end end end end describe ".cookie_param" do subject { exploit_class } context "and when cookie_param is not set in the class" do module TestWebVuln class WithNoCookieParamSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoCookieParamSet } it "must default to nil" do expect(subject.cookie_param).to be(nil) end end context "and when cookie_param is set in the class" do module TestWebVuln class WithCookieParamSet < Ronin::Exploits::WebVuln cookie_param 'test' end end let(:exploit_class) { TestWebVuln::WithCookieParamSet } it "must return the set cookie_param" do expect(subject.cookie_param).to eq("test") end end context "but when the cookie_param was set in the superclass" do module TestWebVuln class InheritsItsCookieParam < WithCookieParamSet end end let(:exploit_class) { TestWebVuln::InheritsItsCookieParam } it "must return the cookie_param set in the superclass" do expect(subject.cookie_param).to eq("test") end context "but the cookie_param is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedCookieParam < WithCookieParamSet cookie_param "test2" end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedCookieParam end it "must return the cookie_param set in the sub-class" do expect(subject.cookie_param).to eq("test2") end end end end describe ".form_param" do subject { exploit_class } context "and when form_param is not set in the class" do module TestWebVuln class WithNoFormParamSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoFormParamSet } it "must default to nil" do expect(subject.form_param).to be(nil) end end context "and when form_param is set in the class" do module TestWebVuln class WithFormParamSet < Ronin::Exploits::WebVuln form_param 'test' end end let(:exploit_class) { TestWebVuln::WithFormParamSet } it "must return the set form_param" do expect(subject.form_param).to eq("test") end end context "but when the form_param was set in the superclass" do module TestWebVuln class InheritsItsFormParam < WithFormParamSet end end let(:exploit_class) { TestWebVuln::InheritsItsFormParam } it "must return the form_param set in the superclass" do expect(subject.form_param).to eq("test") end context "but the form_param is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedFormParam < WithFormParamSet form_param "test2" end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedFormParam end it "must return the form_param set in the sub-class" do expect(subject.form_param).to eq("test2") end end end end describe ".headers" do subject { exploit_class } context "and when headers is not set in the class" do module TestWebVuln class WithNoHeadersSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoHeadersSet } it "must default to nil" do expect(subject.headers).to be(nil) end end context "and when headers is set in the class" do module TestWebVuln class WithHeadersSet < Ronin::Exploits::WebVuln headers 'X-Foo' => 'foo' end end let(:exploit_class) { TestWebVuln::WithHeadersSet } it "must return the set headers" do expect(subject.headers).to eq({'X-Foo' => 'foo'}) end end context "but when the headers was set in the superclass" do module TestWebVuln class InheritsItsHeaders < WithHeadersSet end end let(:exploit_class) { TestWebVuln::InheritsItsHeaders } it "must return the headers set in the superclass" do expect(subject.headers).to eq({'X-Foo' => 'foo'}) end context "but the headers is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedHeaders < WithHeadersSet headers 'X-Bar' => 'bar' end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedHeaders end it "must return the headers set in the sub-class" do expect(subject.headers).to eq({'X-Bar' => 'bar'}) end end end end describe ".cookie" do subject { exploit_class } context "and when cookie is not set in the class" do module TestWebVuln class WithNoCookieSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoCookieSet } it "must default to nil" do expect(subject.cookie).to be(nil) end end context "and when cookie is set in the class" do module TestWebVuln class WithCookieSet < Ronin::Exploits::WebVuln cookie 'foo' => '1' end end let(:exploit_class) { TestWebVuln::WithCookieSet } it "must return the set cookie" do expect(subject.cookie).to eq({'foo' => '1'}) end end context "but when the cookie was set in the superclass" do module TestWebVuln class InheritsItsCookie < WithCookieSet end end let(:exploit_class) { TestWebVuln::InheritsItsCookie } it "must return the cookie set in the superclass" do expect(subject.cookie).to eq({'foo' => '1'}) end context "but the cookie is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedCookie < WithCookieSet cookie 'bar' => '2' end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedCookie end it "must return the cookie set in the sub-class" do expect(subject.cookie).to eq({'bar' => '2'}) end end end end describe ".form_data" do subject { exploit_class } context "and when form_data is not set in the class" do module TestWebVuln class WithNoFormDataSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoFormDataSet } it "must default to nil" do expect(subject.form_data).to be(nil) end end context "and when form_data is set in the class" do module TestWebVuln class WithFormDataSet < Ronin::Exploits::WebVuln form_data 'foo' => 'a' end end let(:exploit_class) { TestWebVuln::WithFormDataSet } it "must return the set form_data" do expect(subject.form_data).to eq({'foo' => 'a'}) end end context "but when the form_data was set in the superclass" do module TestWebVuln class InheritsItsFormData < WithFormDataSet end end let(:exploit_class) { TestWebVuln::InheritsItsFormData } it "must return the form_data set in the superclass" do expect(subject.form_data).to eq({'foo' => 'a'}) end context "but the form_data is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedFormData < WithFormDataSet form_data 'bar' => 'b' end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedFormData end it "must return the form_data set in the sub-class" do expect(subject.form_data).to eq({'bar' => 'b'}) end end end end describe ".referer" do subject { exploit_class } context "and when referer is not set in the class" do module TestWebVuln class WithNoRefererSet < Ronin::Exploits::WebVuln end end let(:exploit_class) { TestWebVuln::WithNoRefererSet } it "must default to nil" do expect(subject.referer).to be(nil) end end context "and when referer is set in the class" do module TestWebVuln class WithRefererSet < Ronin::Exploits::WebVuln referer '/previous/page' end end let(:exploit_class) { TestWebVuln::WithRefererSet } it "must return the set referer" do expect(subject.referer).to eq('/previous/page') end end context "but when the referer was set in the superclass" do module TestWebVuln class InheritsItsReferer < WithRefererSet end end let(:exploit_class) { TestWebVuln::InheritsItsReferer } it "must return the referer set in the superclass" do expect(subject.referer).to eq('/previous/page') end context "but the referer is overridden in the sub-class" do module TestWebVuln class OverridesItsInheritedReferer < WithRefererSet referer '/previous/page2' end end let(:exploit_class) do TestWebVuln::OverridesItsInheritedReferer end it "must return the referer set in the sub-class" do expect(subject.referer).to eq('/previous/page2') end end end end module TestWebVuln class TestExploit < Ronin::Exploits::WebVuln base_path '/path/to/vuln' query_param 'id' end end let(:exploit_class) { TestWebVuln::TestExploit } let(:base_url) { 'https://www.example.com/' } subject do exploit_class.new( params: { base_url: base_url } ) end describe "#url" do let(:expected_url) do URI(base_url).merge(exploit_class.base_path) end it "must return a URL built from the exploit's .base_path" do expect(subject.url).to eq(expected_url) end end describe "#web_vuln_kwargs" do subject do exploit_class.new( params: { base_url: base_url } ) end it "must set the :http keyword to #http" do expect(subject.web_vuln_kwargs[:http]).to be(subject.http) end context "when the exploit class defines a query_param value" do module TestWebVuln class TestExploitWithQueryParam < Ronin::Exploits::WebVuln query_param 'id' end end let(:exploit_class) { TestWebVuln::TestExploitWithQueryParam } it "must set the :query_param value" do expect(subject.web_vuln_kwargs[:query_param]).to eq(exploit_class.query_param) end end context "when the exploit class defines a header_name value" do module TestWebVuln class TestExploitWithHeaderName < Ronin::Exploits::WebVuln header_name 'X-Foo' end end let(:exploit_class) { TestWebVuln::TestExploitWithHeaderName } it "must set the :header_name value" do expect(subject.web_vuln_kwargs[:header_name]).to eq(exploit_class.header_name) end end context "when the exploit class defines a cookie_param value" do module TestWebVuln class TestExploitWithCookieParam < Ronin::Exploits::WebVuln cookie_param 'foo' end end let(:exploit_class) { TestWebVuln::TestExploitWithCookieParam } it "must set the :cookie_param value" do expect(subject.web_vuln_kwargs[:cookie_param]).to eq(exploit_class.cookie_param) end end context "when the exploit class defines a form_param value" do module TestWebVuln class TestExploitWithFormParam < Ronin::Exploits::WebVuln form_param 'bar' end end let(:exploit_class) { TestWebVuln::TestExploitWithFormParam } it "must set the :form_param value" do expect(subject.web_vuln_kwargs[:form_param]).to eq(exploit_class.form_param) end end context "when the exploit class defines a request_method value" do module TestWebVuln class TestExploitWithRequestMethod < Ronin::Exploits::WebVuln request_method :post end end let(:exploit_class) { TestWebVuln::TestExploitWithRequestMethod } it "must set the :request_method value" do expect(subject.web_vuln_kwargs[:request_method]).to eq(exploit_class.request_method) end end context "when the exploit has the 'http_user' param set" do let(:http_user) { 'bob' } subject do exploit_class.new( params: { base_url: base_url, http_user: http_user } ) end it "must set the :user value to the 'http_user' param" do expect(subject.web_vuln_kwargs[:user]).to eq(http_user) end end context "when the exploit has the 'http_password' param set" do let(:http_password) { 'secret' } subject do exploit_class.new( params: { base_url: base_url, http_password: http_password } ) end it "must set the :password value to the 'http_password' param" do expect(subject.web_vuln_kwargs[:password]).to eq(http_password) end end context "when the exploit class defines a headers value" do module TestWebVuln class TestExploitWithHeaders < Ronin::Exploits::WebVuln headers 'X-Foo' => 'foo', 'X-Bar' => 'bar' end end let(:exploit_class) { TestWebVuln::TestExploitWithHeaders } it "must set the :headers value" do expect(subject.web_vuln_kwargs[:headers]).to eq(exploit_class.headers) end end context "when the exploit class defines a cookie value" do module TestWebVuln class TestExploitWithCookie < Ronin::Exploits::WebVuln cookie 'foo' => 'a', 'bar' => 'b' end end let(:exploit_class) { TestWebVuln::TestExploitWithCookie } it "must set the :cookie value" do expect(subject.web_vuln_kwargs[:cookie]).to eq(exploit_class.cookie) end end context "when the exploit class defines a form_data value" do module TestWebVuln class TestExploitWithFormData < Ronin::Exploits::WebVuln form_data 'foo' => 'a', 'bar' => 'b' end end let(:exploit_class) { TestWebVuln::TestExploitWithFormData } it "must set the :form_data value" do expect(subject.web_vuln_kwargs[:form_data]).to eq(exploit_class.form_data) end end context "when the exploit class defines a referer value" do module TestWebVuln class TestExploitWithReferer < Ronin::Exploits::WebVuln referer '/page' end end let(:exploit_class) { TestWebVuln::TestExploitWithReferer } it "must set the :referer value to the expanded referer URL" do expect(subject.web_vuln_kwargs[:referer]).to eq(subject.url_for(exploit_class.referer)) end end end describe "#vuln" do it "must raise NotImplementedError by default" do expect { subject.vuln }.to raise_error(NotImplementedError,"#{subject.class}#vuln was not implemented") end end describe "#test" do let(:vuln) { double('Ronin::Vulns::WebVuln object') } before do expect(subject).to receive(:vuln).and_return(vuln) end context "when #vuln.vulnerable? returns true" do before { allow(vuln).to receive(:vulnerable?).and_return(true) } it "must return TestResult::Vulnerable" do result = subject.test expect(result).to be_kind_of(Ronin::Exploits::TestResult::Vulnerable) expect(result.message).to eq("The target URL is vulnerable") end end context "when #vuln.vulnerable? returns false" do before { allow(vuln).to receive(:vulnerable?).and_return(false) } it "must return TestResult::NotVulnerable" do result = subject.test expect(result).to be_kind_of(Ronin::Exploits::TestResult::NotVulnerable) expect(result.message).to eq("The target URL is not vulnerable") end end end end