# frozen_string_literal: true # # ronin-exploits - A Ruby library for ronin-rb that provides exploitation and # payload crafting functionality. # # Copyright (c) 2007-2023 Hal Brodigan (postmodern.mod3 at gmail.com) # # ronin-exploits is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # ronin-exploits is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with ronin-exploits. If not, see . # require 'ronin/exploits/cli/exploit_command' require 'ronin/payloads/cli/printing' require 'ronin/core/cli/printing/metadata' require 'ronin/core/cli/printing/arch' require 'ronin/core/cli/printing/os' require 'ronin/core/cli/printing/params' require 'ronin/core/metadata/version' require 'command_kit/printing/fields' module Ronin module Exploits class CLI module Commands # # Prints information about an exploit. # # ## Usage # # ronin-exploits show [options] {NAME | --file FILE} # # ## Options # # -f, --file FILE The exploit file to load # -v, --verbose Enables verbose output # -h, --help Print help information # # ## Arguments # # [NAME] The exploit name to load # class Show < ExploitCommand include Core::CLI::Printing::Metadata include Core::CLI::Printing::Arch include Core::CLI::Printing::OS include Core::CLI::Printing::Params include CommandKit::Printing::Fields include Payloads::CLI::Printing description 'Prints information about an exploit' man_page 'ronin-exploits-show.1' # # Runs the `ronin-exploits show` command. # # @param [String] name # The optional name of the exploit to load and print metadata about. # def run(name=nil) super(name) print_exploit(exploit_class) end # # Prints the exploit class'es metadata. # # @param [Class] exploit # The loaded exploit class. # def print_exploit(exploit) puts "[ #{exploit.id} ]" puts indent do print_metadata(exploit) print_advisories(exploit) print_authors(exploit) print_description(exploit) print_references(exploit) if defined?(Mixins::HasTargets) && exploit.include?(Mixins::HasTargets) unless exploit.targets.empty? exploit.targets.each_with_index do |target,index| puts "[ Target ##{index + 1} ]" puts indent { print_target(target) } end end end print_shouts(exploit) end print_params(exploit) end # # Print the main metadata fields for the exploit. # # @param [Class] exploit # The loaded exploit class. # def print_metadata(exploit) fields = { 'Type' => exploit_type(exploit) } if defined?(Core::Metadata::Version) && exploit.include?(Core::Metadata::Version) fields['Version'] = exploit.version if exploit.version end fields['Quality'] = exploit.quality if exploit.quality fields['Released'] = exploit.release_date if exploit.release_date fields['Disclosed'] = exploit.disclosure_date if exploit.disclosure_date if defined?(Metadata::Arch) && exploit.include?(Metadata::Arch) if (arch = target.arch) fields['Arch'] = arch end end if defined?(Metadata::OS) && exploit.include?(Metadata::OS) if (os = exploit.os) fields['OS'] = if (os_version = exploit.os_version) "#{os} #{os_version}" else os end end end if (software = exploit.software) fields['Software'] = software end if (versions = exploit.software_versions) case versions when Array fields['Software Versions'] = versions.join(', ') when Range fields['Software Versions'] = "#{versions.begin} - #{versions.end}" end end if defined?(Mixins::HasPayload) && exploit.include?(Mixins::HasPayload) fields['Payload Type'] = payload_type(exploit.payload_class) end fields['Summary'] = exploit.summary if exploit.summary print_fields(fields) end # # Prints any advisories defined by an exploit class. # # @param [Class] exploit # The loaded exploit class. # def print_advisories(exploit) unless exploit.advisories.empty? puts "Advisories:" puts indent do exploit.advisories.each do |advisory| print_advisory(advisory) end end puts end end # # Prints the shouts section. # # @param [Class] exploit # The loaded exploit class. # def print_shouts(exploit) if defined?(Metadata::Shouts) && exploit.include?(Metadata::Shouts) puts "Shouts: #{exploit.shouts.join(', ')}" end end # Known exploit types and their printable names. EXPLOIT_TYPES = { exploit: 'Custom', # memory corruption exploits memory_corruption: 'Memory Corruption', stack_overflow: 'Stack Overflow', seh_overflow: 'SEH Overflow', heap_overflow: 'Heap Overflow', use_after_free: 'Use After Free', # web exploits web: 'Web', lfi: 'Local File Inclusion (LFI)', rfi: 'Remote File Inclusion (RFI)', sqli: 'SQL injection (SQLI)', xss: 'Cross-Site Scripting (XSS)', open_redirect: 'Open Redirect', ssti: 'Server-Side Template Injection (SSTI)' } # # Returns the printable exploit type for the exploit class. # # @param [Class] exploit_class # # @return [String] # def exploit_type(exploit_class) EXPLOIT_TYPES.fetch(exploit_class.exploit_type,'unknown') end # # Prints an advisory. # # @param [Advisory] advisory # The advisory to print. # def print_advisory(advisory) if advisory.url then puts "* #{advisory.id} (#{advisory.url})" else puts "* #{advisory.id}" end end # # Prints an exploit target. # # @param [Target] target # A target defined on the exploit. # def print_target(target) fields = {} fields['Arch'] = target.arch if target.arch if target.os fields['OS'] = if target.os_version "#{target.os} #{target.os_version}" else target.os end end if target.software fields['Software'] = if target.software_version "#{target.software} #{target.software_version}" else target.software end end print_fields(fields) if verbose? unless target.empty? puts "Params:" indent { print_fields(target.to_h) } end end puts end end end end end end