Skip to content

Commit

Permalink
UDP scan
Browse files Browse the repository at this point in the history
  • Loading branch information
v-byte-cpu committed Mar 24, 2021
1 parent 991a7f8 commit 8af3359
Show file tree
Hide file tree
Showing 8 changed files with 533 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Features:
* TCP SYN scan
* TCP FIN / NULL / Xmas scans
* Custom TCP scans with any TCP flags
* UDP scan

## Building

Expand Down
60 changes: 60 additions & 0 deletions command/udp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package command

import (
"context"
"errors"
"os"
"os/signal"
"runtime"
"strings"

"github.com/spf13/cobra"
"github.com/v-byte-cpu/sx/pkg/scan"
"github.com/v-byte-cpu/sx/pkg/scan/arp"
"github.com/v-byte-cpu/sx/pkg/scan/icmp"
"github.com/v-byte-cpu/sx/pkg/scan/udp"
)

func init() {
udpCmd.Flags().StringVarP(&cliPortsFlag, "ports", "p", "", "set ports to scan")
rootCmd.AddCommand(udpCmd)
}

var udpCmd = &cobra.Command{
Use: "udp [flags] subnet",
Example: strings.Join([]string{"udp -p 22 192.168.0.1/24", "udp -p 22-4567 10.0.0.1"}, "\n"),
Short: "Perform UDP scan",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return errors.New("requires one ip subnet argument")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()

var conf *scanConfig
if conf, err = parseScanConfig(udp.ScanType, args[0], cliPortsFlag); err != nil {
return
}

m := newUDPScanMethod(ctx, conf)

return startEngine(ctx, &engineConfig{
logger: conf.logger,
scanRange: conf.scanRange,
scanMethod: m,
bpfFilter: icmp.BPFFilter,
})
},
}

func newUDPScanMethod(ctx context.Context, conf *scanConfig) *udp.ScanMethod {
reqgen := arp.NewCacheRequestGenerator(
scan.RequestGeneratorFunc(scan.Requests), conf.gatewayIP, conf.cache)
pktgen := scan.NewPacketMultiGenerator(udp.NewPacketFiller(), runtime.NumCPU())
psrc := scan.NewPacketSource(reqgen, pktgen)
results := scan.NewResultChan(ctx, 1000)
return udp.NewScanMethod(psrc, results)
}
18 changes: 18 additions & 0 deletions pkg/scan/icmp/bpf.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package icmp

import (
"fmt"

"github.com/v-byte-cpu/sx/pkg/scan"
)

// Set to typical maximum Ethernet frame size = MTU (1500 bytes)
// + Ethernet header (14 bytes) + FCS (4 bytes)
const MaxPacketLength = 1518

func BPFFilter(r *scan.Range) (filter string, maxPacketLength int) {
if r.DstSubnet == nil {
return "icmp", MaxPacketLength
}
return fmt.Sprintf("icmp and ip src net %s", r.DstSubnet.String()), MaxPacketLength
}
43 changes: 43 additions & 0 deletions pkg/scan/icmp/bpf_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package icmp

import (
"net"
"testing"

"github.com/stretchr/testify/assert"
"github.com/v-byte-cpu/sx/pkg/scan"
)

func TestBPFFilter(t *testing.T) {
t.Parallel()

tests := []struct {
name string
scanRange *scan.Range
expectedFilter string
}{
{
name: "EmptySubnet",
expectedFilter: "icmp",
scanRange: &scan.Range{},
},
{
name: "OneSubnet",
scanRange: &scan.Range{
DstSubnet: &net.IPNet{
IP: net.IPv4(192, 168, 0, 0),
Mask: net.CIDRMask(24, 32),
},
},
expectedFilter: "icmp and ip src net 192.168.0.0/24",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
filter, maxPacketLength := BPFFilter(tt.scanRange)
assert.Equal(t, tt.expectedFilter, filter)
assert.Equal(t, maxPacketLength, MaxPacketLength)
})
}
}
6 changes: 6 additions & 0 deletions pkg/scan/icmp/icmp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package icmp

type Response struct {
Type uint8
Code uint8
}
161 changes: 161 additions & 0 deletions pkg/scan/udp/result_easyjson.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8af3359

Please sign in to comment.