PageRenderTime 106ms CodeModel.GetById 20ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 1ms

/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb

https://github.com/debbiemezyene/metasploit-framework
Ruby | 1174 lines | 947 code | 222 blank | 5 comment | 41 complexity | edceedd2d173a42dae5f4cb1e9a37621 MD5 | raw file
   1# -*- coding:binary -*-
   2require 'builder'
   3
   4shared_examples_for 'Msf::DBManager::ImportMsfXml' do
   5  # Serialized format from pro/modules/auxiliary/pro/report.rb
   6  def serialize(object)
   7    # FIXME https://www.pivotaltracker.com/story/show/46578647
   8    marshalled = Marshal.dump(object)
   9    base64_encoded = [marshalled].pack('m')
  10    compact = base64_encoded.gsub(/\s+/, '')
  11
  12    compact
  13  end
  14
  15  def with_info
  16    db_manager.should_receive(:import_msf_web_element) do |*args, &specialization|
  17      info = specialization.call(element, options)
  18
  19      yield info
  20    end
  21
  22    subject
  23  end
  24
  25  let(:allow_yaml) do
  26    false
  27  end
  28
  29  let(:document) do
  30    REXML::Document.new(source)
  31  end
  32
  33  let(:element) do
  34    nil
  35  end
  36
  37  let(:host_attributes) do
  38    FactoryGirl.attributes_for(:mdm_host)
  39  end
  40
  41  let(:msf_web_text_element_names) do
  42    [
  43        'created-at',
  44        'host',
  45        'path',
  46        'port',
  47        'query',
  48        'ssl',
  49        'updated-at',
  50        'vhost'
  51    ]
  52  end
  53
  54  let(:notifier) do
  55    lambda do |event, data|
  56
  57    end
  58  end
  59
  60  let(:options) do
  61    {
  62        :allow_yaml => allow_yaml,
  63        :workspace => workspace
  64    }
  65  end
  66
  67  let(:service_attributes) do
  68    FactoryGirl.attributes_for(:web_service)
  69  end
  70
  71  let(:web_form_attributes) do
  72    FactoryGirl.attributes_for(:mdm_web_form, :exported)
  73  end
  74
  75  let(:web_page_attributes) do
  76    FactoryGirl.attributes_for(:mdm_web_page)
  77  end
  78
  79  let(:workspace) do
  80    nil
  81  end
  82
  83  let(:xml) do
  84    Builder::XmlMarkup.new(:indent => 2)
  85  end
  86
  87  it 'should include methods from module so method can be overridden easier in pro' do
  88    db_manager.should be_a Msf::DBManager::ImportMsfXml
  89  end
  90
  91  context 'CONSTANTS' do
  92    it 'should define MSF_WEB_PAGE_TEXT_ELEMENT_NAMES in any order' do
  93      described_class::MSF_WEB_PAGE_TEXT_ELEMENT_NAMES =~ [
  94          'auth',
  95          'body',
  96          'code',
  97          'cookie',
  98          'ctype',
  99          'location',
 100          'mtime'
 101      ]
 102    end
 103
 104    it 'should define MSF_WEB_TEXT_ELEMENT_NAMES in any order' do
 105      described_class::MSF_WEB_TEXT_ELEMENT_NAMES =~ msf_web_text_element_names
 106    end
 107
 108    it 'should define MSF_WEB_VULN_TEXT_ELEMENT_NAMES in any order' do
 109      described_class::MSF_WEB_VULN_TEXT_ELEMENT_NAMES =~ [
 110          'blame',
 111          'category',
 112          'confidence',
 113          'description',
 114          'method',
 115          'name',
 116          'pname',
 117          'proof',
 118          'risk'
 119      ]
 120    end
 121  end
 122
 123  context '#check_msf_xml_version!' do
 124    let(:root_tag) do
 125      'root'
 126    end
 127
 128    let(:source) do
 129      xml.tag!(root_tag)
 130
 131      xml.target!
 132    end
 133
 134    subject(:metadata) do
 135      db_manager.send(:check_msf_xml_version!, document)
 136    end
 137
 138    it_should_behave_like(
 139        'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag',
 140        'MetasploitExpressV1',
 141        :allow_yaml => true
 142    )
 143
 144    it_should_behave_like(
 145        'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag',
 146        'MetasploitExpressV2',
 147        :allow_yaml => true
 148    )
 149
 150    it_should_behave_like(
 151        'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag',
 152        'MetasploitExpressV3',
 153        :allow_yaml => false
 154    )
 155
 156    it_should_behave_like(
 157        'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag',
 158        'MetasploitExpressV4',
 159        :allow_yaml => false
 160    )
 161
 162    context 'with other' do
 163      it 'should raise DBImportError' do
 164        expect {
 165          metadata
 166        }.to raise_error(
 167                 Msf::DBImportError,
 168                 'Unsupported Metasploit XML document format'
 169             )
 170      end
 171    end
 172  end
 173
 174  context '#import_msf_text_element' do
 175    let(:parent_element) do
 176      document.root
 177    end
 178
 179    let(:child_name) do
 180      'child'
 181    end
 182
 183    let(:child_sym) do
 184      child_name.to_sym
 185    end
 186
 187    subject(:info) do
 188      db_manager.send(:import_msf_text_element, parent_element, child_name)
 189    end
 190
 191    context 'with child element' do
 192      let(:source) do
 193        xml.parent do
 194          xml.tag!(child_name, text)
 195        end
 196
 197        xml.target!
 198      end
 199
 200      context 'with padded text' do
 201        let(:stripped) do
 202          'stripped'
 203        end
 204
 205        let(:text) do
 206          "  #{stripped} "
 207        end
 208
 209        it 'should strip text' do
 210          info[:child].should == stripped
 211        end
 212      end
 213
 214      context 'with NULL text' do
 215        let(:text) do
 216          'NULL'
 217        end
 218
 219        it 'should have nil for child name in info' do
 220          # use have_key to verify info isn't just returning hash default of
 221          # `nil`.
 222          info.should have_key(child_sym)
 223          info[child_sym].should be_nil
 224        end
 225      end
 226
 227      context 'without NULL text' do
 228        let(:text) do
 229          'some text'
 230        end
 231
 232        it 'should have text for child name in info' do
 233          info[child_sym].should == text
 234        end
 235      end
 236    end
 237
 238    context 'without child element' do
 239      let(:source) do
 240        xml.parent
 241
 242        xml.target!
 243      end
 244
 245      it 'should return an empty Hash' do
 246        info.should == {}
 247      end
 248    end
 249  end
 250
 251  context 'import_msf_web_element' do
 252    let(:element) do
 253      document.root
 254    end
 255
 256    let(:options) do
 257      {}
 258    end
 259
 260    let(:specialization) do
 261      lambda { |element, options|
 262        {}
 263      }
 264    end
 265
 266    subject(:import_msf_web_element) do
 267      db_manager.send(
 268          :import_msf_web_element,
 269          element,
 270          options,
 271          &specialization
 272      )
 273    end
 274
 275    context 'with :type' do
 276      include_context 'DatabaseCleaner'
 277
 278      let(:source) do
 279        xml.tag!("web_#{type}") do
 280          web_site = web_vuln.web_site
 281          service = web_site.service
 282
 283          xml.host(service.host.address)
 284          xml.path(web_vuln.path)
 285          xml.port(service.port)
 286          xml.query(web_vuln.query)
 287
 288          ssl = false
 289
 290          if service.name == 'https'
 291            ssl = true
 292          end
 293
 294          xml.ssl(ssl)
 295
 296          xml.vhost(web_site.vhost)
 297        end
 298
 299        xml.target!
 300      end
 301
 302      let(:type) do
 303        :vuln
 304      end
 305
 306      let(:web_vuln) do
 307        FactoryGirl.create(:mdm_web_vuln)
 308      end
 309
 310      before(:each) do
 311        db_manager.stub(
 312            :report_web_vuln
 313        ).with(
 314            an_instance_of(Hash)
 315        )
 316
 317        options[:type] = type
 318      end
 319
 320      context 'with :workspace' do
 321        let(:workspace) do
 322          double(':workspace')
 323        end
 324
 325        before(:each) do
 326          options[:workspace] = workspace
 327        end
 328
 329        it 'should not call Msf::DBManager#workspace' do
 330          db_manager.should_not_receive(:workspace)
 331
 332          import_msf_web_element
 333        end
 334
 335        it 'should pass :workspace to report_web_<:type>' do
 336          db_manager.should_receive(
 337              "report_web_#{type}"
 338          ).with(
 339              hash_including(:workspace => workspace)
 340          )
 341
 342          import_msf_web_element
 343        end
 344      end
 345
 346      context 'without :workspace' do
 347        let(:workspace) do
 348          FactoryGirl.create(:mdm_workspace)
 349        end
 350
 351        before(:each) do
 352          db_manager.workspace = workspace
 353        end
 354
 355        it 'should call Msf::DBManager#workspace' do
 356          db_manager.should_receive(:workspace).and_call_original
 357
 358          import_msf_web_element
 359        end
 360
 361        it 'should pass Msf::DBManager#workspace to report_web_<:type>' do
 362          db_manager.should_receive(
 363              "report_web_#{type}"
 364          ).with(
 365              hash_including(:workspace => workspace)
 366          )
 367
 368          import_msf_web_element
 369        end
 370      end
 371
 372      it 'should import all elements in MSF_WEB_TEXT_ELEMENT_NAMES with #import_msf_text_element' do
 373        msf_web_text_element_names.each do |name|
 374          db_manager.should_receive(
 375              :import_msf_text_element
 376          ).with(
 377              element,
 378              name
 379          ).and_call_original
 380        end
 381
 382        import_msf_web_element
 383      end
 384
 385      context 'with non-empty Hash from #import_msf_text_element' do
 386        let(:returned_hash) do
 387          {
 388              :host => '192.168.0.1'
 389          }
 390        end
 391
 392        before(:each) do
 393          db_manager.stub(:import_msf_text_element).and_return(returned_hash)
 394        end
 395
 396        it 'should pass returned Hash as part of Hash passed to report_web_<:type' do
 397          db_manager.should_receive(
 398              "report_web_#{type}"
 399          ).with(
 400              hash_including(returned_hash)
 401          )
 402
 403          import_msf_web_element
 404        end
 405      end
 406
 407      context 'ssl element' do
 408        context 'without element' do
 409          let(:source) do
 410            xml.tag!("web_#{type}")
 411
 412            xml.target!
 413          end
 414
 415          it 'should pass false for :ssl to report_web_<:type>' do
 416            db_manager.should_receive(
 417                "report_web_#{type}"
 418            ).with(
 419                hash_including(:ssl => false)
 420            )
 421
 422            import_msf_web_element
 423          end
 424        end
 425
 426        context 'with element' do
 427          let(:source) do
 428            xml.tag!("web_#{type}") do
 429              xml.ssl(ssl)
 430            end
 431
 432            xml.target!
 433          end
 434
 435          context "with 'true' text" do
 436            let(:ssl) do
 437              true
 438            end
 439
 440            it 'should pass true for :ssl to report_web_<:type>' do
 441              db_manager.should_receive(
 442                  "report_web_#{type}"
 443              ).with(
 444                  hash_including(:ssl => true)
 445              )
 446
 447              import_msf_web_element
 448            end
 449          end
 450
 451          context "without 'true' text" do
 452            let(:ssl) do
 453              false
 454            end
 455
 456            it 'should pass false for :ssl to report_web_<:type>' do
 457              db_manager.should_receive(
 458                  "report_web_#{type}"
 459              ).with(
 460                  hash_including(:ssl => false)
 461              )
 462
 463              import_msf_web_element
 464            end
 465          end
 466        end
 467      end
 468
 469      context 'specialization block' do
 470        let(:returned_hash) do
 471          {
 472              :specialized => double('Value')
 473          }
 474        end
 475
 476        let(:specialization) do
 477          lambda { |element, option|
 478            returned_hash
 479          }
 480        end
 481
 482        it 'should be called with element and options' do
 483          actual_args = []
 484
 485          db_manager.send(
 486              :import_msf_web_element,
 487              element,
 488              options) do |*args|
 489            actual_args = args
 490
 491            returned_hash
 492          end
 493
 494          actual_args.should == [element, options]
 495        end
 496
 497        it 'should pass return Hash to report_web_<:type>' do
 498          db_manager.should_receive(
 499              "report_web_#{type}"
 500          ).with(
 501              hash_including(returned_hash)
 502          )
 503
 504          import_msf_web_element
 505        end
 506      end
 507
 508      context 'notifier' do
 509        context 'with :notifier' do
 510          let(:event) do
 511            "web_#{type}".to_sym
 512          end
 513
 514          let(:notifier) do
 515            lambda do |*args|
 516              successive_args << args
 517            end
 518          end
 519
 520          let(:successive_args) do
 521            []
 522          end
 523
 524          before(:each) do
 525            options[:notifier] = notifier
 526          end
 527
 528          it 'should call :notifier with event and path' do
 529            import_msf_web_element
 530
 531            successive_args.length.should == 1
 532
 533            args = successive_args[0]
 534
 535            args.length.should == 2
 536            args[0].should == event
 537            args[1].should == web_vuln.path
 538          end
 539        end
 540
 541        context 'without :notifier' do
 542          it 'should not raise an error' do
 543            expect {
 544              import_msf_web_element
 545            }.to_not raise_error
 546          end
 547        end
 548      end
 549    end
 550
 551    context 'without :type' do
 552      let(:element) do
 553        nil
 554      end
 555
 556      it 'should raise KeyError' do
 557        expect {
 558          import_msf_web_element
 559        }.to raise_error(KeyError, 'key not found: :type')
 560      end
 561    end
 562  end
 563
 564  context '#import_msf_web_form_element' do
 565    let(:type) do
 566      :form
 567    end
 568
 569    subject(:import_msf_web_form_element) do
 570      db_manager.import_msf_web_form_element(
 571          element,
 572          options,
 573          &notifier
 574      )
 575    end
 576
 577    context 'call to #import_msf_web_element' do
 578      it_should_behave_like 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization'
 579
 580      context 'specialization return' do
 581        let(:element) do
 582          document.root
 583        end
 584
 585        let(:source) do
 586          xml.web_form do
 587            xml.method(
 588                web_form_attributes.fetch(:method)
 589            )
 590
 591            serialized_params = serialize(
 592                web_form_attributes.fetch(:params)
 593            )
 594            xml.params(serialized_params)
 595          end
 596
 597          xml.target!
 598        end
 599
 600        it 'should be a Hash' do
 601          with_info do |info|
 602            info.should be_a Hash
 603          end
 604        end
 605
 606        it 'should include :method' do
 607          with_info do |info|
 608            info[:method].should == web_form_attributes[:method]
 609          end
 610        end
 611
 612        it 'should include :params' do
 613          with_info do |info|
 614            info[:params].should == web_form_attributes[:params]
 615          end
 616        end
 617      end
 618    end
 619
 620    context 'with required attributes' do
 621      include_context 'DatabaseCleaner'
 622
 623      let(:element) do
 624        document.root
 625      end
 626
 627      let(:source) do
 628        xml.web_form do
 629          xml.host(
 630              host_attributes.fetch(:address)
 631          )
 632          xml.method(
 633              web_form_attributes.fetch(:method)
 634          )
 635          xml.path(
 636              web_form_attributes.fetch(:path)
 637          )
 638          xml.port(
 639              service_attributes.fetch(:port)
 640          )
 641
 642          ssl = false
 643
 644          if service_attributes[:name] == 'https'
 645            ssl = true
 646          end
 647
 648          xml.ssl(ssl)
 649        end
 650
 651        xml.target!
 652      end
 653
 654      it 'should create an Mdm::WebForm' do
 655        expect {
 656          import_msf_web_form_element
 657        }.to change(Mdm::WebForm, :count).by(1)
 658      end
 659    end
 660  end
 661
 662  context '#import_msf_web_page_element' do
 663    let(:type) do
 664      :page
 665    end
 666
 667    subject(:import_msf_web_page_element) do
 668      db_manager.import_msf_web_page_element(
 669          element,
 670          options,
 671          &notifier
 672      )
 673    end
 674
 675    context 'call to #import_msf_web_element' do
 676      it_should_behave_like 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization'
 677
 678      context 'specialization return' do
 679        let(:element) do
 680          document.root
 681        end
 682
 683        let(:source) do
 684          xml.web_page do
 685            xml.auth(
 686                web_page_attributes.fetch(:auth)
 687            )
 688            xml.body(
 689                web_page_attributes.fetch(:body)
 690            )
 691            xml.code(
 692                web_page_attributes.fetch(:code)
 693            )
 694            xml.cookie(
 695                web_page_attributes.fetch(:cookie)
 696            )
 697            xml.ctype(
 698                web_page_attributes.fetch(:ctype)
 699            )
 700
 701            serialized_headers = serialize(
 702                web_page_attributes.fetch(:headers)
 703            )
 704            xml.headers(serialized_headers)
 705
 706            xml.location(
 707                web_page_attributes.fetch(:location)
 708            )
 709            xml.mtime(
 710                web_page_attributes.fetch(:mtime)
 711            )
 712          end
 713
 714          xml.target!
 715        end
 716
 717        it 'should be a Hash' do
 718          db_manager.should_receive(:import_msf_web_element) do |*args, &specialization|
 719            info = specialization.call(element, options)
 720
 721            info.should be_a Hash
 722          end
 723
 724          import_msf_web_page_element
 725        end
 726
 727        it 'should include :auth' do
 728          with_info do |info|
 729            info[:auth].should == web_page_attributes.fetch(:auth)
 730          end
 731        end
 732
 733        it 'should include :body' do
 734          with_info do |info|
 735            info[:body].should == web_page_attributes.fetch(:body)
 736          end
 737        end
 738
 739        it 'should include :code' do
 740          with_info do |info|
 741            info[:code].should == web_page_attributes.fetch(:code)
 742          end
 743        end
 744
 745        it 'should include :cookie' do
 746          with_info do |info|
 747            info[:cookie].should == web_page_attributes.fetch(:cookie)
 748          end
 749        end
 750
 751        it 'should include :ctype' do
 752          with_info do |info|
 753            info[:ctype].should == web_page_attributes.fetch(:ctype)
 754          end
 755        end
 756
 757        it 'should include :headers' do
 758          with_info do |info|
 759            info[:headers].should == web_page_attributes.fetch(:headers)
 760          end
 761        end
 762
 763        it 'should include :location' do
 764          with_info do |info|
 765            info[:location].should == web_page_attributes.fetch(:location)
 766          end
 767        end
 768
 769        it 'should include :mtime' do
 770          with_info do |info|
 771            info[:mtime].should == web_page_attributes.fetch(:mtime)
 772          end
 773        end
 774      end
 775    end
 776
 777    context 'with required attributes' do
 778      include_context 'DatabaseCleaner'
 779
 780      let(:element) do
 781        document.root
 782      end
 783
 784      let(:source) do
 785        xml.web_page do
 786          xml.body(
 787              web_page_attributes.fetch(:body)
 788          )
 789          xml.code(
 790              web_page_attributes.fetch(:code)
 791          )
 792
 793          serialized_headers = serialize(
 794              web_page_attributes.fetch(:headers)
 795          )
 796          xml.headers(serialized_headers)
 797
 798          xml.host(
 799              host_attributes.fetch(:address)
 800          )
 801          xml.path(
 802              web_page_attributes.fetch(:headers)
 803          )
 804          xml.port(
 805              service_attributes.fetch(:port)
 806          )
 807          xml.query(
 808              web_page_attributes.fetch(:query)
 809          )
 810
 811          ssl = false
 812
 813          if service_attributes[:name] == 'https'
 814            ssl = true
 815          end
 816
 817          xml.ssl(ssl)
 818        end
 819
 820        xml.target!
 821      end
 822
 823      it 'should create an Mdm::WebPage' do
 824        expect {
 825          import_msf_web_page_element
 826        }.to change(Mdm::WebPage, :count).by(1)
 827      end
 828    end
 829  end
 830
 831  context '#import_msf_web_vuln_element' do
 832    let(:type) do
 833      :vuln
 834    end
 835
 836    let(:web_vuln_attributes) do
 837      FactoryGirl.attributes_for(:exported_web_vuln)
 838    end
 839
 840    subject(:import_msf_web_vuln_element) do
 841      db_manager.import_msf_web_vuln_element(
 842          element,
 843          options,
 844          &notifier
 845      )
 846    end
 847
 848    context 'call to #import_msf_web_element' do
 849      it_should_behave_like 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization'
 850
 851      context 'specialization return' do
 852        let(:element) do
 853          document.root
 854        end
 855
 856        let(:source) do
 857          xml.web_vuln do
 858            xml.blame(
 859                web_vuln_attributes.fetch(:blame)
 860            )
 861            xml.category(
 862                web_vuln_attributes.fetch(:category)
 863            )
 864            xml.confidence(
 865                web_vuln_attributes.fetch(:confidence)
 866            )
 867            xml.description(
 868                web_vuln_attributes.fetch(:description)
 869            )
 870            xml.method(
 871                web_vuln_attributes.fetch(:method)
 872            )
 873            xml.name(
 874                web_vuln_attributes.fetch(:name)
 875            )
 876            xml.pname(
 877                web_vuln_attributes.fetch(:pname)
 878            )
 879            xml.proof(
 880                web_vuln_attributes.fetch(:proof)
 881            )
 882            xml.risk(
 883                web_vuln_attributes.fetch(:risk)
 884            )
 885          end
 886
 887          xml.target!
 888        end
 889
 890        it 'should be a Hash' do
 891          with_info do |info|
 892            info.should be_a Hash
 893          end
 894
 895          import_msf_web_vuln_element
 896        end
 897
 898        it 'should include :blame' do
 899          with_info do |info|
 900            info[:blame].should == web_vuln_attributes.fetch(:blame)
 901          end
 902        end
 903
 904        it 'should include :category' do
 905          with_info do |info|
 906            info[:category].should == web_vuln_attributes.fetch(:category)
 907          end
 908        end
 909
 910        it 'should include :confidence' do
 911          with_info do |info|
 912            info[:confidence].should == web_vuln_attributes.fetch(:confidence)
 913          end
 914        end
 915
 916        it 'should include :description' do
 917          with_info do |info|
 918            info[:description].should == web_vuln_attributes.fetch(:description)
 919          end
 920        end
 921
 922        it 'should include :method' do
 923          with_info do |info|
 924            info[:method].should == web_vuln_attributes.fetch(:method)
 925          end
 926        end
 927
 928        it 'should include :name' do
 929          with_info do |info|
 930            info[:name].should == web_vuln_attributes.fetch(:name)
 931          end
 932        end
 933
 934        it 'should include :pname' do
 935          with_info do |info|
 936            info[:pname].should == web_vuln_attributes.fetch(:pname)
 937          end
 938        end
 939
 940        it 'should include :proof' do
 941          with_info do |info|
 942            info[:proof].should == web_vuln_attributes.fetch(:proof)
 943          end
 944        end
 945
 946        it 'should include :risk' do
 947          with_info do |info|
 948            info[:risk].should == web_vuln_attributes.fetch(:risk)
 949          end
 950        end
 951      end
 952    end
 953
 954    context 'with required attributes' do
 955      include_context 'DatabaseCleaner'
 956
 957      let(:element) do
 958        document.root
 959      end
 960
 961      let(:source) do
 962        xml.web_vuln do
 963          xml.category(
 964              web_vuln_attributes.fetch(:category)
 965          )
 966          xml.host(
 967              host_attributes.fetch(:address)
 968          )
 969          xml.method(
 970              web_vuln_attributes.fetch(:method)
 971          )
 972          xml.name(
 973              web_vuln_attributes.fetch(:name)
 974          )
 975
 976          serialized_params = serialize(
 977              web_vuln_attributes.fetch(:params)
 978          )
 979          xml.params(serialized_params)
 980
 981          xml.path(
 982              web_vuln_attributes.fetch(:path)
 983          )
 984          xml.pname(
 985              web_vuln_attributes.fetch(:pname)
 986          )
 987          xml.port(
 988              service_attributes.fetch(:port)
 989          )
 990          xml.proof(
 991              web_vuln_attributes.fetch(:proof)
 992          )
 993          xml.risk(
 994              web_vuln_attributes.fetch(:risk)
 995          )
 996
 997          ssl = false
 998
 999          if service_attributes[:name] == 'https'
