class Dradis::Plugins::Wpscan::Importer

Public Instance Methods

create_node( data ) click to toggle source
# File lib/dradis/plugins/wpscan/importer.rb, line 57
def create_node( data )
  node = content_service.create_node(label: data['target_url'], type: :host)

  # Define Node properties
  if node.respond_to?(:properties)
    node.set_property(:start_url, data['target_url'])
    #node.set_property(:start_time, data['start_time'])
    node.set_property(:scan_time, data['elapsed'])
  end

  scan_info = template_service.process_template(template: 'scan_info', data: data)
  content_service.create_note text: scan_info, node: node

  node
end
import(params={}) click to toggle source

The framework will call this function if the user selects this plugin from the dropdown list and uploads a file. @returns true if the operation was successful, false otherwise

# File lib/dradis/plugins/wpscan/importer.rb, line 6
def import(params={})

  file_content = File.read( params[:file] )

  # Parse the uploaded file into a Ruby Hash
  logger.info { "Parsing WPScan output from #{ params[:file] }..." }
  data = MultiJson.decode(file_content)
  logger.info { 'Done.' }

  # Do a sanity check to confirm the user uploaded the right file
  # format.
  if data['target_url'].nil?
    error = "ERROR: No 'target_url' field present in the provided " \
            "JSON data. Are you sure you uploaded a WPScan JSON output file?"
    logger.fatal { error }
    content_service.create_note text: error
    return false
  end

  # Initial data normalisation
  data = parse_json( data )

  # Create a node based on the target_url
  node = create_node( data )

  # Parse vulnerability data and make more human readable.
  # NOTE: You need an API token for the WPVulnDB vulnerability data.
  parse_known_vulnerabilities( data, node )


  # Add bespoke/config vulnerabilities to Dradis
  #
  # TODO: Can we add severity to issues?
  #
  # Note: No API key needed.
  parse_config_vulnerabilities( data, node )
end
parse_config_vulnerabilities( data, node ) click to toggle source
# File lib/dradis/plugins/wpscan/importer.rb, line 120
def parse_config_vulnerabilities( data, node )
  vulnerabilities = []

  if data['config_backups']
    data['config_backups'].each do |url, value|
      vulnerability = {}
      vulnerability['title']    = 'WordPress Configuration Backup Found'
      vulnerability['evidence'] = url

      vulnerabilities << vulnerability
    end
  end

  if data['db_exports']
    data['db_exports'].each do |url, value|
      vulnerability = {}
      vulnerability['title']    = 'Database Backup File Found'
      vulnerability['evidence'] = url

      vulnerabilities << vulnerability
    end
  end

  if data['timthumbs']
    data['timthumbs'].each do |url, value|
      unless value['vulnerabilities'].empty?
        vulnerability = {}
        vulnerability['title']    = "Timthumb RCE File Found"
        vulnerability['evidence'] = url

        vulnerabilities << vulnerability
      end
    end
  end

  if data['password_attack']
    data['password_attack'].each do |user|
      vulnerability = {}
      vulnerability['title'] = "WordPres Weak User Password Found"
      vulnerability['evidence'] = "#{user[0]}:#{user[1]['password']}"

      vulnerabilities << vulnerability
    end
  end

  # Add WordPress configuration vulnerabilities to Dradis
  vulnerabilities.each do |vulnerability|
    logger.info { "Adding vulnerability: #{vulnerability['title']}" }

    vulnerability_template = template_service.process_template(template: 'vulnerability', data: vulnerability)
    issue = content_service.create_issue(text: vulnerability_template, id: "wpscan_#{rand(999999)}")

    if vulnerability['evidence']
      evidence_content = template_service.process_template(template: 'evidence', data: vulnerability)
      content_service.create_evidence(issue: issue, node: node, content: vulnerability['evidence'])
    end
  end
end
parse_json( data ) click to toggle source
# File lib/dradis/plugins/wpscan/importer.rb, line 44
def parse_json( data )
  # Parse scan info data and make more human readable.
  data['wpscan_version']    = data.dig('banner', 'version')
  data['start_time']        = DateTime.strptime(data['start_time'].to_s,'%s')
  data['elapsed']           = "#{data["elapsed"]} seconds"
  data['wordpress_version'] = data.dig('version', 'number')   if data['version']
  data['plugins_string']    = data['plugins'].keys.join("\n") if data['plugins']
  data['themes_string']     = data['themes'].keys.join("\n")  if data['themes']
  data['users']             = data['users'].keys.join("\n")   if data['users']

  data
end
parse_known_vulnerabilities( data, node ) click to toggle source
# File lib/dradis/plugins/wpscan/importer.rb, line 74
def parse_known_vulnerabilities( data, node )
  vulnerabilities = []

  # WordPress Vulnerabilities
  if data['version'] && data['version']['status'] == 'insecure'
    data['version']['vulnerabilities'].each do |vulnerability_data|
      vulnerabilities << parse_vulnerability( vulnerability_data )
    end
  end

  # Plugin Vulnerabilities
  if data['plugins']
    data['plugins'].each do |key, plugin|
      if plugin['vulnerabilities']
        plugin['vulnerabilities'].each do |vulnerability_data|
          vulnerabilities << parse_vulnerability( vulnerability_data )
        end
      end
    end
  end

  # Theme Vulnerabilities
  if data['themes']
    data['themes'].each do |key, theme|
      if theme['vulnerabilities']
        theme['vulnerabilities'].each do |vulnerability_data|
          vulnerabilities << parse_vulnerability( vulnerability_data )
        end
      end
    end
  end

  # Add vulnerabilities from WPVulnDB to Dradis
  vulnerabilities.each do |vulnerability|
    logger.info { "Adding vulnerability: #{vulnerability['title']}" }

    vulnerability_template = template_service.process_template(template: 'vulnerability', data: vulnerability)
    issue = content_service.create_issue(text: vulnerability_template, id: vulnerability['wpvulndb_id'], node: node)

    if vulnerability['evidence']
      evidence_content = template_service.process_template(template: 'evidence', data: vulnerability)
      content_service.create_evidence(issue: issue, node: node, content: vulnerability['evidence'])
    end
  end
end
parse_vulnerability( vulnerability_data ) click to toggle source
# File lib/dradis/plugins/wpscan/importer.rb, line 179
def parse_vulnerability( vulnerability_data )
  wpvulndb_url = 'https://wpvulndb.com/vulnerabilities/'

  vulnerability = {}
  vulnerability['title']        = vulnerability_data['title']
  vulnerability['fixed_in']     = vulnerability_data['fixed_in'] if vulnerability_data['fixed_in']
  vulnerability['cve']          = 'CVE-' + vulnerability_data['references']['cve'][0] if vulnerability_data['references']['cve']
  vulnerability['url']          = vulnerability_data['references']['url'].join("\n") if vulnerability_data['references']['url']
  vulnerability['wpvulndb_url'] = wpvulndb_url + vulnerability_data['references']['wpvulndb'][0]
  vulnerability['wpvulndb_id']  = vulnerability_data['references']['wpvulndb'][0]

  vulnerability
end