Last active
February 21, 2026 14:22
-
-
Save coderobe/836983ea91bc786fa225adb770a1b356 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| # USAGE: ruby ircd-interrogate.rb example.com:6697 | |
| require 'socket' | |
| require 'openssl' | |
| server, port = ARGV.first.split(":") | |
| port = 6697 if port.nil? | |
| nick = "testnick#{rand(1000)}" | |
| user = "ircv3 capability interrogator" | |
| puts "== \e[34m#{server}\e[0m\n\n" | |
| tcp = TCPSocket.new(server, port) | |
| ssl = OpenSSL::SSL::SSLSocket.new(tcp, OpenSSL::SSL::SSLContext.new) | |
| ssl.hostname = server | |
| ssl.connect | |
| ssl.puts "CAP LS 302\r\nNICK #{nick}\r\nUSER #{user} 0 * :#{user}\r" | |
| caps = [] | |
| isupport = {} | |
| collecting_caps = true | |
| registered = false | |
| version_received = false | |
| while line = ssl.gets | |
| line.chomp! | |
| # Respond to PING | |
| if line =~ /^PING :(.*)/ | |
| ssl.puts "PONG :#{$1}\r" | |
| next | |
| end | |
| # Capture CAP LS | |
| if collecting_caps && line =~ /^:\S+ CAP \* LS (.+)$/ | |
| payload = $1.sub(/^:/, "") | |
| payload = payload[2..] if payload.start_with?("* ") | |
| caps.concat(payload.split) | |
| unless line.include?(" LS * ") | |
| collecting_caps = false | |
| ssl.puts "CAP END\r" | |
| end | |
| next | |
| end | |
| # Capture ISUPPORT (005) tokens sent during registration before 001 | |
| if line =~ /^:\S+ 005 #{nick} (.+) :/ | |
| $1.split.each do |token| | |
| if token.include?("=") | |
| key, value = token.split("=", 2) | |
| isupport[key] = value | |
| else | |
| isupport[token] = true | |
| end | |
| end | |
| next | |
| end | |
| # Registration complete | |
| if line =~ /^:\S+ 001 #{nick} / | |
| registered = true | |
| puts "\e[33m== Capabilities Supported (#{caps.size}) ==\e[0m\n#{caps.sort.join("\n")}\n\n" | |
| ssl.puts "VERSION\r" | |
| next | |
| end | |
| # Capture VERSION reply (351) | |
| if line =~ /^:\S+ 351 #{nick} (.+)/ | |
| # at this point we can check collected isupports | |
| if isupport.any? | |
| puts "\e[33m== ISUPPORT Tokens (#{isupport.size}) ==\e[0m" | |
| isupport.sort.each do |key, value| | |
| if value == true | |
| puts key | |
| else | |
| puts "#{key}=#{value}" | |
| end | |
| end | |
| puts | |
| end | |
| puts "\e[33m== Server Version ==\e[0m\n#{$1}" | |
| version_received = true | |
| end | |
| break if registered && version_received | |
| end | |
| ssl.puts "QUIT\r" | |
| ssl.close | |
| tcp.close |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment