Class: Rex::Post::Meterpreter::Extensions::Bofloader::CnaParser
- Inherits:
-
Object
- Object
- Rex::Post::Meterpreter::Extensions::Bofloader::CnaParser
- Defined in:
- lib/rex/post/meterpreter/extensions/bofloader/cna_parser.rb
Overview
Statically imports conventional BOF launchers from Aggressor scripts.
Defined Under Namespace
Classes: Error, Unsupported
Constant Summary collapse
- FORMAT_TYPES =
{ 'b' => 'bytes', 'i' => 'int32', 's' => 'int16', 'z' => 'string', 'Z' => 'wstring' }.freeze
- INTEGER_RANGES =
{ 'i' => (-2**31)..(2**31 - 1), 's' => (-2**15)..(2**15 - 1) }.freeze
- REQUIRED_INTRINSICS =
%w[ barch beacon_command_register beacon_inline_execute bof_pack iff openf readb script_resource ].freeze
- NULL =
Object.new.freeze
- PARAMETER_PATTERN =
/\A\$(\d+)\z/- USAGE_MARKER_PATTERN =
/\A(?:(?<optional>optional|opt)|required)(?=\s|:|\z)\s*:?\s*/i- VARIABLE_PATTERN =
/\A\$[a-zA-Z_]\w*\z/
Class Method Summary collapse
-
.parse(path:) ⇒ Hash
Parses an Aggressor script.
Instance Method Summary collapse
-
#initialize(path:) ⇒ CnaParser
constructor
Creates a CNA parser.
-
#parse ⇒ Hash
Returns a normalized catalog of statically supported CNA aliases.
Constructor Details
#initialize(path:) ⇒ CnaParser
Creates a CNA parser.
43 44 45 46 |
# File 'lib/rex/post/meterpreter/extensions/bofloader/cna_parser.rb', line 43 def initialize(path:) @path = path @base_path = ::File.dirname(path) end |
Class Method Details
.parse(path:) ⇒ Hash
Parses an Aggressor script.
36 37 38 |
# File 'lib/rex/post/meterpreter/extensions/bofloader/cna_parser.rb', line 36 def self.parse(path:) new(path: path).parse end |
Instance Method Details
#parse ⇒ Hash
Returns a normalized catalog of statically supported CNA aliases.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/rex/post/meterpreter/extensions/bofloader/cna_parser.rb', line 51 def parse source = read_source @code = remove_comments(source) @subroutines = named_blocks('sub') @overridden_intrinsics = (declared_block_names('sub') + declared_block_names('inline')).uniq & REQUIRED_INTRINSICS aliases = named_blocks('alias') registrations = command_registrations bofs = {} warnings = [] duplicate_aliases = aliases.map(&:first).tally.select { |_name, count| count > 1 }.keys duplicate_aliases.each { |alias_name| warnings << "CNA alias '#{alias_name}' is declared more than once" } aliases.each do |alias_name, body| next if duplicate_aliases.include?(alias_name) next if function_calls(body, 'beacon_inline_execute').empty? begin definition = import_alias(alias_name, body, registrations[alias_name]) bofs[alias_name] = definition rescue Unsupported => e warnings << "CNA alias '#{alias_name}' was skipped: #{e.}" end end if bofs.empty? reason = warnings.first || 'the script does not contain a beacon_inline_execute alias' raise Error, "No compatible BOFs found in CNA script #{@path}: #{reason}" end { 'path' => @path, 'bofs' => bofs, 'warnings' => warnings } end |