forked from p15670423/monkey
Merge pull request #1706 from guardicore/1603-refactor-smb-fingerprinter
1603 refactor smb fingerprinter
This commit is contained in:
commit
1dc08e2087
|
@ -22,6 +22,7 @@ from infection_monkey.network.firewall import app as firewall
|
||||||
from infection_monkey.network.http_fingerprinter import HTTPFingerprinter
|
from infection_monkey.network.http_fingerprinter import HTTPFingerprinter
|
||||||
from infection_monkey.network.info import get_local_network_interfaces
|
from infection_monkey.network.info import get_local_network_interfaces
|
||||||
from infection_monkey.network.mssql_fingerprinter import MSSQLFingerprinter
|
from infection_monkey.network.mssql_fingerprinter import MSSQLFingerprinter
|
||||||
|
from infection_monkey.network.smb_fingerprinter import SMBFingerprinter
|
||||||
from infection_monkey.payload.ransomware.ransomware_payload import RansomwarePayload
|
from infection_monkey.payload.ransomware.ransomware_payload import RansomwarePayload
|
||||||
from infection_monkey.puppet.puppet import Puppet
|
from infection_monkey.puppet.puppet import Puppet
|
||||||
from infection_monkey.system_singleton import SystemSingleton
|
from infection_monkey.system_singleton import SystemSingleton
|
||||||
|
@ -186,9 +187,11 @@ class InfectionMonkey:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_puppet() -> IPuppet:
|
def _build_puppet() -> IPuppet:
|
||||||
puppet = Puppet()
|
puppet = Puppet()
|
||||||
|
|
||||||
puppet.load_plugin("elastic", ElasticSearchFingerprinter(), PluginType.FINGERPRINTER)
|
puppet.load_plugin("elastic", ElasticSearchFingerprinter(), PluginType.FINGERPRINTER)
|
||||||
puppet.load_plugin("http", HTTPFingerprinter(), PluginType.FINGERPRINTER)
|
puppet.load_plugin("http", HTTPFingerprinter(), PluginType.FINGERPRINTER)
|
||||||
puppet.load_plugin("mssql", MSSQLFingerprinter(), PluginType.FINGERPRINTER)
|
puppet.load_plugin("mssql", MSSQLFingerprinter(), PluginType.FINGERPRINTER)
|
||||||
|
puppet.load_plugin("smb", SMBFingerprinter(), PluginType.FINGERPRINTER)
|
||||||
|
|
||||||
puppet.load_plugin("ransomware", RansomwarePayload(), PluginType.PAYLOAD)
|
puppet.load_plugin("ransomware", RansomwarePayload(), PluginType.PAYLOAD)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
from odict import odict
|
from odict import odict
|
||||||
|
|
||||||
from infection_monkey.network.HostFinger import HostFinger
|
from infection_monkey.i_puppet import (
|
||||||
|
FingerprintData,
|
||||||
|
IFingerprinter,
|
||||||
|
PingScanData,
|
||||||
|
PortScanData,
|
||||||
|
PortStatus,
|
||||||
|
)
|
||||||
|
|
||||||
|
SMB_DISPLAY_NAME = "SMB"
|
||||||
SMB_PORT = 445
|
SMB_PORT = 445
|
||||||
SMB_SERVICE = "tcp-445"
|
SMB_SERVICE = "tcp-445"
|
||||||
|
|
||||||
|
@ -62,7 +70,7 @@ class SMBNego(Packet):
|
||||||
self.fields["bcc"] = struct.pack("<h", len(self.fields["data"].to_byte_string()))
|
self.fields["bcc"] = struct.pack("<h", len(self.fields["data"].to_byte_string()))
|
||||||
|
|
||||||
|
|
||||||
class SMBNegoFingerData(Packet):
|
class SMBNegoFingerprintData(Packet):
|
||||||
fields = odict(
|
fields = odict(
|
||||||
[
|
[
|
||||||
("separator1", b"\x02"),
|
("separator1", b"\x02"),
|
||||||
|
@ -89,7 +97,7 @@ class SMBNegoFingerData(Packet):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SMBSessionFingerData(Packet):
|
class SMBSessionFingerprintData(Packet):
|
||||||
fields = odict(
|
fields = odict(
|
||||||
[
|
[
|
||||||
("wordcount", b"\x0c"),
|
("wordcount", b"\x0c"),
|
||||||
|
@ -127,25 +135,34 @@ class SMBSessionFingerData(Packet):
|
||||||
self.fields["bcc1"] = struct.pack("<i", len(self.fields["Data"]))[:2]
|
self.fields["bcc1"] = struct.pack("<i", len(self.fields["Data"]))[:2]
|
||||||
|
|
||||||
|
|
||||||
class SMBFinger(HostFinger):
|
class SMBFingerprinter(IFingerprinter):
|
||||||
_SCANNED_SERVICE = "SMB"
|
def get_host_fingerprint(
|
||||||
|
self,
|
||||||
|
host: str,
|
||||||
|
_ping_scan_data: PingScanData,
|
||||||
|
port_scan_data: Dict[int, PortScanData],
|
||||||
|
_options: Dict,
|
||||||
|
) -> FingerprintData:
|
||||||
|
services = {}
|
||||||
|
smb_service = {
|
||||||
|
"display_name": SMB_DISPLAY_NAME,
|
||||||
|
"port": SMB_PORT,
|
||||||
|
}
|
||||||
|
os_type = None
|
||||||
|
os_version = None
|
||||||
|
|
||||||
def __init__(self):
|
if (SMB_PORT not in port_scan_data) or (port_scan_data[SMB_PORT].status != PortStatus.OPEN):
|
||||||
from infection_monkey.config import WormConfiguration
|
return FingerprintData(None, None, services)
|
||||||
|
|
||||||
self._config = WormConfiguration
|
logger.debug(f"Fingerprinting potential SMB port {SMB_PORT} on {host}")
|
||||||
|
|
||||||
def get_host_fingerprint(self, host):
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
s.settimeout(0.7)
|
s.settimeout(0.7)
|
||||||
s.connect((host.ip_addr, SMB_PORT))
|
s.connect((host, SMB_PORT))
|
||||||
|
|
||||||
self.init_service(host.services, SMB_SERVICE, SMB_PORT)
|
|
||||||
|
|
||||||
h = SMBHeader(cmd=b"\x72", flag1=b"\x18", flag2=b"\x53\xc8")
|
h = SMBHeader(cmd=b"\x72", flag1=b"\x18", flag2=b"\x53\xc8")
|
||||||
n = SMBNego(data=SMBNegoFingerData())
|
n = SMBNego(data=SMBNegoFingerprintData())
|
||||||
n.calculate()
|
n.calculate()
|
||||||
|
|
||||||
packet_ = h.to_byte_string() + n.to_byte_string()
|
packet_ = h.to_byte_string() + n.to_byte_string()
|
||||||
|
@ -155,7 +172,7 @@ class SMBFinger(HostFinger):
|
||||||
|
|
||||||
if data[8:10] == b"\x72\x00":
|
if data[8:10] == b"\x72\x00":
|
||||||
header = SMBHeader(cmd=b"\x73", flag1=b"\x18", flag2=b"\x17\xc8", uid=b"\x00\x00")
|
header = SMBHeader(cmd=b"\x73", flag1=b"\x18", flag2=b"\x17\xc8", uid=b"\x00\x00")
|
||||||
body = SMBSessionFingerData()
|
body = SMBSessionFingerprintData()
|
||||||
body.calculate()
|
body.calculate()
|
||||||
|
|
||||||
packet_ = header.to_byte_string() + body.to_byte_string()
|
packet_ = header.to_byte_string() + body.to_byte_string()
|
||||||
|
@ -173,17 +190,17 @@ class SMBFinger(HostFinger):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.debug(f'os_version: "{os_version}", service_client: "{service_client}"')
|
||||||
|
|
||||||
if os_version.lower() != "unix":
|
if os_version.lower() != "unix":
|
||||||
host.os["type"] = "windows"
|
os_type = "windows"
|
||||||
else:
|
else:
|
||||||
host.os["type"] = "linux"
|
os_type = "linux"
|
||||||
|
|
||||||
host.services[SMB_SERVICE]["name"] = service_client
|
smb_service["name"] = service_client
|
||||||
if "version" not in host.os:
|
|
||||||
host.os["version"] = os_version
|
|
||||||
|
|
||||||
return True
|
services[SMB_SERVICE] = smb_service
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.debug("Error getting smb fingerprint: %s", exc)
|
logger.debug("Error getting smb fingerprint: %s", exc)
|
||||||
|
|
||||||
return False
|
return FingerprintData(os_type, os_version, services)
|
Loading…
Reference in New Issue