1000            ssl = true
1001          end
1002
1003          xml.ssl(ssl)
1004        end
1005
1006        xml.target!
1007      end
1008
1009      it 'should create an Mdm::WebVuln' do
1010        expect {
1011          import_msf_web_vuln_element
1012        }.to change(Mdm::WebVuln, :count).by(1)
1013      end
1014    end
1015  end
1016
1017  context '#import_msf_xml' do
1018    let(:data) do
1019      '<MetasploitV4/>'
1020    end
1021
1022    subject(:import_msf_xml) do
1023      db_manager.import_msf_xml(:data => data)
1024    end
1025
1026    it 'should call #check_msf_xml_version!' do
1027      db_manager.should_receive(:check_msf_xml_version!).and_call_original
1028
1029      import_msf_xml
1030    end
1031
1032    context 'with web_forms/web_form elements' do
1033      include_context 'DatabaseCleaner'
1034
1035      let(:data) do
1036        xml.tag!('MetasploitV4') do
1037          xml.web_forms do
1038            xml.web_form do
1039              xml.host(
1040                  host_attributes.fetch(:address)
1041              )
1042              xml.method(
1043                  web_form_attributes.fetch(:method)
1044              )
1045              xml.path(
1046                  web_form_attributes.fetch(:path)
1047              )
1048              xml.port(
1049                  service_attributes.fetch(:port)
1050              )
1051
1052              ssl = false
1053
1054              if service_attributes[:name] == 'https'
1055                ssl = true
1056              end
1057
1058              xml.ssl(ssl)
1059            end
1060          end
1061        end
1062
1063        xml.target!
1064      end
1065
1066      it 'should call #import_msf_web_form_element' do
1067        db_manager.should_receive(:import_msf_web_form_element).and_call_original
1068
1069        import_msf_xml
1070      end
1071    end
1072
1073    context 'with web_pages/web_page elements' do
1074      include_context 'DatabaseCleaner'
1075
1076      let(:data) do
1077        xml.tag!('MetasploitV4') do
1078          xml.web_pages do
1079            xml.web_page do
1080              xml.body(
1081                  web_page_attributes.fetch(:body)
1082              )
1083              xml.code(
1084                  web_page_attributes.fetch(:code)
1085              )
1086
1087              serialized_headers = serialize(
1088                  web_page_attributes.fetch(:headers)
1089              )
1090              xml.headers(serialized_headers)
1091
1092              xml.host(
1093                  host_attributes.fetch(:address)
1094              )
1095              xml.path(
1096                  web_page_attributes.fetch(:headers)
1097              )
1098              xml.port(
1099                  service_attributes.fetch(:port)
1100              )
1101              xml.query(
1102                  web_page_attributes.fetch(:query)
1103              )
1104
1105              ssl = false
1106
1107              if service_attributes[:name] == 'https'
1108                ssl = true
1109              end
1110
1111              xml.ssl(ssl)
1112            end
1113          end
1114        end
1115
1116        xml.target!
1117      end
1118
1119      it 'should call #import_msf_web_page_element' do
1120        db_manager.should_receive(:import_msf_web_page_element).and_call_original
1121
1122        import_msf_xml
1123      end
1124    end
1125
1126    context 'with web_vulns/web_vuln elements' do
1127      include_context 'DatabaseCleaner'
1128
1129      let(:data) do
1130        xml.tag!('MetasploitV4') do
1131          xml.web_vulns do
1132            xml.web_vuln do
1133              xml.category(web_vuln.category)
1134
1135              service = web_vuln.web_site.service
1136              xml.host(service.host.address)
1137
1138              xml.method(web_vuln.method)
1139              xml.name(web_vuln.name)
1140
1141              serialized_params = serialize(web_vuln.params)
1142              xml.params(serialized_params)
1143
1144              xml.path(web_vuln.path)
1145              xml.pname(web_vuln.pname)
1146              xml.port(service.port)
1147              xml.proof(web_vuln.proof)
1148
1149              ssl = false
1150
1151              if service.name == 'https'
1152                ssl = true
1153              end
1154
1155              xml.ssl(ssl)
1156            end
1157          end
1158        end
1159
1160        xml.target!
1161      end
1162
1163      let(:web_vuln) do
1164        FactoryGirl.create(:mdm_web_vuln)
1165      end
1166
1167      it 'should call #import_msf_web_vuln_element' do
1168        db_manager.should_receive(:import_msf_web_vuln_element).and_call_original
1169
1170        import_msf_xml
1171      end
1172    end
1173  end
1174end