Initial commit

This commit is contained in:
Dionysus 2023-09-21 01:10:10 -04:00
parent 6346e38928
commit d3369d868f
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
3 changed files with 258 additions and 2 deletions

15
LICENSE Normal file
View File

@ -0,0 +1,15 @@
ISC License
Copyright (c) 2023, acidvegas <acid.vegas@acid.vegas>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@ -1,2 +1,53 @@
# massrdns
dynamic reverse dns lookup with rotating servers
# MASSRDNS
## Reverse DNS Lookup Tool
This tool provides an efficient way to perform reverse DNS lookups on IP addresses, especially useful for large IP ranges. It uses concurrent workers and distributes the work among them to achieve faster results.
### Building the Project
1. Clone the repository:
```
git clone https://github.com/acidvegas/massrns
cd massrdns
```
2. Build the project:
```
go build -o massrdns
```
This will produce an executable named `massrdns`.
### Usage
The tool requires two main arguments:
- `-cidr`: The IP address CIDR range you want to perform reverse DNS lookup on.
- `-dnsfile`: The path to a file containing DNS servers, one per line.
Optional arguments:
- `-concurrency`: The number of concurrent workers for reverse DNS lookup. Default is 10.
Example:
```
./rdns_lookup -cidr "192.168.0.0/24" -dnsfile "dns_servers.txt"
```
### DNS Servers File Format
The file should contain one DNS server per line, e.g.:
```
8.8.8.8:53
1.1.1.1:53
```
___
###### Mirrors
[acid.vegas](https://git.acid.vegas/massrdns) • [GitHub](https://github.com/acidvegas/massrdns) • [GitLab](https://gitlab.com/acidvegas/massrdns) • [SuperNETs](https://git.supernets.org/acidvegas/massrdns)

190
massrdns.go Normal file
View File

@ -0,0 +1,190 @@
package main
import (
"bufio"
"context"
"flag"
"fmt"
"math/rand"
"net"
"os"
"strconv"
"strings"
"sync"
"time"
)
var dnsServers []string
func loadDNSServersFromFile(filePath string) error {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
server := scanner.Text()
// Check if the server contains a port
if strings.Contains(server, ":") {
host, port, err := net.SplitHostPort(server)
if err != nil {
return fmt.Errorf("invalid IP:port format for %s", server)
}
if net.ParseIP(host) == nil {
return fmt.Errorf("invalid IP address in %s", server)
}
if _, err := strconv.Atoi(port); err != nil {
return fmt.Errorf("invalid port in %s", server)
}
} else {
if net.ParseIP(server) == nil {
return fmt.Errorf("invalid IP address %s", server)
}
server += ":53" // Default to port 53 if not specified
}
dnsServers = append(dnsServers, server)
}
return scanner.Err()
}
func reverseDNSLookup(ip string, server string) string {
ctx := context.Background()
resolver := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{}
return d.DialContext(ctx, network, server)
},
}
names, err := resolver.LookupAddr(ctx, ip)
if err != nil {
return fmt.Sprintf("%s | %s | Error: %s", time.Now().Format("03:04:05 PM"), server, err)
}
if len(names) == 0 {
return fmt.Sprintf("%s | %s | No PTR records", time.Now().Format("03:04:05 PM"), server)
}
return fmt.Sprintf("%s | %s | %s", time.Now().Format("03:04:05 PM"), server, names[0])
}
func worker(cidr *net.IPNet, resultsChan chan string) {
for ip := make(net.IP, len(cidr.IP)); copy(ip, cidr.IP) != 0; incrementIP(ip) {
if !cidr.Contains(ip) {
break
}
randomServer := dnsServers[rand.Intn(len(dnsServers))]
result := reverseDNSLookup(ip.String(), randomServer)
resultsChan <- result
}
}
func splitCIDR(cidr string, parts int) ([]*net.IPNet, error) {
ip, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
maskSize, _ := ipNet.Mask.Size()
newMaskSize := maskSize
for ; (1 << uint(newMaskSize-maskSize)) < parts; newMaskSize++ {
if newMaskSize > 32 {
return nil, fmt.Errorf("too many parts; cannot split further")
}
}
var subnets []*net.IPNet
for i := 0; i < parts; i++ {
subnets = append(subnets, &net.IPNet{
IP: ip,
Mask: net.CIDRMask(newMaskSize, 32),
})
incrementIPBy(ip, 1<<uint(32-newMaskSize))
}
return subnets, nil
}
func main() {
var cidr string
var concurrency int
var dnsFile string
flag.StringVar(&cidr, "cidr", "", "IP address CIDR to perform reverse DNS lookup")
flag.IntVar(&concurrency, "concurrency", 10, "Number of concurrent workers for reverse DNS lookup")
flag.StringVar(&dnsFile, "dnsfile", "", "Path to the file containing DNS servers (one per line)")
flag.Parse()
if cidr == "" || dnsFile == "" {
fmt.Println("Please provide a CIDR using the -cidr flag and a DNS servers file with the -dnsfile flag.")
os.Exit(1)
}
if err := loadDNSServersFromFile(dnsFile); err != nil {
fmt.Printf("Error reading DNS servers from file %s: %s\n", dnsFile, err)
os.Exit(1)
}
if len(dnsServers) == 0 {
fmt.Println("No DNS servers found in the provided file.")
os.Exit(1)
}
rand.Seed(time.Now().UnixNano())
subnets, err := splitCIDR(cidr, concurrency*10) // Create more subnets than workers
if err != nil {
fmt.Printf("Error splitting CIDR: %s\n", err)
os.Exit(1)
}
// Create a channel to feed CIDR blocks to workers
cidrChan := make(chan *net.IPNet, len(subnets))
for _, subnet := range subnets {
cidrChan <- subnet
}
close(cidrChan) // Close it, so workers can detect when there's no more work
resultsChan := make(chan string, concurrency*2) // Increased buffer size for results
var wg sync.WaitGroup
for i := 0; i < concurrency; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for subnet := range cidrChan { // Keep working until there's no more work
worker(subnet, resultsChan)
}
}()
}
go func() {
wg.Wait()
close(resultsChan)
}()
for result := range resultsChan {
fmt.Println(result)
}
}
func incrementIP(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func incrementIPBy(ip net.IP, count int) {
for count > 0 {
incrementIP(ip)
count--
}
}