forked from p15670423/monkey
Agent: Try well-known ports before other ports
This commit is contained in:
parent
4c795343d0
commit
33aac19831
|
@ -1,5 +1,6 @@
|
||||||
import queue
|
import queue
|
||||||
from typing import Any, Dict, List, MutableMapping, Type, TypeVar
|
from bisect import bisect_left
|
||||||
|
from typing import Any, Dict, List, MutableMapping, Sequence, Type, TypeVar
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
@ -48,3 +49,15 @@ def del_key(mapping: MutableMapping[T, Any], key: T):
|
||||||
del mapping[key]
|
del mapping[key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def in_sorted_sequence(item: Any, seq: Sequence[Any]) -> bool:
|
||||||
|
"""
|
||||||
|
Provides fast search in the case that the sequence is sorted.
|
||||||
|
|
||||||
|
:param item: The item to search in the list.
|
||||||
|
:param seq: The sorted sequence in which to search the item.
|
||||||
|
:return: True if the item was found in the list, otherwise false.
|
||||||
|
"""
|
||||||
|
i = bisect_left(seq, item)
|
||||||
|
return i != len(seq) and seq[i] == item
|
||||||
|
|
|
@ -3,14 +3,17 @@ import socket
|
||||||
import struct
|
import struct
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from ipaddress import IPv4Interface
|
from ipaddress import IPv4Interface
|
||||||
from random import randint # noqa: DUO102
|
from random import shuffle # noqa: DUO102
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
import netifaces
|
import netifaces
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
|
from common.utils.code_utils import in_sorted_sequence
|
||||||
from infection_monkey.utils.environment import is_windows_os
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
|
from .ports import COMMON_PORTS
|
||||||
|
|
||||||
# Timeout for monkey connections
|
# Timeout for monkey connections
|
||||||
LOOPBACK_NAME = b"lo"
|
LOOPBACK_NAME = b"lo"
|
||||||
SIOCGIFADDR = 0x8915 # get PA address
|
SIOCGIFADDR = 0x8915 # get PA address
|
||||||
|
@ -119,15 +122,19 @@ else:
|
||||||
|
|
||||||
|
|
||||||
def get_free_tcp_port(min_range=1024, max_range=65535):
|
def get_free_tcp_port(min_range=1024, max_range=65535):
|
||||||
|
|
||||||
|
in_use = sorted([conn.laddr[1] for conn in psutil.net_connections()])
|
||||||
|
|
||||||
|
for port in COMMON_PORTS:
|
||||||
|
if not in_sorted_sequence(port, in_use):
|
||||||
|
return port
|
||||||
|
|
||||||
min_range = max(1, min_range)
|
min_range = max(1, min_range)
|
||||||
max_range = min(65535, max_range)
|
max_range = min(65535, max_range)
|
||||||
|
ports = list(range(min_range, max_range))
|
||||||
in_use = [conn.laddr[1] for conn in psutil.net_connections()]
|
shuffle(ports)
|
||||||
|
for port in ports:
|
||||||
for i in range(min_range, max_range):
|
if not in_sorted_sequence(port, in_use):
|
||||||
port = randint(min_range, max_range)
|
|
||||||
|
|
||||||
if port not in in_use:
|
|
||||||
return port
|
return port
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
COMMON_PORTS: List[int] = [
|
||||||
|
1025, # NFS, IIS
|
||||||
|
1433, # Microsoft SQL Server
|
||||||
|
1434, # Microsoft SQL Monitor
|
||||||
|
1720, # h323q931
|
||||||
|
1723, # Microsoft PPTP VPN
|
||||||
|
3306, # mysql
|
||||||
|
3389, # Windows Terminal Server (RDP)
|
||||||
|
5900, # vnc
|
||||||
|
6001, # X11:1
|
||||||
|
8080, # http-proxy
|
||||||
|
8888, # sun-answerbook
|
||||||
|
]
|
|
@ -1,6 +1,6 @@
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
|
|
||||||
from common.utils.code_utils import del_key, queue_to_list
|
from common.utils.code_utils import del_key, in_sorted_sequence, queue_to_list
|
||||||
|
|
||||||
|
|
||||||
def test_empty_queue_to_empty_list():
|
def test_empty_queue_to_empty_list():
|
||||||
|
@ -40,3 +40,11 @@ def test_del_key__nonexistant_key():
|
||||||
|
|
||||||
# This test passes if the following call does not raise an error
|
# This test passes if the following call does not raise an error
|
||||||
del_key(my_dict, key_to_delete)
|
del_key(my_dict, key_to_delete)
|
||||||
|
|
||||||
|
|
||||||
|
def test_in_sorted_sequence__finds_item():
|
||||||
|
assert in_sorted_sequence(99, range(100))
|
||||||
|
|
||||||
|
|
||||||
|
def test_in_sorted_sequence__does_not_find_nonexistent_item():
|
||||||
|
assert not in_sorted_sequence(101, range(100))
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from infection_monkey.network.info import get_free_tcp_port
|
||||||
|
from infection_monkey.network.ports import COMMON_PORTS
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Connection:
|
||||||
|
laddr: Tuple[str, int]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("port", COMMON_PORTS)
|
||||||
|
def test_get_free_tcp_port__checks_common_ports(port: int, monkeypatch):
|
||||||
|
unavailable_ports = [Connection(("", p)) for p in COMMON_PORTS if p is not port]
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"infection_monkey.network.info.psutil.net_connections", lambda: unavailable_ports
|
||||||
|
)
|
||||||
|
assert get_free_tcp_port() is port
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_free_tcp_port__checks_other_ports_if_common_ports_unavailable(monkeypatch):
|
||||||
|
unavailable_ports = [Connection(("", p)) for p in COMMON_PORTS]
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"infection_monkey.network.info.psutil.net_connections", lambda: unavailable_ports
|
||||||
|
)
|
||||||
|
|
||||||
|
assert get_free_tcp_port() is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_free_tcp_port__none_if_no_available_ports(monkeypatch):
|
||||||
|
unavailable_ports = [Connection(("", p)) for p in range(65535)]
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"infection_monkey.network.info.psutil.net_connections", lambda: unavailable_ports
|
||||||
|
)
|
||||||
|
|
||||||
|
assert get_free_tcp_port() is None
|
Loading…
Reference in New Issue