Skip to content

Commit fedf112

Browse files
committed
added cidr support
1 parent 1ee476e commit fedf112

File tree

2 files changed

+101
-24
lines changed

2 files changed

+101
-24
lines changed

pkg/runner/runner.go

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package runner
33
import (
44
"bufio"
55
"fmt"
6-
"io"
76
"os"
87
"path"
8+
"sync"
99

1010
"github.com/projectdiscovery/naabu/pkg/scan"
1111
"github.com/remeh/sizedwaitgroup"
@@ -18,6 +18,7 @@ type Runner struct {
1818
scanner *scan.Scanner
1919

2020
ports map[int]struct{}
21+
wg sync.WaitGroup
2122
}
2223

2324
// NewRunner creates a new runner struct instance by parsing
@@ -44,9 +45,17 @@ func (r *Runner) RunEnumeration() error {
4445
return fmt.Errorf("could not parse ports: %s", err)
4546
}
4647

48+
targets := make(chan string)
49+
// start listener
50+
r.wg.Add(1)
51+
go r.EnumerateMultipleHosts(targets, ports)
52+
4753
// Check if only a single host is sent as input. Process the host now.
4854
if r.options.Host != "" {
49-
r.EnumerateSingleHost(r.options.Host, ports, r.options.Output, false)
55+
targets <- r.options.Host
56+
close(targets)
57+
58+
r.wg.Wait()
5059
return nil
5160
}
5261

@@ -56,47 +65,78 @@ func (r *Runner) RunEnumeration() error {
5665
if err != nil {
5766
return err
5867
}
59-
r.EnumerateMultipleHosts(f, ports)
60-
f.Close()
68+
defer f.Close()
69+
70+
scanner := bufio.NewScanner(f)
71+
for scanner.Scan() {
72+
targets <- scanner.Text()
73+
}
74+
75+
close(targets)
76+
77+
r.wg.Wait()
6178
return nil
6279
}
6380

6481
// If we have STDIN input, treat it as multiple hosts
6582
if r.options.Stdin {
66-
r.EnumerateMultipleHosts(os.Stdin, ports)
83+
scanner := bufio.NewScanner(os.Stdin)
84+
for scanner.Scan() {
85+
targets <- scanner.Text()
86+
}
87+
88+
close(targets)
89+
90+
r.wg.Wait()
6791
}
6892
return nil
6993
}
7094

7195
// EnumerateMultipleHosts enumerates hosts for ports.
7296
// We keep enumerating ports for a given host until we reach an error
73-
func (r *Runner) EnumerateMultipleHosts(reader io.Reader, ports map[int]struct{}) {
74-
scanner := bufio.NewScanner(reader)
97+
func (r *Runner) EnumerateMultipleHosts(targets chan string, ports map[int]struct{}) {
98+
defer r.wg.Done()
99+
75100
swg := sizedwaitgroup.New(r.options.Threads)
76101

77-
for scanner.Scan() {
78-
host := scanner.Text()
102+
for host := range targets {
79103
if host == "" {
80104
continue
81105
}
82106

83-
swg.Add()
84-
go func(host string) {
85-
// If the user has specifed an output file, use that output file instead
86-
// of creating a new output file for each domain. Else create a new file
87-
// for each domain in the directory.
88-
if r.options.Output != "" {
89-
r.EnumerateSingleHost(host, ports, r.options.Output, true)
90-
} else if r.options.OutputDirectory != "" {
91-
outputFile := path.Join(r.options.OutputDirectory, host)
92-
r.EnumerateSingleHost(host, ports, outputFile, false)
93-
} else {
94-
r.EnumerateSingleHost(host, ports, "", true)
107+
// Check if the host is a cidr
108+
if scan.IsCidr(host) {
109+
ips, err := scan.Ips(host)
110+
if err != nil {
111+
return
112+
}
113+
114+
for _, ip := range ips {
115+
swg.Add()
116+
go r.handleHost(&swg, ip, ports)
95117
}
96-
swg.Done()
97-
}(host)
118+
119+
} else {
120+
swg.Add()
121+
go r.handleHost(&swg, host, ports)
122+
}
98123
}
124+
99125
swg.Wait()
126+
}
100127

101-
return
128+
func (r *Runner) handleHost(swg *sizedwaitgroup.SizedWaitGroup, host string, ports map[int]struct{}) {
129+
defer swg.Done()
130+
131+
// If the user has specifed an output file, use that output file instead
132+
// of creating a new output file for each domain. Else create a new file
133+
// for each domain in the directory.
134+
if r.options.Output != "" {
135+
r.EnumerateSingleHost(host, ports, r.options.Output, true)
136+
} else if r.options.OutputDirectory != "" {
137+
outputFile := path.Join(r.options.OutputDirectory, host)
138+
r.EnumerateSingleHost(host, ports, outputFile, false)
139+
} else {
140+
r.EnumerateSingleHost(host, ports, "", true)
141+
}
102142
}

pkg/scan/util.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package scan
2+
3+
import "net"
4+
5+
// IsCidr determines if the given ip is a cidr range
6+
func IsCidr(ip string) bool {
7+
_, _, err := net.ParseCIDR(ip)
8+
if err != nil {
9+
return false
10+
}
11+
12+
return true
13+
}
14+
15+
// Ips of a cidr
16+
func Ips(cidr string) ([]string, error) {
17+
ip, ipnet, err := net.ParseCIDR(cidr)
18+
if err != nil {
19+
return nil, err
20+
}
21+
22+
var ips []string
23+
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
24+
ips = append(ips, ip.String())
25+
}
26+
// remove network address and broadcast address
27+
return ips[1 : len(ips)-1], nil
28+
}
29+
30+
func inc(ip net.IP) {
31+
for j := len(ip) - 1; j >= 0; j-- {
32+
ip[j]++
33+
if ip[j] > 0 {
34+
break
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)