Skip to content

Commit

Permalink
tweaks for ruclei succes
Browse files Browse the repository at this point in the history
  • Loading branch information
jcran committed Sep 7, 2021
1 parent 0468849 commit 1568acc
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 57 deletions.
4 changes: 2 additions & 2 deletions app/api/v1/entity.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class CoreApp < Sinatra::Base

post "/api/v1/entity" do

content_type "application/json"

halt_unless_authenticated!

# For post requests with a json body, just stick it in params
# don't clobber params, stick it in its own object
json = get_json_body
Expand Down
3 changes: 2 additions & 1 deletion core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@
require_relative 'lib/initialize/hash'
require_relative 'lib/initialize/json_export_file'
require_relative 'lib/initialize/queue'
require_relative 'lib/initialize/resolv'
require_relative 'lib/initialize/sidekiq_profiler'
require_relative 'lib/initialize/string'
require_relative 'lib/initialize/symbol'
require_relative 'lib/initialize/typhoeus'
require_relative 'lib/initialize/resolv'

# load up our system config
require_relative 'lib/system/config'
Expand Down
5 changes: 4 additions & 1 deletion lib/checks/atlassian_confluence_cve_2021_26084.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ def self.check_metadata
def check
# run a nuclei
uri = _get_entity_name
_log "Running on #{uri}"

template = 'cves/2021/CVE-2021-26084'

# if this returns truthy value, an issue will be raised
# the truthy value will be added as proof to the issue
run_nuclei_template uri, template
run_nuclei_template uri, template
end

end
end
end
6 changes: 6 additions & 0 deletions lib/initialize/symbol.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Monkeypatch symbol to handle an encode method (that does nothing)
class Symbol
def encode(a,b)
self
end
end
83 changes: 42 additions & 41 deletions lib/issue_factory.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
#
#
# First, a simple factory interface
#
module Intrigue
module Issue
class IssueFactory

#
# Register a new handler
#
def self.register(klass)
@issue_types = [] unless @issue_types
@issue_types << klass if klass
end

#
# Provide the full list of issues
#
def self.issues
@issue_types
end

#
# Provide the full list of issues
#
def self.issue_by_type(name)
x = self.issues.find{|x| x if x.generate({})[:name] == name }
x.generate({}) if x
x.generate({}) if x
end

#
# Returns an issue name if the check matches a inference:[CVE_ID]
#
def self.get_issue_by_cve_identifier(cve_id)
self.issues.each do |h|
self.issues.each do |h|
# generate the instances
issue_metadata = h.generate({})
next unless issue_metadata[:identifiers]
Expand All @@ -42,61 +42,61 @@ def self.get_issue_by_cve_identifier(cve_id)
end
false
end

#
# Provide the full list of issues, given a
# Provide the full list of issues, given a
#
def self.issues_for_vendor_product(vendor,product)

### First, get all issues with their affected software
mapped_issues = []
self.issues.each do |h|
self.issues.each do |h|
# generate the instances
hi = h.generate({});
hi = h.generate({});
# then geet all instaces of affected software with issues names
as = (hi[:affected_software] || [])
mapped_issues << as.map{|x| x.merge({ :name => hi[:name] }) }
end

mapped_issues.flatten.select{|x| x[:vendor] == vendor && x[:product] == product}.map{|x| x[:name] }.uniq.compact
end

#
# Provide the full list of issues, given a vendor, product
#
def self.checks_for_vendor_product(vendor,product)

### First, get all issues with their affected software
mapped_issues = []
self.issues.each do |h|
# generate the instances
hi = h.generate({});
# then get all instaces of affected software with issues names
as = (hi[:affected_software] || [])

# first check to see if there's an explicit task specified in the issue
# and if there's not default to the name of the issue (it's probably a check and
# ... checks are automatically named by their issue thanks to introspection magic)
# and if there's not default to the name of the issue (it's probably a check and
# ... checks are automatically named by their issue thanks to introspection magic)
mapped_issues << as.map{|x| x.merge({ check_name: (hi[:task]||hi[:name]) }) }
end


## pull out only items that have an affected software that matches our
## passed-in vendor / product and only return the name of the task/check to be run
## pull out only items that have an affected software that matches our
## passed-in vendor / product and only return the name of the task/check to be run
checks = mapped_issues.flatten.select{|x| x[:vendor] == vendor && x[:product] == product}.map{|x| x[:check_name] }
# return only those checks that actually exist. this is due to the magical
# nature of how we select tasks above - which might mean that we pulled in an
# issue that did not have a corresponding check or task

# return only those checks that actually exist. this is due to the magical
# nature of how we select tasks above - which might mean that we pulled in an
# issue that did not have a corresponding check or task
checks.map{|x| x if Intrigue::TaskFactory.include?(x) }.compact.uniq
end

