Skip to content

Commit

Permalink
Create service scan events from command 'ss' using the new entity tag…
Browse files Browse the repository at this point in the history
… address
  • Loading branch information
raulikak committed May 21, 2024
1 parent 45f8405 commit 0301ac0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
19 changes: 16 additions & 3 deletions tcsfw/shell_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from tcsfw.address import Addresses, EndpointAddress, IPAddress
from tcsfw.components import OperatingSystem
from tcsfw.event_interface import EventInterface, PropertyEvent
from tcsfw.model import IoTSystem, NetworkNode
from tcsfw.model import Addressable, IoTSystem, NetworkNode
from tcsfw.property import PropertyKey
from tcsfw.tools import NetworkNodeTool
from tcsfw.traffic import Evidence, EvidenceSource, Protocol
from tcsfw.traffic import Evidence, EvidenceSource, Protocol, ServiceScan
from tcsfw.verdict import Verdict


Expand Down Expand Up @@ -91,7 +91,7 @@ def _parse_address(self, addr: str) -> Tuple[str, str, int]:
"""Parse address into IP, interface, port"""
ad_inf, _, port = addr.rpartition(":")
ad, _, inf = ad_inf.partition("%")
return ad if ad not in {"", "*", "0.0.0.0"} else "", inf, int(port) if port not in {"", "*"} else -1
return ad if ad not in {"", "*", "0.0.0.0", "[::]"} else "", inf, int(port) if port not in {"", "*"} else -1

LOCAL_ADDRESS = "Local_Address"
PEER_ADDRESS = "Peer_Address"
Expand All @@ -101,6 +101,9 @@ def process_node(self, node: NetworkNode, data_file: BytesIO, interface: EventIn
services = set()
conns = set()

assert isinstance(node, Addressable)
tag = Addresses.get_tag(node.addresses)

with TextIOWrapper(data_file) as f:
while True:
line = f.readline()
Expand All @@ -126,6 +129,10 @@ def process_node(self, node: NetworkNode, data_file: BytesIO, interface: EventIn
peer_add = IPAddress.new(peer_ip) if peer_ip else None
if local_inf == "lo" or (local_add and local_add.is_loopback()):
continue # loopback is not external
if not local_add:
if not tag:
continue # no host address known, cannot send events
local_add = tag
if net_id == "udp" and state == "UNCONN":
# listening UDP port
add = EndpointAddress(local_add or Addresses.ANY, Protocol.UDP, local_port)
Expand All @@ -143,3 +150,9 @@ def process_node(self, node: NetworkNode, data_file: BytesIO, interface: EventIn
peer = EndpointAddress(peer_add, proto, peer_port)
conns.add((local, peer))
continue

if self.send_events:
evidence = Evidence(source)
for addr in sorted(services):
scan = ServiceScan(evidence, addr)
interface.service_scan(scan)
3 changes: 0 additions & 3 deletions tests/samples/shell-ss/Device.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ udp UNCONN 0 0
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:*
udp UNCONN 0 0 *:1194 *:*
udp UNCONN 0 0 [::1]:323 [::]:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:41337 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
tcp LISTEN 0 128 169.254.255.255:51337 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:27017 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
tcp ESTAB 0 0 169.254.255.255:51337 169.254.10.1:39236
tcp ESTAB 0 0 169.254.255.255:51337 169.254.10.2:56164
tcp SYN-RECV 0 0 65.21.253.97:80 104.223.42.139:10446
Expand Down
4 changes: 4 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def get_inspector(self):
"""Get inspector"""
return Inspector(self.get_system())

def get_hosts(self):
"""Get hosts"""
return [c for c in self.get_system().children if isinstance(c, Host)]


def simple_setup_1(external=False) -> SystemBackend:
sb = SystemBackend()
Expand Down
21 changes: 18 additions & 3 deletions tests/test_shell_ss.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import pathlib

from tcsfw.basics import Status
from tcsfw.batch_import import BatchImporter
from tcsfw.components import OperatingSystem
from tcsfw.property import PropertyKey
from tcsfw.verdict import Verdict
from tests.test_model import Setup

Expand All @@ -13,9 +12,25 @@ class Setup_1(Setup):
"""Setup for tests here"""
def __init__(self):
super().__init__()
self.device1 = self.system.device().hw("1:0:0:0:0:1")
self.device1 = self.system.device().ip("192.168.6.12")


def test_shell_ss_pass():
su = Setup_1()
BatchImporter(su.get_inspector()).import_batch(pathlib.Path("tests/samples/shell-ss"))
hs = su.get_hosts()
assert len(hs) == 3
h = hs[0]
assert len(h.children) == 4
s = h.children[0]
assert s.long_name() == "Device TCP:22"
assert s.status_verdict() == (Status.UNEXPECTED, Verdict.FAIL)
s = h.children[1]
assert s.long_name() == "Device TCP:41337"
assert s.status_verdict() == (Status.UNEXPECTED, Verdict.FAIL)
s = h.children[2]
assert s.long_name() == "Device UDP:1194"
assert s.status_verdict() == (Status.UNEXPECTED, Verdict.FAIL)
s = h.children[3]
assert s.long_name() == "Device UDP:123"
assert s.status_verdict() == (Status.UNEXPECTED, Verdict.FAIL)

0 comments on commit 0301ac0

Please sign in to comment.