Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Verify

# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
actions: none
checks: none
contents: none
deployments: none
id-token: none
issues: none
discussions: none
packages: none
pages: none
pull-requests: none
repository-projects: none
security-events: none
statuses: none

on:
push:
branches:
- '*'
pull_request:
branches:
- '*'

jobs:
build:
uses: rapid7/metasploit-framework/.github/workflows/shared_gem_verify.yml@master
39 changes: 4 additions & 35 deletions lib/rex/elfscan/scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,9 @@ def config(param)
regexstr += "\xff[#{calls}]|"
end

# Adapting to Regexp.new's New Signature in Ruby 3.3+
regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = regexstr.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(regexstr, nil, 'n')
end

self.regex = Regexp.new(regexstr, Regexp::NOENCODING)
end

# build a list for regex of the possible bytes, based on a base
Expand Down Expand Up @@ -165,18 +156,7 @@ class PopPopRetScanner < JmpRegScanner

def config(param)
pops = _build_byte_list(0x58, (0 .. 7).to_a - [4]) # we don't want pop esp's...
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = "[#{pops}][#{pops}](\xc3|\xc2..)"
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)", Regexp::NOENCODING)
end

def scan_segment(program_header, param={})
Expand Down Expand Up @@ -211,18 +191,7 @@ def scan_segment(program_header, param={})
class RegexScanner < JmpRegScanner

def config(param)
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = param['args']
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
self.regex = Regexp.new(param['args'], Regexp::NOENCODING)
end

def scan_segment(program_header, param={})
Expand Down
39 changes: 4 additions & 35 deletions lib/rex/machscan/scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,9 @@ def config(param)
regexstr += "\xff[#{calls}]|"
end

# Adapting to Regexp.new's New Signature in Ruby 3.3+
regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = regexstr.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(regexstr, nil, 'n')
end

self.regex = Regexp.new(regexstr, Regexp::NOENCODING)
end

# build a list for regex of the possible bytes, based on a base
Expand Down Expand Up @@ -154,18 +145,7 @@ class PopPopRetScanner < JmpRegScanner

def config(param)
pops = _build_byte_list(0x58, (0 .. 7).to_a - [4]) # we don't want pop esp's...
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = "[#{pops}][#{pops}](\xc3|\xc2..)"
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)", Regexp::NOENCODING)
end

def scan_segment(segment, param={})
Expand Down Expand Up @@ -201,18 +181,7 @@ def scan_segment(segment, param={})
class RegexScanner < JmpRegScanner

def config(param)
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = param['args']
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
self.regex = Regexp.new(param['args'], Regexp::NOENCODING)
end

def scan_segment(segment, param={})
Expand Down
18 changes: 3 additions & 15 deletions lib/rex/pescan/analyze.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,9 @@ def scan(param)

@sigs.each_pair do |name, data|
begin
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = '^' + data[0]
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
if (buf.match(regex))
$stdout.puts param['file'] + ": " + name
end
if (buf.match(Regexp.new('^' + data[0], Regexp::NOENCODING)))
$stdout.puts param['file'] + ": " + name
end
rescue RegexpError
$stderr.puts "Invalid signature: #{name} #{data[0]}"
end
Expand Down
39 changes: 4 additions & 35 deletions lib/rex/pescan/scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,9 @@ def config(param)
regexstr += "\xff[#{calls}]|"
end

# Adapting to Regexp.new's New Signature in Ruby 3.3+
regexstr += "\xff[#{jmps}]|([#{pushs1}]|\xff[#{pushs2}])(\xc3|\xc2..))"
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = regexstr.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(regexstr, nil, 'n')
end

self.regex = Regexp.new(regexstr, Regexp::NOENCODING)
end

# build a list for regex of the possible bytes, based on a base
Expand Down Expand Up @@ -170,18 +161,7 @@ class PopPopRetScanner < JmpRegScanner

def config(param)
pops = _build_byte_list(0x58, (0 .. 7).to_a - [4]) # we don't want pop esp's...
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = "[#{pops}][#{pops}](\xc3|\xc2..)"
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
self.regex = Regexp.new("[#{pops}][#{pops}](\xc3|\xc2..)", Regexp::NOENCODING)
end

def scan_section(section, param={})
Expand Down Expand Up @@ -215,18 +195,7 @@ def scan_section(section, param={})
class RegexScanner < Generic