#
# Find issue based on check value
#
def self.find_issue_by_check(check)
self.issues.each do |h|

self.issues.each do |h|
# generate the instances
hi = h.generate({});
if hi[:check] == check
Expand All @@ -105,16 +105,16 @@ def self.find_issue_by_check(check)
end
nil
end


#
# Check to see if this handler exists (check by type)
#
def self.include?(name)
@issue_types.each { |h| return true if "#{h.generate({})[:name]}" == "#{name}" }
false
end

#
# create_by_type(type)
#
Expand All @@ -125,26 +125,27 @@ def self.include?(name)
# - A handler, which you can call generate on
#
def self.create_instance_by_type(requested_type, issue_model_details, instance_specifics={})

# first look thorugh our issue types and get the right one
issue_type = self.issues.select{ |h| h.generate({})[:name] == requested_type }.first
unless issue_type
unless issue_type
raise "Unknown issue type: #{requested_type}"
return
end

issue_instance_details = issue_type.generate(instance_specifics)

# add in the fields we want to use when querying...

sanitized_details = instance_specifics.sanitize_unicode
issue_instance_details = issue_type.generate(sanitized_details)

# add in the fields we want to use when querying...
issue_model = issue_model_details.merge({
name: issue_instance_details[:name],
source: issue_instance_details[:source]
})

# then create the darn thing
issue = Intrigue::Core::Model::Issue.update_or_create(issue_model)
# save the specifics

# save the specifics
issue.description = issue_type.generate({})[:description]
issue.pretty_name = issue_instance_details[:pretty_name]
issue.status = issue_instance_details[:status]
Expand All @@ -154,10 +155,10 @@ def self.create_instance_by_type(requested_type, issue_model_details, instance_s
issue.references = issue_type.generate({})[:references]
issue.details = issue_instance_details
issue.save_changes

issue
end

end
end
end
35 changes: 23 additions & 12 deletions lib/tasks/helpers/vuln_check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def matches_fingerprint_metadata?(fingerprint, value_to_match, type)
# function to compare version_a with version_b according to given operator.
# will try to parse both parameters with versionomy. if parsing fails, it will compare them as string literals.
def compare_versions_by_operator(version_a, version_b, operator)

# try to parse via versionomy
begin
parsed_a = Versionomy.parse(version_a.scan(/\d\.?+/).join(''))
Expand Down Expand Up @@ -68,16 +68,27 @@ def run_nuclei_template(uri, template)
_log "Running #{template} against #{uri}"
begin
ruclei = Ruclei::Ruclei.new
ruclei.load_template("data/nuclei-templates/#{template}.yaml")
ruclei.load_template("#{$intrigue_basedir}/data/nuclei-templates/#{template}.yaml")
res = ruclei.run(uri)
return { proof: res.results } unless res.nil?
rescue Errno::ENOENT # cannot find template

# if we got a result, let's return it!
if res
proof_hash = { # construct a hash with safe details
proof: {
url: res.url,
template_info: res.template_info
}
}
return proof_hash
end

rescue Ruclei::Exceptions::MissingTemplateError # cannot find template
_log_error 'ERROR: Cannot find template at specified path.'
rescue Psych::SyntaxError # non-yaml file passed
rescue Ruclei::Exceptions::InvalidTemplateError
_log_error 'ERROR: Specified template does not appear to be in YAML format.'
end
return nil

nil
end

def run_nuclei_template_from_string(uri, template_string)
Expand All @@ -88,11 +99,11 @@ def run_nuclei_template_from_string(uri, template_string)
ruclei.parse_template template_string
res = ruclei.run(uri)
return { proof: res.results } unless res.nil?
rescue Psych::SyntaxError # non-yaml file passed
rescue Ruclei::Exceptions::InvalidTemplateError
_log_error 'ERROR: Specified template does not appear to be in YAML format.'
end

return nil
nil
end


Expand Down Expand Up @@ -129,13 +140,13 @@ def get_update_for_vendor_product(entity, vendor, product)
end

def fingerprint_to_inference_issues(fingerprint)
fingerprint.each do |fp|
fingerprint.each do |fp|
next unless fp["vulns"]
fp["vulns"].each do |vuln|
# get and create the issue here
# get and create the issue here
issue_metadata = Intrigue::Issue::IssueFactory.get_issue_by_cve_identifier(vuln["cve"])
next unless issue_metadata

# if we have an issue who has that cve as an identifiger, run the check task
task_name = issue_metadata[:task] || issue_metadata[:name]
start_task("task_autoscheduled", @project, @task_result.scan_result_id, task_name, @entity, 1)
Expand Down

0 comments on commit 1568acc

Please sign in to comment.