module Dawn module Kb class RubyVersionCheck include BasicCheck # Array of hashes in the {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p342"} form attr_accessor :safe_rubies # Hash in the {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p342"} form attr_accessor :detected_ruby def vuln? vv_a = [] vv_p = [] vv_e = [] vp = false ve = false @safe_rubies.each do |ss| vv_e << ss[:engine] vv_a << ss[:version] vv_p << ss[:patchlevel].split("p")[1].to_i end version_check = Dawn::Kb::VersionCheck.new(:safe=>vv_a,:detected=>detected_ruby[:version], :debug=>@debug, :save_major=>true) vengine = self.is_vulnerable_engine?(detected_ruby[:engine], vv_e) vv = version_check.vuln? ve = self.is_same_version?(detected_ruby[:version], vv_a) vp = is_vulnerable_patchlevel?(detected_ruby[:version], detected_ruby[:patchlevel]) debug_verbosely("#{__FILE__}@#{__LINE__}: check: #{self.name}, engine is vulnerable?=#{vengine}, version is vulnerable?=#{vv}, is same version?=#{ve}, is_vulnerable_patchlevel?=#{vp}->#{vv && vengine}, #{(ve && vp && vengine )}") debug_verbosely("#{__FILE__}@#{__LINE__}: safe ruby is: #{@safe_rubies}") debug_verbosely("#{__FILE__}@#{__LINE__}: detected ruby is: #{@detected_ruby}") if ( vv && vengine) @status = vp if ve @status = true unless ve else @status = (ve && vp && vengine ) end debug_verbosely("STATUS:#{@status}") self.evidences << "#{@detected_ruby[:engine]} v#{@detected_ruby[:version]}-#{@detected_ruby[:patchlevel]} detected" if @status return @status # return true if ( vv && vengine ) # return (ve && vp && vengine ) end def is_vulnerable_engine?(target, fixes = []) fixes.each do |f| return true if f == target end false end def is_same_version?(target, fixes = []) fixes.each do |f| debug_verbosely("F=#{f}, TARGET=#{target}") return true if f == target end false end def is_vulnerable_patchlevel?(version, patchlevel) fixes = [] debug_verbosely "is_vulnerable_patchlevel? called with VERSION=#{version} and PLEVEL=#{patchlevel}" @safe_rubies.each do |ss| fixes << ss[:patchlevel].split("p")[1].to_i if ss[:version] == version end debug_verbosely "FIXES IS EMPTY" if fixes.empty? debug_verbosely "FIXES LIST IS #{fixes}" unless fixes.empty? return true if fixes.empty? t = patchlevel.split("p")[1].to_i if patchlevel.include? 'p' t = patchlevel.to_i unless patchlevel.include? 'p' fixes.each do |f| debug_verbosely "PATCHLEVEL FIXES = #{f}, PATCHLEVEL TARGET = #{t}" return true if f > t end false end end end end