From f2b92c0b3f4654f034bfef4416c789b9ce95d691 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Fri, 9 Feb 2024 11:25:02 -0500 Subject: [PATCH 1/4] Add tests for multiple IP addresses --- spec/rex/socket_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/rex/socket_spec.rb b/spec/rex/socket_spec.rb index 3d2d3af..018ce10 100644 --- a/spec/rex/socket_spec.rb +++ b/spec/rex/socket_spec.rb @@ -242,6 +242,13 @@ end end + context 'with multiple IPv4 addresses' do + let(:try) { "127.0.0.1\n127.0.0.1" } + it 'should return false' do + expect(addr).to eq false + end + end + context 'with an IPv6 address' do let(:try) { '::1' } it 'should return false' do @@ -283,6 +290,13 @@ end end + context 'with multiple IPv6 addresses' do + let(:try) { "::1\n::1" } + it 'should return false' do + expect(addr).to eq false + end + end + context 'with a hostname' do let(:try) { "localhost" } it "should return false" do From 32d16b9871889011ed732279ae95f640e9dd26da Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Fri, 9 Feb 2024 11:39:53 -0500 Subject: [PATCH 2/4] Add the is_name? class function with tests --- lib/rex/socket.rb | 19 ++++++++--- spec/rex/socket_spec.rb | 74 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/lib/rex/socket.rb b/lib/rex/socket.rb index 5c139b5..2997873 100644 --- a/lib/rex/socket.rb +++ b/lib/rex/socket.rb @@ -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,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/im + 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*$/ @@ -125,24 +128,32 @@ 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) + 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 # @@ -157,7 +168,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 diff --git a/spec/rex/socket_spec.rb b/spec/rex/socket_spec.rb index 018ce10..6fe9488 100644 --- a/spec/rex/socket_spec.rb +++ b/spec/rex/socket_spec.rb @@ -243,9 +243,18 @@ end context 'with multiple IPv4 addresses' do - let(:try) { "127.0.0.1\n127.0.0.1" } - it 'should return false' do - expect(addr).to eq false + 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 @@ -291,9 +300,18 @@ end context 'with multiple IPv6 addresses' do - let(:try) { "::1\n::1" } - it 'should return false' do - expect(addr).to eq false + 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 @@ -311,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 false" do + expect(name).to eq false + 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 From 764718bf3dd397c0a5ecc41ee0874d826e9c9144 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Fri, 9 Feb 2024 14:49:23 -0500 Subject: [PATCH 3/4] Fix the DNS name regex --- lib/rex/socket.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/rex/socket.rb b/lib/rex/socket.rb index 2997873..7fd2665 100644 --- a/lib/rex/socket.rb +++ b/lib/rex/socket.rb @@ -85,7 +85,7 @@ def self.create_ip(opts = {}) # # see: https://debugpointer.com/regex/regex-for-dns-name - MATCH_DNS_NAME = /^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/im + 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*$/ @@ -132,6 +132,7 @@ def self.support_ipv6? # 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 From 564dede6a4de7791ab807f1cdff43d74e27d34b4 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Fri, 9 Feb 2024 15:47:18 -0500 Subject: [PATCH 4/4] Hostnames return true as well --- spec/rex/socket_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/rex/socket_spec.rb b/spec/rex/socket_spec.rb index 6fe9488..f2c9ca0 100644 --- a/spec/rex/socket_spec.rb +++ b/spec/rex/socket_spec.rb @@ -337,8 +337,8 @@ context 'with a hostname' do let(:try) { "localhost" } - it "should return false" do - expect(name).to eq false + it "should return true" do + expect(name).to eq true end end