-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #138 from rackerlabs/nmap_port_range_carver
Added nmap_port_range_carver files
- Loading branch information
Showing
4 changed files
with
27,521 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Carve out top TCP/UDP ranked ports from nmap according to the nmap-services file | ||
|
||
A standalone script to carve out a range of the top TCP/UDP ports according to the `nmap-services` file. This is useful | ||
when: | ||
|
||
1. You want to scan a subset of the ports specified in `--top-ports`, say the 10th through 20th top TCP ports, but not | ||
the 1st or 9th ports. | ||
|
||
2. You want the 1337th ranked TCP port. | ||
|
||
3. You want to utilize nmap to scan **both** TCP and UDP, but not scan the same number of top ports. | ||
|
||
This works and will scan the top 10 ports for BOTH TCP and UDP | ||
|
||
```bash | ||
nmap --top-ports 10 -sU -sT <TARGET> | ||
``` | ||
|
||
but you can't only scan the top 20 TCP and top 10 UDP ports using `--top-ports`. | ||
|
||
## Installation | ||
|
||
```bash | ||
git clone https://github.com/rackerlabs/scantron.git | ||
cd scantron/nmap_port_range_carver | ||
virtualenv -p python3 .venv # If using a virtual environment. | ||
source .venv/bin/activate # If using a virtual environment. | ||
``` | ||
|
||
## Command Line Usage | ||
|
||
Script switches | ||
|
||
```bash | ||
python nmap_port_range_carver.py -h | ||
``` | ||
|
||
Retrieve TCP ports ranked 10 through 20: | ||
|
||
```bash | ||
$ python nmap_port_range_carver.py -s 10 -e 20 | ||
port_rank_list: [139, 143, 53, 135, 3306, 8080, 1723, 111, 995, 993, 5900] | ||
port_rank_csv: 139,143,53,135,3306,8080,1723,111,995,993,5900 | ||
``` | ||
|
||
Retrieve 1,337th ranked TCP port: | ||
|
||
```bash | ||
$ python nmap_port_range_carver.py -s 1337 -e 1337 | ||
port_rank_list: [7010] | ||
port_rank_csv: 7010 | ||
``` | ||
|
||
Retrieve UDP ports ranked 50 through 60: | ||
|
||
```bash | ||
$ python nmap_port_range_carver.py -s 50 -e 60 -p udp | ||
port_rank_list: [1027, 177, 1719, 427, 497, 4444, 1023, 65024, 19, 9, 49193] | ||
port_rank_csv: 1027,177,1719,427,497,4444,1023,65024,19,9,49193 | ||
``` | ||
|
||
## Python Import Usage | ||
|
||
If used as a Python module, it returns a dictionary with a keys for a Python list and CSV string: | ||
|
||
```python | ||
import nmap_port_range_carver | ||
tcp_ports_range_10_20 = nmap_port_range_carver.main(start_rank=10, end_rank=20, protocol="tcp") | ||
print(tcp_ports_range_10_20) | ||
``` | ||
|
||
```json | ||
{ | ||
"port_rank_list": [139, 143, 53, 135, 3306, 8080, 1723, 111, 995, 993, 5900], | ||
"port_rank_csv": "139,143,53,135,3306,8080,1723,111,995,993,5900" | ||
} | ||
``` | ||
|
||
## Generate top ports files from nmap's nmap-services | ||
|
||
> Note: The `nmap-services` file only contains the top 8309 ports. | ||
These files are already provided, but here are the commands to generate them. | ||
|
||
```bash | ||
egrep /tcp /usr/share/nmap/nmap-services | sort -r -k3 | sed 's/[\t ]/,/g' \ | ||
| cut -d "," -f 2 | cut -f 1 -d "/" > nmap_top_ports_tcp.txt | ||
egrep /udp /usr/share/nmap/nmap-services | sort -r -k3 | sed 's/[\t ]/,/g' \ | ||
| cut -d "," -f 2 | cut -f 1 -d "/" > nmap_top_ports_udp.txt | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#!/usr/bin/env python | ||
|
||
# Standard Python libraries. | ||
import argparse | ||
|
||
# Third party Python libraries. | ||
|
||
|
||
# Custom Python libraries. | ||
|
||
|
||
# BASH command to generate nmap_top_ports_PROTOCOL.txt files. | ||
r""" | ||
egrep /tcp /usr/share/nmap/nmap-services | sort -r -k3 | sed 's/[\t ]/,/g' \ | ||
| cut -d "," -f 2 | cut -f 1 -d "/" > nmap_top_ports_tcp.txt | ||
egrep /udp /usr/share/nmap/nmap-services | sort -r -k3 | sed 's/[\t ]/,/g' \ | ||
| cut -d "," -f 2 | cut -f 1 -d "/" > nmap_top_ports_udp.txt | ||
""" | ||
|
||
|
||
def main(start_rank, end_rank, protocol="tcp"): | ||
|
||
if protocol == "tcp": | ||
port_file = "nmap_top_ports_tcp.txt" | ||
|
||
elif protocol == "udp": | ||
port_file = "nmap_top_ports_udp.txt" | ||
|
||
else: | ||
print("This should never be reached.") | ||
exit() | ||
|
||
# Build list of port ranks. | ||
port_list = [] | ||
|
||
with open(port_file, "r") as fh: | ||
for index, port in enumerate(fh): | ||
port_list.append(port.strip()) | ||
|
||
# Don't subtract one from end_rank to include actual rank. | ||
# Creates a list of strings, will covert to list of ints later. | ||
port_rank_list_temp = port_list[(start_rank - 1) : end_rank] # noqa | ||
port_rank_csv = ",".join(port_rank_list_temp) | ||
|
||
port_rank_list = [] | ||
for rank in port_rank_list_temp: | ||
port_rank_list.append(int(rank)) | ||
|
||
print(f"port_rank_list: {port_rank_list}") | ||
print(f"port_rank_csv: {port_rank_csv}") | ||
|
||
# fmt: off | ||
port_rank_dict = { | ||
"port_rank_list": port_rank_list, | ||
"port_rank_csv": port_rank_csv, | ||
} | ||
# fmt: on | ||
|
||
return port_rank_dict | ||
|
||
|
||
if __name__ == "__main__": | ||
|
||
parser = argparse.ArgumentParser(description="") | ||
parser.add_argument( | ||
"-s", dest="start_rank", action="store", type=int, required=True, help="Port rank to start at. Minimum: 1" | ||
) | ||
parser.add_argument( | ||
"-e", dest="end_rank", action="store", type=int, required=True, help="Port rank to end at. Maximum: 8309" | ||
) | ||
parser.add_argument( | ||
"-p", | ||
dest="protocol", | ||
action="store", | ||
required=False, | ||
default="tcp", | ||
help="Specify tcp or udp protocol. Default: tcp", | ||
) | ||
|
||
args = parser.parse_args() | ||
|
||
args.protocol = args.protocol.lower() | ||
|
||
if args.protocol not in ["tcp", "udp"]: | ||
print("Protocol must be 'tcp' or 'udp'") | ||
exit() | ||
|
||
if args.end_rank < args.start_rank: | ||
print("Start rank must be less than (<) end rank.") | ||
exit() | ||
|
||
if args.start_rank not in range(1, 8310): | ||
print("Port start rank must be 1-8309 inclusive") | ||
exit() | ||
|
||
if args.end_rank not in range(1, 8310): | ||
print("Port end rank must be 1-8309 inclusive") | ||
exit() | ||
|
||
main(**vars(args)) |
Oops, something went wrong.