portscan

package module
v0.5.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2019 License: BSD-3-Clause Imports: 30 Imported by: 1

README

Build Status Go Report Card GitHub release GitHub license

TCPScan

TCPScan is a simple utility for discovering open (or closed) TCP ports on servers. It uses gopacket(https://github.com/google/gopacket) to craft SYN packets, listening asynchronously for (SYN-)ACK or RST responses without completing the full TCP handshake. TCPScan uses goroutines for asynchronous scans and it searches for the most likely listening ports first, using NMap's "port frequency" ordering. Anecdotal results show that TCPScan is fast!

TCPScan is not a replacement for the awesome NMap tool, but it promises to be a useful library for go applications that need a fast and simple TCP port scanning capability.

Using it as a command-line tool

TCPScan is also available as a command-line tool.

Installation

Prebuilt binaries may be found for your operating system here: https://github.com/adedayo/tcpscan/releases

For macOS X, you could install via brew as follows:

brew tap adedayo/tap
brew install tcpscan
Scanning CIDR ranges
tcpscan 192.168.2.5/30 10.11.12.13/31

For JSON-formatted output simply add the --json or -j flag:

tcpscan --json 192.168.2.5/30 10.11.12.13/31

Depending on the fidelity of the network being scanned or the size of CIDR ranges, it may be expedient to adjust the scan timeout accordingly with the --timeout or -t flag, which indicates the number of seconds to wait for ACK or RST responses as follows:

tcpscan --json --timeout 5 192.168.2.5/30 10.11.12.13/31

Note that scans generally run faster with shorter timeouts, but you may be sacrificing accuracy on slow networks or for large CIDR ranges.

Command line options
Usage:
  tcpscan [flags]

Examples:
tcpscan 8.8.8.8/32 10.10.10.1/30

Flags:
  -h, --help                                               help for tcpscan
  -j, --json                                               generate JSON output
  -q, --quiet                                              control whether to produce a running commentary of intermediate results or stay quiet till the end
  -r, --rate int                                           the rate (in packets per second) that we should send SYN scan packets. This influences overall scan time, but be careful not to overwhelm your network (default 1000)
  -s, --service string[="data/config/TCPScanConfig.yml"]   run tcpscan as a service (default "data/config/TCPScanConfig.yml")
  -t, --timeout int                                        TIMEOUT (in seconds) to adjust how much we are willing to wait for servers to come back with responses. Smaller timeout sacrifices accuracy for speed (default 5)
      --version                                            version for tcpscan

Using TCPScan as a library

In order to start, go get this repository:

go get github.com/adedayo/tcpscan
Example

In your code simply import as usual and enjoy:

package main

import 
(
    "fmt"
    "github.com/adedayo/tcpscan"
)

func main() {
	cidr := "8.8.8.8/32"
	config := portscan.ScanConfig {
		Timeout: 5,
	}
	result := portscan.ScanCIDR(config, cidr)
	for ack := range result {
         fmt.Printf("%s:\tPort %s(%s) is %s\n", ack.Host, ack.Port, ack.GetServiceName(), status(ack))
    }
}

func status(ack portscan.PortACK) string {
	if ack.IsClosed() {
		return "Closed"
	}
	if ack.IsOpen() {
		return "Open"
	}
	return "of Unknown Status"
}

This should produce an output similar to the following:

8.8.8.8:        Port 443(https) is Open
8.8.8.8:        Port 53(domain) is Open
8.8.8.8:        Port 853(domain-s) is Open

An issue on macOS

You may encounter errors such as

panic: en0: You don't have permission to capture on that device ((cannot open BPF device) /dev/bpf0: Permission denied)

Fix the permission problem permanently by using the "Wireshark" approach of pre-allocating /dev/bpf*, and changing their permissions so that the admin group can read from and write packets to the devices. I have provided the fix-bpf-permissions.sh script to simplify the steps, you can run it as shown below. It will ask for your password for the privileged part of the script, but read the script to satisfy yourself that you trust what it is doing! You care about security, right?

curl -O https://raw.githubusercontent.com/adedayo/tcpscan/master/fix-bpf-permissions.sh
chmod +x fix-bpf-permissions.sh
./fix-bpf-permissions.sh  

You should be good to go! You may need to reboot once, but this works across reboots. Note that this is a common problem for tools such as Wireshark, TCPDump etc. that need to read from or write to /dev/bpf*. This solution should fix the problem for all of them - the idea was actually stolen from Wireshark with some modifications :-).

Running as non-root on Linux

You ideally want to be able to run tcpscan as an ordinary user, say, my_user, but since tcpscan sends raw packets you need to adjust capabilities to allow it to do so. The following may be necessary:

Ensure the following two lines are in /etc/security/capability.conf

cap_net_admin   my_user
none *

Also, in /etc/pam.d/login add the following

auth    required        pam_cap.so

Finally, grant the capability to the tcpscan file (assuming /path/to is the absolute path to your tcpscan binary)

setcap cap_net_raw,cap_net_admin=eip /path/to/tcpscan

License

