# # ronin-exploits - A Ruby library for ronin-rb that provides exploitation and # payload crafting functionality. # # Copyright (c) 2007-2022 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/command' require 'ronin/exploits/root' require 'ronin/payloads/cli/generator/payload_types' require 'ronin/core/cli/options/values/arches' require 'ronin/core/cli/options/values/oses' require 'ronin/core/cli/generator' require 'ronin/core/cli/generator/options/author' require 'ronin/core/cli/generator/options/summary' require 'ronin/core/cli/generator/options/description' require 'ronin/core/cli/generator/options/reference' require 'ronin/core/git' require 'command_kit/inflector' module Ronin module Exploits class CLI module Commands # # Creates a new exploit file. # # ## Usage # # ronin-exploit new [options] FILE # # ## Options # # -t exploit|heap_overflow|stack_overflow|web|open_redirect|lfi|rfi|sqli|ssti|xss, # --type The type for the new exploit # -a, --author NAME The name of the author # -e, --author-email EMAIL The email address of the author # -s, --summary TEXT One sentence summary # -d, --description TEXT A longer description # -I CVE-YYYY-NNNN|GHSA-XXXXX|..., Add the advisory ID to the exploit # --advisory-id # -R, --reference URL Adds a reference URL # -P payload|asm|shellcode|c|shell|powershell|html|javascript|typpescript|java|sql|php|nodejs, # --has-payload The payload type the exploit uses # -N remote_tcp|remote_udp|http, The networking mixin to use # --networking # -A x86|x86-64|amd64|ia64|ppc|ppc64|arm|armbe|arm64|arm64be|mips|mipsle|mips64|mips64le, # --arch The architecture to target # -O linux|macos|windows|freebsd|openbsd|netbsd, # --os The Operating System (OS) to target # --os-version VERSION The OS version to target # -S, --software NAME The software to target # -V, --software-version ARCH The software version to target # -L, --loot Adds the loot mixin # -h, --help Print help information # # ## Arguments # # FILE The path to the new exploit file. # class New < Command include Core::CLI::Generator include Payloads::CLI::Generator EXPLOIT_TYPES = { exploit: { file: 'exploit', class: 'Exploit' }, heap_overflow: { file: 'heap_overflow', class: 'HeapOverflow' }, stack_overflow: { file: 'stack_overflow', class: 'StackOverflow' }, seh_overflow: { file: 'seh_overflow', class: 'SEHOverflow' }, user_after_free: { file: 'use_after_free', class: 'UseAfterFree' }, web: { file: 'web', class: 'Web' }, lfi: { file: 'lfi', class: 'LFI' }, rfi: { file: 'rfi', class: 'RFI' }, sqli: { file: 'sqli', class: 'SQLI' }, ssti: { file: 'ssti', class: 'SSTI' }, xss: { file: 'xss', class: 'XSS' } } NETWORKING_TYPES = { remote_tcp: { file: 'remote_tcp', module: 'RemoteTCP' }, remote_udp: { file: 'remote_udp', module: 'RemoteUDP' }, http: { file: 'http', module: 'HTTP' } } template_dir File.join(ROOT,'data','new') usage '[options] FILE' option :type, short: '-t', value: { type: EXPLOIT_TYPES.keys.compact }, desc: 'The type for the new exploit' do |type| @exploit_type = EXPLOIT_TYPES.fetch(type) end include Core::CLI::Generator::Options::Author include Core::CLI::Generator::Options::Summary include Core::CLI::Generator::Options::Description option :advisory_id, short: '-I', value: { type: String, usage: 'CVE-YYYY-NNNN|GHSA-XXXXX|...' }, desc: 'Add the advisory ID to the exploit' do |id| @advisories << id end include Core::CLI::Generator::Options::Reference option :has_payload, short: '-P', value: {type: PAYLOAD_TYPES.keys}, desc: 'The payload type the exploit uses' do |type| @has_payload = PAYLOAD_TYPES.fetch(type) end option :networking, short: '-N', value: { type: NETWORKING_TYPES.keys }, desc: 'The networking mixin to use' do |type| @networking = type @networking_mixin = NETWORKING_TYPES.fetch(type) end option :arch, short: '-A', value: { type: Core::CLI::Options::Values::ARCHES }, desc: 'The architecture to target' do |arch| @target ||= {} @target[:arch] = arch end option :os, short: '-O', value: { type: Core::CLI::Options::Values::OSES }, desc: 'The Operating System (OS) to target' do |os| @target ||= {} @target[:os] = os end option :os_version, value: { type: String, usage: 'VERSION' }, desc: 'The OS version to target' do |ver| @target ||= {} @target[:os_version] = ver end option :software, short: '-S', value: { type: String, usage: 'NAME' }, desc: 'The software to target' do |name| @target ||= {} @target[:software] = name end option :software_version, short: '-V', value: { type: String, usage: 'ARCH' }, desc: 'The software version to target' do |ver| @target ||= {} @target[:version] = ver end option :loot, short: '-L', desc: 'Adds the loot mixin' do @loot = true end argument :file, desc: 'The path to the new exploit file' description 'Creates a new exploit file' man_page 'ronin-exploits-new.1' # # Initialies the `ronin-exploits new` command. # # @param [Hash{Symbol => Object}] kwargs # Additional keyword arguments. # def initialize(**kwargs) super(**kwargs) @exploit_type = EXPLOIT_TYPES.fetch(:exploit) @advisories = [] end # # Runs the `ronin-exploits new` command. # # @param [String] file # The path to the new exploit file. # def run(file) @file_name = File.basename(file,File.extname(file)) @class_name = CommandKit::Inflector.camelize(@file_name) erb "exploit.rb.erb", file chmod '+x', file end # # Formats a Hash into Ruby keyword arguments. # # @param [Hash{Symbol => Object}] kwargs # # @return [String] # def format_kwargs(kwargs) args = [] kwargs.each do |key,value| args << "#{key}: #{value.inspect}" end return args.join(', ') end # Web exploit class names. WEB_VULN_EXPLOITS = %w[LFI RFI SQLI] # # Determines if the exploit type is `stack_overflow`. # # @return [Boolean] # def stack_overflow_exploit? @exploit_type[:class] == 'StackOverflow' end # # Determines if the exploit type is `seh_overflow`. # # @return [Boolean] # def seh_overflow_exploit? @exploit_type[:class] == 'SEHOverflow' end # # Determines if the exploit type is a web vuln exploit. # # @return [Boolean] # def web_vuln_exploit? WEB_VULN_EXPLOITS.include?(@exploit_type[:class]) end end end end end end