@@ -2,7 +2,6 @@ package scan
22
33import (
44 "fmt"
5- "io"
65 "math"
76 "math/rand"
87 "net"
@@ -12,9 +11,9 @@ import (
1211
1312 "github.com/google/gopacket"
1413 "github.com/google/gopacket/layers"
15- "github.com/google/gopacket/pcap"
1614 "github.com/phayes/freeport"
1715 "github.com/projectdiscovery/gologger"
16+ "github.com/remeh/sizedwaitgroup"
1817)
1918
2019// Scanner is a scanner that scans for ports using SYN packets.
@@ -69,48 +68,16 @@ func (s *Scanner) send(conn net.PacketConn, l ...gopacket.SerializableLayer) (in
6968 return conn .WriteTo (buf .Bytes (), & net.IPAddr {IP : s .host })
7069}
7170
72- // Scan scans a single host and returns the results
73- func (s * Scanner ) Scan (wordlist map [int ]struct {}) (map [int ]struct {}, error ) {
74- inactive , err := pcap .NewInactiveHandle (s .networkInterface .Name )
75- if err != nil {
76- return nil , err
77- }
78- inactive .SetSnapLen (65536 )
79-
80- readTimeout := time .Duration (1500 ) * time .Millisecond
81- if err = inactive .SetTimeout (readTimeout ); err != nil {
82- inactive .CleanUp ()
83- return nil , err
84- }
85- inactive .SetImmediateMode (true )
86-
87- handle , err := inactive .Activate ()
71+ // ScanSyn scans a single host and returns the results
72+ func (s * Scanner ) ScanSyn (wordlist map [int ]struct {}) (map [int ]struct {}, error ) {
73+ conn , err := net .ListenPacket ("ip4:tcp" , "0.0.0.0" )
8874 if err != nil {
89- inactive .CleanUp ()
9075 return nil , err
9176 }
77+ defer conn .Close ()
9278
9379 rawPort , err := freeport .GetFreePort ()
9480 if err != nil {
95- handle .Close ()
96- inactive .CleanUp ()
97- return nil , err
98- }
99-
100- // Strict BPF filter
101- // + Packets coming from target ip
102- // + Destination port equals to sender socket source port
103- err = handle .SetBPFFilter (fmt .Sprintf ("tcp and port %d and ip host %s" , rawPort , s .host ))
104- if err != nil {
105- handle .Close ()
106- inactive .CleanUp ()
107- return nil , err
108- }
109-
110- conn , err := net .ListenPacket ("ip4:tcp" , "0.0.0.0" )
111- if err != nil {
112- handle .Close ()
113- inactive .CleanUp ()
11481 return nil , err
11582 }
11683
@@ -155,53 +122,35 @@ func (s *Scanner) Scan(wordlist map[int]struct{}) (map[int]struct{}, error) {
155122
156123 tasksWg := & sync.WaitGroup {}
157124 tasksWg .Add (1 )
158- ipFlow := gopacket .NewFlow (layers .EndpointIPv4 , s .host , s .srcIP )
159125
160126 go func () {
161- var (
162- eth layers.Ethernet
163- ip4 layers.IPv4
164- tcp layers.TCP
165- parser * gopacket.DecodingLayerParser
166- )
167-
168- if s .networkInterface .HardwareAddr != nil {
169- // Interfaces with MAC (Physical + Virtualized)
170- parser = gopacket .NewDecodingLayerParser (layers .LayerTypeEthernet , & eth , & ip4 , & tcp )
171- } else {
172- // Interfaces without MAC (TUN/TAP)
173- parser = gopacket .NewDecodingLayerParser (layers .LayerTypeIPv4 , & ip4 , & tcp )
174- }
175-
176- decoded := []gopacket.LayerType {}
127+ defer tasksWg .Done ()
128+ data := make ([]byte , 4096 )
177129 for {
178- data , _ , err := handle . ReadPacketData ( )
179- if err == io . EOF {
130+ n , addr , err := conn . ReadFrom ( data )
131+ if err != nil {
180132 break
181- } else if err != nil {
182- continue
183133 }
184134
185- if err := parser .DecodeLayers (data , & decoded ); err != nil {
135+ // not matching ip
136+ if addr .String () != s .host .String () {
186137 continue
187138 }
188- for _ , layerType := range decoded {
189- switch layerType {
190- case layers .LayerTypeIPv4 :
191- if ip4 .NetworkFlow () != ipFlow {
192- continue
193- }
194- case layers .LayerTypeTCP :
195- // We consider only incoming packets
196- if tcp .DstPort != layers .TCPPort (rawPort ) {
197- continue
198- } else if tcp .SYN && tcp .ACK {
199- openChan <- int (tcp .SrcPort )
200- }
139+
140+ packet := gopacket .NewPacket (data [:n ], layers .LayerTypeTCP , gopacket .Default )
141+ if tcpLayer := packet .Layer (layers .LayerTypeTCP ); tcpLayer != nil {
142+ tcp , ok := tcpLayer .(* layers.TCP )
143+ if ! ok {
144+ continue
145+ }
146+ // We consider only incoming packets
147+ if tcp .DstPort != layers .TCPPort (rawPort ) {
148+ continue
149+ } else if tcp .SYN && tcp .ACK {
150+ openChan <- int (tcp .SrcPort )
201151 }
202152 }
203153 }
204- tasksWg .Done ()
205154 }()
206155
207156 limiter := time .Tick (time .Second / time .Duration (s .rate ))
@@ -233,20 +182,69 @@ func (s *Scanner) Scan(wordlist map[int]struct{}) (map[int]struct{}, error) {
233182 // Just like masscan, wait for 10 seconds for further packets
234183 if s .timeout > 0 {
235184 timer := time .AfterFunc (10 * time .Second , func () {
236- handle .Close ()
237185 conn .Close ()
238186 })
239187 defer timer .Stop ()
240188 } else {
241- handle .Close ()
242189 conn .Close ()
243190 }
244191
245192 tasksWg .Wait ()
246193 close (openChan )
247194 resultsWg .Wait ()
248195
249- inactive .CleanUp ()
196+ return results , nil
197+ }
198+
199+ // ScanConnect a single host and returns the results
200+ func (s * Scanner ) ScanConnect (wordlist map [int ]struct {}) (map [int ]struct {}, error ) {
201+ openChan := make (chan int )
202+ results := make (map [int ]struct {})
203+ resultsWg := & sync.WaitGroup {}
204+ resultsWg .Add (1 )
205+
206+ go func () {
207+ for open := range openChan {
208+ gologger .Debugf ("Found active port %d on %s\n " , open , s .host .String ())
209+
210+ results [open ] = struct {}{}
211+ }
212+ resultsWg .Done ()
213+ }()
214+
215+ tasksWg := & sync.WaitGroup {}
216+ tasksWg .Add (1 )
217+
218+ ports := make (chan int )
219+ go func () {
220+ defer tasksWg .Done ()
221+
222+ swgscan := sizedwaitgroup .New (s .rate )
223+ for port := range ports {
224+ swgscan .Add ()
225+ go func (port int ) {
226+ defer swgscan .Done ()
227+
228+ conn , err := net .DialTimeout ("tcp" , fmt .Sprintf ("%s:%d" , s .host , port ), s .timeout )
229+ if err != nil {
230+ return
231+ }
232+ defer conn .Close ()
233+
234+ openChan <- port
235+ }(port )
236+ }
237+ swgscan .Wait ()
238+ }()
239+
240+ for port := range wordlist {
241+ ports <- port
242+ }
243+ close (ports )
244+
245+ tasksWg .Wait ()
246+ close (openChan )
247+ resultsWg .Wait ()
250248
251249 return results , nil
252250}
0 commit comments