Skip to content

Latest commit

Β 

History

154 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

License Build Status Platform

sx is the command-line network scanner designed to follow the UNIX philosophy.

The goal of this project is to create the fastest network scanner with clean and simple code.

πŸ“– Table of Contents

✨ Features

  • ⚑ 30x times faster than nmap
  • ARP, NDP, and multicast ICMPv6 scans: Discover IPv4 and IPv6 neighbors on local networks
  • Dual-stack scanning: ICMP, TCP, UDP, and SOCKS5 support IPv4 and IPv6
  • ICMP scan: Use advanced ICMP scanning techniques to detect live hosts and firewall rules
  • TCP SYN scan: Traditional half-open scan to find open TCP ports
  • TCP FIN / NULL / Xmas scans: Scan techniques to bypass some firewall rules
  • Custom TCP scans with any TCP flags: Send whatever exotic packets you want and get a result with all the TCP flags set in the reply packet
  • UDP scan: Scan UDP ports and get full ICMP replies to detect open ports or firewall rules
  • Application scans:
    • SOCKS5 scan: Detect live SOCKS5 proxies by scanning ip range or list of ip/port pairs from a file
  • Randomized iteration over IP addresses using finite cyclic multiplicative groups
  • JSON output support: sx is designed specifically for convenient automatic processing of results

πŸ“¦ Install

The simplest way is to download from GitHub Releases and place the executable file in your PATH.

πŸ›  Build from source

Requirements:

On macOS, install the Xcode Command Line Tools first so CGO can link against the system libpcap:

xcode-select --install

From the root of the source tree, run:

go build

πŸš€ Quick Start

Here's a quick examples showing how you can scan networks with sx.

ARP scan

Scan your local network and display the IP address, MAC address and associated hardware vendor of connected devices:

sx arp 192.168.0.1/24

sample output:

192.168.0.1          b0:be:76:40:05:8d    TP-LINK TECHNOLOGIES CO.,LTD.
192.168.0.111        80:c5:f2:0b:02:e3    AzureWave Technology Inc.
192.168.0.171        88:53:95:2d:3c:af    Apple, Inc.

with JSON output:

sx arp --json 192.168.0.1/24

sample output:

{"ip":"192.168.0.1","mac":"b0:be:76:40:05:8d","vendor":"TP-LINK TECHNOLOGIES CO.,LTD."}
{"ip":"192.168.0.111","mac":"80:c5:f2:0b:02:e3","vendor":"AzureWave Technology Inc."}
{"ip":"192.168.0.171","mac":"88:53:95:2d:3c:af","vendor":"Apple, Inc."}

wait 5 seconds before exiting to receive delayed reply packets, by default sx waits 300 milliseconds:

sx arp --exit-delay 5s 192.168.0.1/24

Live scan mode that rescans network every 10 seconds:

sx arp 192.168.0.1/24 --live 10s

ARP is an IPv4-only protocol. For IPv6, use Neighbor Discovery Protocol (NDP):

sx ndp --json 'fe80::%en0/120' | tee neighbor.cache

Scoped link-local hosts and prefixes are supported. The interface zone is retained in JSON output, for example fe80::1%en0. NDP also supports --live and --file in the same way as ARP and the other IP scanners.

For a fast best-effort IPv6 discovery pass, send one ICMPv6 Echo Request to the link-local all-nodes group (ff02::1):

sudo sx icmp discover --iface en0 --json | tee neighbor.cache

An explicit link-local multicast group can be supplied as the optional argument:

sudo sx icmp discover --iface en0 'ff02::1%en0'

By default, the command uses the first link-local IPv6 address assigned to the interface. If the interface has multiple link-local addresses, select one explicitly with --srcip:

sudo sx icmp discover --iface en0 --srcip 'fe80::1234%en0'

The source override must be a link-local unicast IPv6 address. Its optional zone must match --iface. As with other raw-packet scans, the override does not have to be assigned to the interface.

The command maps the multicast IPv6 destination to its 33:33:xx:xx:xx:xx Ethernet address and reports each correlated Echo Reply as the same ip, mac, and vendor JSONL shape used by ARP and NDP. Link-local result addresses retain the interface zone, so the JSON output can be passed directly to TCP or UDP scans as a neighbor cache. This is best-effort discovery: many hosts or firewalls ignore multicast Echo Requests, and an empty result does not mean that the link has no hosts or reveal every multicast membership.

TCP scan

Unlike nmap and other scanners that implicitly resolve link-layer addresses before the actual scan, sx explicitly uses a neighbor cache. The cache is a JSONL file with ip, mac, and optional vendor fields. It can contain IPv4 entries produced by sx arp and IPv6 entries produced by sx ndp or sx icmp discover. Higher-level scans read it from stdin by default.

This also avoids repeating ARP or NDP discovery for every higher-level scan.

Let's assume that the current IPv4 neighbor cache is in the arp.cache file. We can create it manually or populate it with an ARP scan:

