Agent: Try well-known ports before other ports

This commit is contained in:
Kekoa Kaaikala 2022-09-07 17:55:44 +00:00 committed by Mike Salvatore
parent 4c795343d0
commit 33aac19831
5 changed files with 93 additions and 10 deletions

View File

@ -1,5 +1,6 @@
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")
@ -48,3 +49,15 @@ def del_key(mapping: MutableMapping[T, Any], key: T):
del mapping[key]
except KeyError:
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

View File

@ -3,14 +3,17 @@ import socket
import struct
from dataclasses import dataclass
from ipaddress import IPv4Interface
from random import randint # noqa: DUO102
from random import shuffle # noqa: DUO102
from typing import List
import netifaces
import psutil
from common.utils.code_utils import in_sorted_sequence
from infection_monkey.utils.environment import is_windows_os
from .ports import COMMON_PORTS
# Timeout for monkey connections
LOOPBACK_NAME = b"lo"
SIOCGIFADDR = 0x8915 # get PA address
@ -119,15 +122,19 @@ else:
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)
max_range = min(65535, max_range)
in_use = [conn.laddr[1] for conn in psutil.net_connections()]
for i in range(min_range, max_range):
port = randint(min_range, max_range)
if port not in in_use:
ports = list(range(min_range, max_range))
shuffle(ports)
for port in ports:
if not in_sorted_sequence(port, in_use):
return port
return None

View File

@ -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
]

View File

@ -1,6 +1,6 @@
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():
@ -40,3 +40,11 @@ def test_del_key__nonexistant_key():
# This test passes if the following call does not raise an error
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))

View File

@ -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