Skip to content

Commit

Permalink
Land #65, Add .is_name? And Strengthen .is_ip_addr? Validation
Browse files Browse the repository at this point in the history
  • Loading branch information
adfoster-r7 authored Feb 14, 2024
2 parents 97c2871 + 564dede commit b06fe01
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 4 deletions.
20 changes: 16 additions & 4 deletions lib/rex/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ def self.create_ip(opts = {})
# Common Regular Expressions
#

# see: https://debugpointer.com/regex/regex-for-dns-name
MATCH_DNS_NAME = /^(((?!-))(xn--)?([a-z0-9][a-z0-9\-]{0,59})?[a-z0-9]\.)*(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/i

MATCH_IPV6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/

MATCH_IPV4 = /^\s*(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))\s*$/
Expand Down Expand Up @@ -125,24 +128,33 @@ def self.support_ipv6?
# Cache our resolver
@@resolver = nil

#
# Determine whether this is a valid DNS name without trying to resolve it
#
def self.is_name?(name)
return false if name.length > 253
name =~ MATCH_DNS_NAME ? (name =~ /\s/).nil? : false
end

#
# Determine whether this is an IPv4 address
#
def self.is_ipv4?(addr)
addr =~ MATCH_IPV4 ? true : false
addr =~ MATCH_IPV4 ? (addr =~ /\s/).nil? : false
end

#
# Determine whether this is an IPv6 address
#
def self.is_ipv6?(addr)
addr =~ MATCH_IPV6 ? true : false
addr =~ MATCH_IPV6 ? (addr =~ /\s/).nil? : false
end

#
# Determine whether this is a MAC address
#
def self.is_mac_addr?(addr)
!(addr =~ MATCH_MAC_ADDR).nil?
addr =~ MATCH_MAC_ADDR ? (addr =~ /\s/).nil? : false
end

#
Expand All @@ -157,7 +169,7 @@ def self.is_ip_addr?(addr)
# Checks to see if the supplied address is in "dotted" form
#
def self.dotted_ip?(addr)
(support_ipv6? && addr =~ MATCH_IPV6) || (addr =~ MATCH_IPV4)
(support_ipv6? && self.is_ipv6?(addr)) || self.is_ipv4?(addr)
end

# Checks to see if an address is an IPv6 address and if so, converts it into its
Expand Down
76 changes: 76 additions & 0 deletions spec/rex/socket_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@
end
end

context 'with multiple IPv4 addresses' do
context 'separated by newlines' do
let(:try) { "127.0.0.1\n127.0.0.1" }
it 'should return false' do
expect(addr).to eq false
end
end

context 'separated by spaces' do
let(:try) { "127.0.0.1 127.0.0.1" }
it 'should return false' do
expect(addr).to eq false
end
end
end

context 'with an IPv6 address' do
let(:try) { '::1' }
it 'should return false' do
Expand Down Expand Up @@ -283,6 +299,22 @@
end
end

context 'with multiple IPv6 addresses' do
context 'separated by newlines' do
let(:try) { "::1\n::1" }
it 'should return false' do
expect(addr).to eq false
end
end

context 'separated by spaces' do
let(:try) { "::1 ::1" }
it 'should return false' do
expect(addr).to eq false
end
end
end

context 'with a hostname' do
let(:try) { "localhost" }
it "should return false" do
Expand All @@ -297,4 +329,48 @@
end
end
end

describe '.is_name?' do
subject(:name) do
described_class.is_name?(try)
end

context 'with a hostname' do
let(:try) { "localhost" }
it "should return true" do
expect(name).to eq true
end
end

context 'with a fully qualified domain name' do
let(:try) { "www.metasploit.com" }
it "should return true" do
expect(name).to eq true
end
end

context 'with multiple fully qualified domain names' do
context 'separated by newlines' do
let(:try) { "www.metasploit.com\nmetasploit.com" }
it 'should return false' do
expect(name).to eq false
end
end

context 'separated by spaces' do
let(:try) { "www.metasploit.com metasploit.com" }
it 'should return false' do
expect(name).to eq false
end
end
end

context 'international domain names' do
# 搾取の translation: of exploitation (metasploit)
let(:try) { "xn--u9jw97h8hl.com" }
it 'should return true' do
expect(name).to eq true
end
end
end
end

0 comments on commit b06fe01

Please sign in to comment.