Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/module_validation_spec.rb
Views: 11704
RSpec.describe ModuleValidation::Validator do1let(:mod_class) { Msf::Exploit }2let(:mod_options) do3{4framework: framework,5name: 'Testing bad chars',6author: [7Msf::Author.new('Foobar'),8Msf::Author.new('Jim'),9Msf::Author.new('Bob')10],11license: MSF_LICENSE,12references: [Msf::Module::SiteReference.new('URL', 'https://example.com')],13rank_to_s: Msf::RankingName[Msf::ExcellentRanking],14rank: Msf::ExcellentRanking,15notes: {16'Stability' => [Msf::CRASH_SAFE],17'SideEffects' => [Msf::ARTIFACTS_ON_DISK],18'Reliability' => [Msf::FIRST_ATTEMPT_FAIL],19'AKA' => %w[SMBGhost CoronaBlue]20},21stability: [Msf::CRASH_SAFE],22side_effects: [Msf::ARTIFACTS_ON_DISK],23reliability: [Msf::FIRST_ATTEMPT_FAIL],24file_path: 'modules/exploits/windows/smb/cve_2020_0796_smbghost.rb',25type: 'exploit',26platform: Msf::Module::PlatformList.new(Msf::Module::Platform::Windows),27targets: [Msf::Module::Target.new('Windows 10 v1903-1909 x64', { 'Platform' => 'win', 'Arch' => ['x64'] })],28description: %q{29A vulnerability exists within the Microsoft Server Message Block 3.1.1 (SMBv3) protocol that can be leveraged to30execute code on a vulnerable server. This remove exploit implementation leverages this flaw to execute code31in the context of the kernel, finally yielding a session as NT AUTHORITY\SYSTEM in spoolsv.exe. Exploitation32can take a few minutes as the necessary data is gathered.33}34}35end36let(:framework) do37instance_double(Msf::Framework)38end3940let(:mod) do41instance_double(mod_class, **mod_options)42end4344subject { described_class.new(mod) }4546describe '#errors' do47before(:each) do |example|48subject.validate unless example.metadata[:skip_before]49end5051context 'when the module is valid' do52it 'has no errors' do53expect(subject.errors.full_messages).to be_empty54end55end5657context 'when notes contains an invalid value' do58let(:mod_options) do59super().merge(notes: {60'Stability' => [Msf::CRASH_SAFE],61'SideEffects' => [Msf::ARTIFACTS_ON_DISK],62'Reliability' => [Msf::FIRST_ATTEMPT_FAIL],63'AKA' => %w[SMBGhost CoronaBlue],64'NOCVE' => 'Reason not given'65})66end6768it 'has errors' do69expect(subject.errors.full_messages).to eq ['Notes note value "NOCVE" must be an array, got "Reason not given"']70end71end7273context 'when the stability rating contains an invalid value' do74let(:mod_options) do75super().merge(stability: ['CRASH_SAFE'], rank: Msf::GreatRanking, rank_to_s: 'great')76end7778it 'has errors' do79expect(subject.errors.full_messages).to eq ['Stability contains invalid values ["CRASH_SAFE"] - only ["crash-safe", "crash-service-restarts", "crash-service-down", "crash-os-restarts", "crash-os-down", "service-resource-loss", "os-resource-loss"] is allowed']80end81end8283context 'when the stability rating contains an invalid values and an excellent ranking' do84let(:mod_options) do85super().merge(stability: [Msf::CRASH_SERVICE_RESTARTS])86end8788it 'has errors' do89expect(subject.errors.full_messages).to eq ['Stability must have CRASH_SAFE value if module has an ExcellentRanking, instead found ["crash-service-restarts"]']90end91end9293context 'when the side effects rating contains an invalid value' do94let(:mod_options) do95super().merge(side_effects: ['ARTIFACTS_ON_DISK'])96end9798it 'has errors' do99expect(subject.errors.full_messages).to eq ['Side effects contains invalid values ["ARTIFACTS_ON_DISK"] - only ["artifacts-on-disk", "config-changes", "ioc-in-logs", "account-lockouts", "screen-effects", "audio-effects", "physical-effects"] is allowed']100end101end102103context 'when the reliability rating contains an invalid value' do104let(:mod_options) do105super().merge(reliability: ['FIRST_ATTEMPT_FAIL'])106end107108it 'has errors' do109expect(subject.errors.full_messages).to eq ['Reliability contains invalid values ["FIRST_ATTEMPT_FAIL"] - only ["first-attempt-fail", "repeatable-session", "unreliable-session", "event-dependent"] is allowed']110end111end112113context 'when the references contains an invalid value' do114let(:mod_options) do115super().merge(references: [116Msf::Module::SiteReference.new('url', 'https://example.com'),117Msf::Module::SiteReference.new('FOO', 'https://example.com'),118Msf::Module::SiteReference.new('NOCVE', 'Reason not given'),119Msf::Module::SiteReference.new('AKA', 'Foobar'),120])121end122123it 'has errors' do124expect(subject.errors.full_messages).to eq [125'References url is not valid, must be in ["CVE", "CWE", "BID", "MSB", "EDB", "US-CERT-VU", "ZDI", "URL", "WPVDB", "PACKETSTORM", "LOGO", "SOUNDTRACK", "OSVDB", "VTS", "OVE"]',126'References FOO is not valid, must be in ["CVE", "CWE", "BID", "MSB", "EDB", "US-CERT-VU", "ZDI", "URL", "WPVDB", "PACKETSTORM", "LOGO", "SOUNDTRACK", "OSVDB", "VTS", "OVE"]',127"References NOCVE please include NOCVE values in the 'notes' section, rather than in 'references'",128"References AKA please include AKA values in the 'notes' section, rather than in 'references'"129]130end131end132133context 'when the license contains an invalid value' do134let(:mod_options) do135super().merge(license: 'MSF_LICENSE')136end137138it 'has errors' do139expect(subject.errors.full_messages).to eq ['License must include a valid license']140end141end142143context 'when the rank contains an invalid value' do144let(:mod_options) do145super().merge(rank: 'ExcellentRanking')146end147148it 'has errors' do149expect(subject.errors.full_messages).to eq ['Rank must include a valid module ranking']150end151end152153context 'when the author is missing' do154let(:mod_options) do155super().merge(author: [])156end157158it 'has errors' do159expect(subject.errors.full_messages).to eq ["Author can't be blank"]160end161end162163context 'when the author contains bad characters' do164let(:mod_options) do165super().merge(author: [166Msf::Author.new('@Foobar'),167Msf::Author.new('Foobar')168])169end170171it 'has errors' do172expect(subject.errors.full_messages).to eq ['Author must not include username handles, found "@Foobar". Try leaving it in a comment instead']173end174end175176context 'when the module name contains bad characters' do177let(:mod_options) do178super().merge(name: 'Testing <> bad & chars')179end180181it 'has errors' do182expect(subject.errors.full_messages).to eq ['Name must not contain the characters &<>']183end184end185186context 'when the module file path is not snake case' do187let(:mod_options) do188super().merge(file_path: 'modules/exploits/windows/smb/CVE_2020_0796_smbghost.rb')189end190191it 'has errors' do192expect(subject.errors.full_messages).to eq ['File path must be snake case, instead found "modules/exploits/windows/smb/CVE_2020_0796_smbghost.rb"']193end194end195196context 'when the description is missing' do197let(:mod_options) do198super().merge(description: nil)199end200201it 'has errors' do202expect(subject.errors.full_messages).to eq ["Description can't be blank"]203end204end205206context 'when the platform value is invalid', skip_before: true do207let(:mod_options) do208super().merge(platform: Msf::Module::PlatformList.new('foo'))209end210211it 'raises an ArgumentError' do212expect { subject }.to raise_error ArgumentError, 'No classes in Msf::Module::Platform for foo!'213end214end215216context 'when the platform is missing and targets does not contain platform values' do217let(:mod_options) do218super().merge(platform: nil, targets: [Msf::Module::Target.new('Windows 10 v1903-1909 x64', { 'Arch' => ['x64'] })])219end220221it 'has errors' do222expect(subject.errors.full_messages).to eq ['Platform must be included either within targets or platform module metadata']223end224end225end226end227228229