sx arp 192.168.0.1/24 --json | tee arp.cache

Once we have the neighbor cache file, we can run higher-level scans such as TCP SYN:

cat arp.cache | sx tcp -p 1-65535 192.168.0.171

sample output:

192.168.0.171        22
192.168.0.171        443

In this case we find out that ports 22 and 443 are open.

If you see send: No buffer space available during large scans, it usually means the sender is outrunning the kernel/raw-socket buffers. The first fix is to add --rate and lower the send burst, for example -r 100000/s or lower if needed. On some systems, tuning OS socket/buffer limits can also help, but rate limiting is the primary fix.

scan with JSON output:

cat arp.cache | sx tcp  --json -p 1-65535 192.168.0.171

sample output:

{"scan":"tcpsyn","ip":"192.168.0.171","port":22}
{"scan":"tcpsyn","ip":"192.168.0.171","port":443}

scan multiple port ranges:

cat arp.cache | sx tcp -p 1-23,25-443 192.168.0.171

or individual ports:

cat arp.cache | sx tcp -p 22,443 192.168.0.171

or use the --ports-file option to specify a file with ports or port ranges to scan, one per line.

scan ip/port pairs from a file with JSON output:

cat arp.cache | sx tcp --json -f ip_ports_file.jsonl

Each line of the input file is a json string, which must contain the ip and port fields.

sample input file:

{"ip":"10.0.1.1","port":1080}
{"ip":"10.0.2.2","port":1081}

It is possible to specify the neighbor cache file using -a or --neighbor-cache. The old --arp-cache name remains as a deprecated alias:

sx tcp -a arp.cache -p 22,443 192.168.0.171

or stdin redirect:

sx tcp -p 22,443 192.168.0.171 < arp.cache

IPv6 works with the same TCP, UDP, ICMP, and SOCKS commands:

sx ndp --json 'fe80::%en0/120' | sx tcp -p 22,443 'fe80::1%en0'
sx socks -p 1080 '2001:db8::/120'

For file-only raw-packet scans, pass --ipv6 to select an IPv6 source/interface. IPv6 packet fields use --hop-limit, --next-header, and --payload-length; ICMPv6 additionally uses --icmpv6-type and --icmpv6-code. IPv4-only fields such as --ttl, --ipproto, --ipflags, and --iplen are rejected for IPv6 scans.

To keep randomized target generation bounded, directly generated IPv6 ranges must be /96 or narrower. Use --file for larger or explicitly selected address sets.

You can also use the tcp syn subcommand instead of the tcp:

cat arp.cache | sx tcp syn -p 22 192.168.0.171

tcp subcomand is just a shorthand for tcp syn subcommand unless --flags option is passed, see below.

VPN interfaces

sx supports scanning with virtual network interfaces (wireguard, openvpn, etc.) and in this case it is not necessary to use the arp cache, since these interfaces require raw IP packets instead of Ethernet frames as input. For instance, scanning an IP address on a vpn network:

sx tcp 10.1.27.1 -p 80 --json

TCP FIN scan

Most network scanners try to interpret results of the scan. For instance they say "this port is closed" instead of "I received a RST". Sometimes they are right. Sometimes not. It's easier for beginners, but when you know what you're doing, you keep on trying to deduce what really happened from the program's interpretation, especially for more advanced scan techniques.

sx tries to overcome those problems. It returns information about all reply packets for TCP FIN, NULL, Xmas and custom TCP scans. The information contains IP address, TCP port and all TCP flags set in the reply packet.

TCP FIN scan and its other variations (NULL and Xmas) exploit RFC793 Section 3.9:

SEGMENT ARRIVES

If the state is CLOSED (i.e., TCB does not exist) then

 all data in the incoming segment is discarded.  An incoming
 segment containing a RST is discarded.  An incoming segment not
 containing a RST causes a RST to be sent in response.  The
 acknowledgment and sequence field values are selected to make the
 reset sequence acceptable to the TCP that sent the offending
 segment.

so closed port should return packet with RST flag.

This section also states that:

If the state is LISTEN then

...

Any other control or text-bearing segment (not containing SYN) must have an ACK and thus would be discarded by the ACK processing. An incoming RST segment could not be valid, since it could not have been sent in response to anything sent by this incarnation of the connection. So you are unlikely to get here, but if you do, drop the segment, and return.

the main phrase here: drop the segment, and return. So an open port on most operating systems will drop the TCP packet containing any flags except SYN,ACK and RST.

Let's scan some closed port with TCP FIN scan:

cat arp.cache | sx tcp fin --json -p 23 192.168.0.171

sample output:

{"scan":"tcpfin","ip":"192.168.0.171","port":23,"flags":"ar"}

flags field contains all TCP flags in the reply packet, where each letter represents one of the TCP flags:

  • s - SYN flag
  • a - ACK flag
  • f - FIN flag
  • r - RST flag
  • p - PSH flag
  • u - URG flag
  • e - ECE flag
  • c - CWR flag
  • n - NS flag

