История изменений
Исправление rtxtxtrx, (текущая версия) :
Да оно только так и работает:
def normalize_ports(ports: list[str]) -> set[int]:
rv = set()
for x in ports:
try:
a, b = map(int, x.split("-", 1))
rv.update(range(a, b + 1))
except ValueError:
rv.add(int(x))
return rv
WELL_KNOWN_PORTS = frozenset(
[
110,
143,
21,
22,
2222,
23,
25,
3306,
443,
465,
5432,
587,
5900,
6379,
80,
8080,
8443,
9000,
993,
995,
]
)
class NameSpace(argparse.Namespace):
address: str
ports: list[str]
debug: bool
timeout: float
def parse_args(
argv: list[str] | None,
) -> tuple[argparse.ArgumentParser, NameSpace]:
parser = argparse.ArgumentParser()
parser.add_argument("address", type=socket.gethostbyname)
parser.add_argument(
"-p",
"--port",
dest="ports",
nargs="+",
help="port or range of ports",
)
parser.add_argument("-t", "--timeout", type=float, default=15.0)
parser.add_argument("-d", "--debug", action="store_true", default=False)
args = parser.parse_args(argv, namespace=NameSpace())
return parser, args
def main(argv: list[str] | None = None) -> None:
_, args = parse_args(argv)
if args.debug:
logging.basicConfig()
logger.setLevel(logging.DEBUG)
ports = normalize_ports(args.ports) if args.ports else WELL_KNOWN_PORTS
local_ip = get_local_ip()
sniff_t = threading.Thread(
target=sniff,
args=(local_ip, args.address, ports),
)
sniff_t.daemon = True
sniff_t.start()
with socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW
) as s:
for port in ports:
src_port = random.randint(30000, 50000)
packet = make_syn_packet(local_ip, src_port, args.address, port)
n = s.sendto(packet, (args.address, 0))
logger.debug("bytes sent: %d", n)
sniff_t.join(args.timeout)
def sniff(local_ip: str, target_ip: str, ports: set[int]) -> None:
with socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP
) as s:
while 1:
res, addr = s.recvfrom(65535)
if addr[0] != target_ip:
continue
src_ip = socket.inet_ntoa(res[12:16])
if src_ip != target_ip:
continue
dst_ip = socket.inet_ntoa(res[16:20])
if dst_ip != local_ip:
continue
src_port = int.from_bytes(res[20:22])
# dst_port = int.from_bytes(res[22:24])
# Это самый быстрый способ проверить открыт ли порт
if res[33] == 0x012 and src_port in ports:
print(src_ip, src_port)
if __name__ == "__main__":
sys.exit(main())
Так-то он нормально порты перебирает:
❯ sudo ./scan_ports.py github.com
140.82.121.3 22
140.82.121.3 443
140.82.121.3 80
Исправление rtxtxtrx, :
Да оно только так и работает:
def normalize_ports(ports: list[str]) -> set[int]:
rv = set()
for x in ports:
try:
a, b = map(int, x.split("-", 1))
rv.update(range(a, b + 1))
except ValueError:
rv.add(int(x))
return rv
WELL_KNOWN_PORTS = frozenset(
[
110,
143,
21,
22,
2222,
23,
25,
3306,
443,
465,
5432,
587,
5900,
6379,
80,
8080,
8443,
9000,
993,
995,
]
)
class NameSpace(argparse.Namespace):
address: str
ports: list[str]
debug: bool
timeout: float
def parse_args(
argv: list[str] | None,
) -> tuple[argparse.ArgumentParser, NameSpace]:
parser = argparse.ArgumentParser()
parser.add_argument("address", type=socket.gethostbyname)
parser.add_argument(
"-p",
"--port",
dest="ports",
nargs="+",
help="port or range of ports",
)
parser.add_argument("-t", "--timeout", type=float, default=15.0)
parser.add_argument("-d", "--debug", action="store_true", default=False)
args = parser.parse_args(argv, namespace=NameSpace())
return parser, args
def main(argv: list[str] | None = None) -> None:
_, args = parse_args(argv)
if args.debug:
logging.basicConfig()
logger.setLevel(logging.DEBUG)
ports = normalize_ports(args.ports) if args.ports else WELL_KNOWN_PORTS
local_ip = get_local_ip()
sniff_t = threading.Thread(
target=sniff,
args=(local_ip, args.address, ports),
)
sniff_t.daemon = True
sniff_t.start()
with socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW
) as s:
for port in ports:
src_port = random.randint(30000, 50000)
packet = make_syn_packet(local_ip, src_port, args.address, port)
n = s.sendto(packet, (args.address, 0))
logger.debug("bytes sent: %d", n)
sniff_t.join(args.timeout)
def sniff(local_ip: str, target_ip: str, ports: set[int]) -> None:
with socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP
) as s:
while 1:
res, addr = s.recvfrom(65535)
if addr[0] != target_ip:
continue
src_ip = socket.inet_ntoa(res[12:16])
if src_ip != target_ip:
continue
dst_ip = socket.inet_ntoa(res[16:20])
if dst_ip != local_ip:
continue
src_port = int.from_bytes(res[20:22])
# dst_port = int.from_bytes(res[22:24])
# Это самый быстрый способ проверить открыт ли порт
if res[33] == 0x012 and src_port in ports:
print(src_ip, src_port)
if __name__ == "__main__":
sys.exit(main())
Исходная версия rtxtxtrx, :
Да оно только так и работает:
def normalize_ports(ports: list[str]) -> set[int]:
rv = set()
for x in ports:
try:
a, b = map(int, x.split("-", 1))
rv.update(range(a, b + 1))
except ValueError:
rv.add(int(x))
return rv
WELL_KNOWN_PORTS = frozenset(
[
110,
143,
21,
22,
2222,
23,
25,
3306,
443,
465,
5432,
587,
5900,
6379,
80,
8080,
8443,
9000,
993,
995,
]
)
class NameSpace(argparse.Namespace):
address: str
ports: list[str]
debug: bool
timeout: float
def parse_args(
argv: list[str] | None,
) -> tuple[argparse.ArgumentParser, NameSpace]:
parser = argparse.ArgumentParser()
parser.add_argument("address", type=socket.gethostbyname)
parser.add_argument(
"-p",
"--port",
dest="ports",
nargs="+",
help="port or range of ports",
)
parser.add_argument("-t", "--timeout", type=float, default=15.0)
parser.add_argument("-d", "--debug", action="store_true", default=False)
args = parser.parse_args(argv, namespace=NameSpace())
return parser, args
def main(argv: list[str] | None = None) -> None:
_, args = parse_args(argv)
if args.debug:
logging.basicConfig()
logger.setLevel(logging.DEBUG)
ports = normalize_ports(args.ports) if args.ports else WELL_KNOWN_PORTS
local_ip = get_local_ip()
sniff_t = threading.Thread(
target=sniff,
args=(local_ip, args.address, ports),
)
sniff_t.daemon = True
sniff_t.start()
with socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW
) as s:
for port in ports:
src_port = random.randint(30000, 50000)
packet = make_syn_packet(local_ip, src_port, args.address, port)
s = socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW
)
n = s.sendto(packet, (args.address, 0))
logger.debug("bytes sent: %d", n)
sniff_t.join(args.timeout)
def sniff(local_ip: str, target_ip: str, ports: set[int]) -> None:
with socket.socket(
socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP
) as s:
while 1:
res, addr = s.recvfrom(65535)
if addr[0] != target_ip:
continue
src_ip = socket.inet_ntoa(res[12:16])
if src_ip != target_ip:
continue
dst_ip = socket.inet_ntoa(res[16:20])
if dst_ip != local_ip:
continue
src_port = int.from_bytes(res[20:22])
# dst_port = int.from_bytes(res[22:24])
# Это самый быстрый способ проверить открыт ли порт
if res[33] == 0x012 and src_port in ports:
print(src_ip, src_port)
if __name__ == "__main__":
sys.exit(main())