Develop the right mindset for Rails security
Avoid shipping vulnerable code by learning how to prevent security issues in your Rails applications.
Get the course for $99I love Ruby and it is my goto scripting language. Even in the age of AI, I like to write short custom scripts for my tool arsenal. One way to find subdomains of a potential hacking target is to initiate a DNS zone transfer. You can use various shell tools for this, but if it is part of a process(my case), it might be easier and more flexible to just script it in Ruby. I decided to use the dnsruby gem to save some work, otherwise I would need to do a TCP connection to the nameservers myself. For the sake of demonstration, I converted my script into a command line one, that will accept 2 parameters, the host and an optional IP address of a nameserver:
domain = ARGV[0] or abort "You have to specify a domain"
nameservers = [ARGV[1]].compact
zone = domain.chomp('.').downcase
The next step is to fetch the nameservers if there wasn’t one provided:
resolver = Dnsruby::Resolver.new
if nameservers.empty?
nameservers = resolver.query(zone, Dnsruby::Types.NS).answer
.select { |rr| rr.type == Dnsruby::Types.NS }
.map { |rr| rr.nsdname.to_s }
.uniq
end
abort "No NS records found for #{zone}" if nameservers.empty?
Dnsruby makes this really simple, it has a Resolver class and constants to query
for various records, in this case we are looking for the NS records of the
domain.
Once we have the nameservers, we want to try a zone transfer on each of them:
nameservers.each do |ns|
puts "\n== Trying zone transfer from #{ns} =="
begin
transfer = Dnsruby::ZoneTransfer.new
transfer.server = ns
records = transfer.transfer(zone)
puts "Transferred #{records.size} records"
records.each do |rr|
name = rr.name.to_s.chomp('.').downcase
next if name == zone
next unless name.end_with?(".#{zone}")
subdomains << name
end
rescue => e
warn "Failed from #{ns}: #{e.message}"
end
end
puts "\nSubdomains found:"
puts subdomains.uniq.sort
This is again, very simple with this gem, we can just create a ZoneTransfer class, set the nameserver we want t arget and call the transfer method. In case of success, we get the records and we can loop over them to find the subdomains. That’s it, pretty simple and beautiful Ruby.