In this case we find out that port 23 sent reply packet with ACK and RST flags set (typical response for a closed port according to the rfc793).

If we scan an open port, we get no response (unless the firewall is spoofing the responses).

Other types of TCP scans can be conducted by analogy.

TCP NULL scan:

cat arp.cache | sx tcp null --json -p 23 192.168.0.171

TCP Xmas scan:

cat arp.cache | sx tcp xmas --json -p 23 192.168.0.171

Custom TCP scans

It is possible to send TCP packets with custom TCP flags using --flags option.

Let's send TCP packet with SYN, FIN and ACK flags set to fingerprint remote OS:

cat arp.cache | sx tcp --flags syn,fin,ack --json -p 23 192.168.0.171

Windows and MacOS will not respond to this packet, but Linux will send reply packet with RST flag.

Possible arguments to --flags option:

  • syn - SYN flag
  • ack - ACK flag
  • fin - FIN flag
  • rst - RST flag
  • psh - PSH flag
  • urg - URG flag
  • ece - ECE flag
  • cwr - CWR flag
  • ns - NS flag

UDP scan

sx can help investigate open UDP ports. UDP scan exploits RFC1122 Section 4.1.3.1:

If a datagram arrives addressed to a UDP port for which there is no pending LISTEN call, UDP SHOULD send an ICMP Port Unreachable message.

Similar to TCP scans, sx returns information about all reply ICMP packets for UDP scan. The information contains IP address, ICMP packet type and code set in the reply packet.

For instance, to detect DNS server on host, run:

cat arp.cache | sx udp --json -p 53 192.168.0.171

sample output:

{"scan":"udp","ip":"192.168.0.171","icmp":{"type":3,"code":3}}

In this case we find out that host sent ICMP reply packet with Destination Unreachable type and Port Unreachable code (typical response for a closed port according to the rfc1122).

Firewalls typically set ICMP code distinct from Port Unreachanble and so can be easily detected.

Rate limiting

Sometimes you need to limit the speed at which generated packets are sent. This can be done with the --rate option.

For example, to limit the speed to 1 packet per 5 seconds:

cat arp.cache | sx tcp --rate 1/5s --json -p 22,80,443 192.168.0.171

Exclude subnets

Sometimes you need to exclude some ip addresses and subnets from scanning. This can be done with the --exclude option. It specifies a file with IPs or subnets in CIDR notation to exclude, one-per line.

For instance, to exclude RFC 1918 addresses, create a file ips.txt with the following contents:

10.0.0.0/8
172.16.0.0/16
192.168.0.0/16

You can also insert comments and blank lines:

# exclude RFC 1918 addresses
10.0.0.0/8 # comment 1
172.16.0.0/12 # comment 2
192.168.0.0/16 # comment 3

0.0.0.0/8 # used in initialization procedures (RFC 6890)

# exclude RFC 5735 addresses
127.0.0.0/8 # loopback address
192.0.0.0/24 # reserved block for IETF protocol assignments
224.0.0.0/4 # allocated for use in IPv4 multicast address assignments
240.0.0.0/4 # reserved for future use

# exclude Amazon network
3.0.0.0/8

# ip addresses are valid as well
1.1.1.1

and run a scan with --exclude ips.txt option.

Live LAN TCP SYN scanner

As an example of scan composition, you can combine ARP and TCP SYN scans to create live TCP port scanner that periodically scan whole LAN network.

Start live ARP scan and save results to arp.cache file:

sx arp 192.168.0.1/24 --live 10s --json | tee arp.cache

In another terminal start TCP SYN scan:

while true; do sx tcp -p 1-65535 -a arp.cache -f arp.cache; sleep 30; done

SOCKS5 scan

sx can detect live SOCKS5 proxies. To scan, you must specify an IP range or JSONL file with ip/port pairs.

For example, an IP range scan:

sx socks -p 1080 10.0.0.1/16

scan ip/port pairs from a file with JSON output:

sx socks --json -f ip_ports_file.jsonl 

Each line of the input file is a json string, which must contain the ip and port fields.

sample input file:

{"ip":"10.0.1.1","port":1080}
{"ip":"10.0.2.2","port":1081}

You can also specify a range of ports to scan:

sx socks -p 1080-4567 -f ips_file.jsonl

In this case only ip addresses will be taken from the file and the port field is no longer necessary.

Usage help

sx help

πŸ“œ References

🀝 Contributing

Contributions, issues and feature requests are welcome.

πŸ’Ž Credits

Logo is designed by mikhailtsoy.com

License

This project is licensed under the MIT License. See the LICENSE file for the full license text.

About

πŸ–– Fast, modern, easy-to-use network scanner

Topics

Resources

Stars

1.6k stars

Watchers

14 watching

Forks

Releases

Packages

Used by

Contributors

Languages