def config(param)
# Adapting to Regexp.new's New Signature in Ruby 3.3+
pattern = param['args']
# Choose initialization method based on Ruby version
major, minor, _patch = RUBY_VERSION.split('.').map(&:to_i)
self.regex = if (major > 3) || (major == 3 && minor >= 3)
# For Ruby 3.3+: explicitly mark as binary pattern and use NOENCODING
binary_pattern = pattern.b
Regexp.new(binary_pattern, Regexp::NOENCODING)
else
# For Ruby <= 3.2: use legacy three-argument syntax
Regexp.new(pattern, nil, 'n')
end
self.regex = Regexp.new(param['args'], Regexp::NOENCODING)
end

def scan_section(section, param={})
Expand Down
48 changes: 48 additions & 0 deletions spec/lib/rex/elfscan/scanner_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- coding:binary -*-
require 'spec_helper'

require 'rex/elfscan/scanner'
require 'rex/elfparsey'

RSpec.describe Rex::ElfScan::Scanner do
let(:elf) { instance_double(Rex::ElfParsey::Elf) }

describe Rex::ElfScan::Scanner::JmpRegScanner do
subject { described_class.new(elf) }

describe '#config' do
it 'creates a regex with NOENCODING for jmp reg patterns' do
param = { 'args' => [0, 1, 2, 3, 5, 6, 7] }
expect { subject.config(param) }.not_to raise_error
expect(subject.regex).to be_a(Regexp)
expect(subject.regex.encoding).to eq(Encoding::ASCII_8BIT)
end
end
end

describe Rex::ElfScan::Scanner::PopPopRetScanner do
subject { described_class.new(elf) }

describe '#config' do
it 'creates a regex with NOENCODING for pop pop ret patterns' do
param = {}
expect { subject.config(param) }.not_to raise_error
expect(subject.regex).to be_a(Regexp)
expect(subject.regex.encoding).to eq(Encoding::ASCII_8BIT)
end
end
end

describe Rex::ElfScan::Scanner::RegexScanner do
subject { described_class.new(elf) }

describe '#config' do
it 'creates a regex with NOENCODING from user-supplied pattern' do
param = { 'args' => '\xcc' }
expect { subject.config(param) }.not_to raise_error
expect(subject.regex).to be_a(Regexp)
expect(subject.regex.encoding).to eq(Encoding::ASCII_8BIT)
end
end
end
end
48 changes: 48 additions & 0 deletions spec/lib/rex/machscan/scanner_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- coding:binary -*-
require 'spec_helper'

require 'rex/machparsey'
require 'rex/machscan/scanner'

RSpec.describe Rex::MachScan::Scanner do
let(:mach) { instance_double(Rex::MachParsey::Mach) }

describe Rex::MachScan::Scanner::JmpRegScanner do
subject { described_class.new(mach) }

describe '#config' do
it 'creates a regex with NOENCODING for jmp reg patterns' do
param = { 'args' => [0, 1, 2, 3, 5, 6, 7] }
expect { subject.config(param) }.not_to raise_error
expect(subject.regex).to be_a(Regexp)
expect(subject.regex.encoding).to eq(Encoding::ASCII_8BIT)
end
end
end

describe Rex::MachScan::Scanner::PopPopRetScanner do
subject { described_class.new(mach) }

describe '#config' do
it 'creates a regex with NOENCODING for pop pop ret patterns' do
param = {}
expect { subject.config(param) }.not_to raise_error
expect(subject.regex).to be_a(Regexp)
expect(subject.regex.encoding).to eq(Encoding::ASCII_8BIT)
end
end
end

describe Rex::MachScan::Scanner::RegexScanner do
subject { described_class.new(mach) }

describe '#config' do
it 'creates a regex with NOENCODING from user-supplied pattern' do
param = { 'args' => '\xcc' }
expect { subject.config(param) }.not_to raise_error
expect(subject.regex).to be_a(Regexp)
expect(subject.regex.encoding).to eq(Encoding::ASCII_8BIT)
end
end
end
end
33 changes: 33 additions & 0 deletions spec/lib/rex/pescan/analyze_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding:binary -*-
require 'spec_helper'

require 'rex/pescan/analyze'
require 'rex/peparsey'

RSpec.describe Rex::PeScan::Analyze::Fingerprint do
let(:opt) { double('opt', AddressOfEntryPoint: 0) }
let(:hdr) { double('hdr', opt: opt) }
let(:pe) { instance_double(Rex::PeParsey::Pe, hdr: hdr, read_rva: "MZ\x90\x00".b) }

subject { described_class.new(pe) }

let(:param) do
{
'database' => File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'data', 'identify.txt'),
'file' => 'test.exe'
}
end

describe '#config' do
it 'loads signatures from the database without error' do
expect { subject.config(param) }.not_to raise_error
end
end

describe '#scan' do
it 'matches signatures using Regexp with NOENCODING after config' do
subject.config(param)
expect { subject.scan(param) }.not_to raise_error
end
end
end
Loading
Loading