BSD 3-Clause License

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	//TCPScanConfigPath is the default config path of the TCPScan service
	TCPScanConfigPath = filepath.Join("data", "config", "TCPScanConfig.yml")
)

Functions

func CompactDB added in v0.4.0

func CompactDB(dayPath, scanID string)

CompactDB reclaims space by pruning the database

func GetNextScanID added in v0.4.0

func GetNextScanID() string

GetNextScanID returns the next unique scan ID

func PersistScanRequest added in v0.4.0

func PersistScanRequest(psr PersistedScanRequest)

PersistScanRequest persists scan request

func PersistScans added in v0.4.0

func PersistScans(psr PersistedScanRequest, server string, scans []PortACK)

PersistScans persists the result of scans per server

func ScanCIDR

func ScanCIDR(config ScanConfig, cidrAddresses ...string) <-chan PortACK

ScanCIDR scans for open TCP ports in IP addresses within a CIDR range

func ScheduleTCPScan added in v0.4.0

func ScheduleTCPScan(ipSource func() []string)

ScheduleTCPScan runs TCPScan service scan

func Service added in v0.4.0

func Service(configPath string)

Service main service entry function

Types

type MyPPP

type MyPPP layers.PPP

MyPPP is layers.PPP with CanDecode and other decoding operations implemented

func (*MyPPP) CanDecode

func (ppp *MyPPP) CanDecode() gopacket.LayerClass

CanDecode indicates that we can decode PPP packets

func (*MyPPP) DecodeFromBytes

func (ppp *MyPPP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error

DecodeFromBytes as name suggest

func (*MyPPP) LayerType

func (ppp *MyPPP) LayerType() gopacket.LayerType

LayerType -

func (*MyPPP) NextLayerType

func (ppp *MyPPP) NextLayerType() gopacket.LayerType

NextLayerType gets type

type PersistedScanRequest added in v0.4.0

type PersistedScanRequest struct {
	Request   ScanRequest
	Hosts     []string
	ScanStart time.Time
	ScanEnd   time.Time
	Progress  int
}

PersistedScanRequest persisted version of ScanRequest

func LoadScanRequest added in v0.4.0

func LoadScanRequest(dir, scanID string) (psr PersistedScanRequest, e error)

LoadScanRequest retrieves persisted scan request from folder following a layout pattern

func UnmasharlPersistedScanRequest added in v0.4.0

func UnmasharlPersistedScanRequest(data []byte) (PersistedScanRequest, error)

UnmasharlPersistedScanRequest builds PersistedScanRequest from bytes

func (PersistedScanRequest) Marshall added in v0.4.0

func (psr PersistedScanRequest) Marshall() []byte

Marshall scan request

type PortACK

type PortACK struct {
	Host string
	Port string
	RST  bool
	SYN  bool
}

PortACK describes a port with an ACK after a TCP SYN request

func (PortACK) GetServiceName

func (p PortACK) GetServiceName() string

GetServiceName returns the service name indicated by the port number

func (PortACK) IsClosed

func (p PortACK) IsClosed() bool

IsClosed determines whether the port is filtered by e.g. by a firewall

func (PortACK) IsOpen

func (p PortACK) IsOpen() bool

IsOpen determines whether the port is open or not

func (PortACK) Status

func (p PortACK) Status() string

Status is a string representation of the port status

type PortAckSorter added in v0.4.0

type PortAckSorter []PortACK

PortAckSorter sorts ack messages

func (PortAckSorter) Len added in v0.4.0

func (k PortAckSorter) Len() int

func (PortAckSorter) Less added in v0.4.0

func (k PortAckSorter) Less(i, j int) bool

func (PortAckSorter) Swap added in v0.4.0

func (k PortAckSorter) Swap(i, j int)

type ScanConfig

type ScanConfig struct {
	//How long to wait listening for TCP ACK/RST responses
	Timeout int
	//Number of Packets per Second to send out during scan
	PacketsPerSecond int
	//Should a running commentary of results be generated?
	Quiet bool
	//If not empty, indicates which network interface to use, bypassing automated guessing
	Interface string
}

ScanConfig describes details of how the port scan should be carried out

type ScanRequest added in v0.4.0

type ScanRequest struct {
	CIDRs  []string
	Config ScanConfig
	Day    string //Date the scan was run in the format yyyy-mm-dd
	ScanID string //Non-empty ScanID means this is a ScanRequest to resume an existing, possibly incomplete, scan
}

ScanRequest is a model to describe a given TLS Audit scan

func ListScans added in v0.4.0

func ListScans(rewindDays int, completed bool) (result []ScanRequest)

ListScans returns the ScanID list of persisted scans

type TCPScanConfig added in v0.4.0

type TCPScanConfig struct {
	DailySchedules   []string `yaml:"dailySchedules"` // in the format 13:45, 01:20 etc
	IsProduction     bool     `yaml:"isProduction"`
	PacketsPerSecond int      `yaml:"packetsPerSecond"`
	Timeout          int      `yaml:"timeout"`
	CIDRRanges       []string `yaml:"cidrRanges"`
}

TCPScanConfig config data structure for the scanner service

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL