@@ -3,9 +3,9 @@ package runner
33import (
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}
0 commit comments