Browse Source

add lib function documentation

fix some library functions

documented functions:
get_smb_version
get_smb_platform_data
invalid_smb_version
get_rnd_os
check_platform
get_ip_range
generate_source_port_from_platform
get_filetime_format
get_rnd_boot_time

modified functions:
get_smb_version
get_smb_platform_data
invalid_smb_version
get_filetime_format
get_rnd_boot_time
Stefano Acquaviti 6 years ago
parent
commit
de5b6d0b11
3 changed files with 74 additions and 27 deletions
  1. 4 3
      code/Attack/SMBScanAttack.py
  2. 21 8
      code/ID2TLib/SMBLib.py
  3. 49 16
      code/ID2TLib/Utility.py

+ 4 - 3
code/Attack/SMBScanAttack.py

@@ -72,7 +72,6 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         else:
             ip_destinations = all_ips
         self.add_param_value(Param.IP_DESTINATION, ip_destinations)
-        # FIXME: MAYBE REMOVE/CHANGE THIS MAC STUFF
         destination_mac = []
         for ip in ip_destinations:
             destination_mac.append(self.statistics.get_mac_address(str(ip)))
@@ -126,6 +125,8 @@ class SMBScanAttack(BaseAttack.BaseAttack):
 
         def get_ip_data(ip_address: str):
             """
+            Gets the MSS, TTL and Windows Size values of a given IP
+
             :param ip_address: the ip of which (packet-)data shall be returned
             :return: MSS, TTL and Window Size values of the given IP
             """
@@ -178,10 +179,10 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         # Check smb version
         smb_version = self.get_param_value(Param.PROTOCOL_VERSION)
         if smb_version not in smb_versions:
-            invalid_version(smb_version)
+            invalid_smb_version(smb_version)
         hosting_version = self.get_param_value(Param.HOSTING_VERSION)
         if hosting_version not in smb_versions:
-            invalid_version(hosting_version)
+            invalid_smb_version(hosting_version)
         # Check source platform
         src_platform = self.get_param_value(Param.SOURCE_PLATFORM).lower()
         packets = []

+ 21 - 8
code/ID2TLib/SMBLib.py

@@ -53,6 +53,13 @@ security_blob_macos = "\x60\x7e\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x74\x30\x72\
 
 
 def get_smb_version(platform: str):
+    """
+    Returns SMB version based on given platform
+
+    :param platform: the platform as string
+    :return: SMB version as string
+    """
+    check_platform(platform)
     if platform is "linux":
         return random.choice(list(smb_versions_per_samba.values()))
     elif platform is "macos":
@@ -61,12 +68,14 @@ def get_smb_version(platform: str):
         return smb_versions_per_win[platform]
 
 
-def get_rnd_smb_version():
-    platform = get_rnd_os()
-    return get_smb_version(platform)
+def get_smb_platform_data(platform: str, timestamp: float):
+    """
+    Gets platform-dependent data for SMB 2 packets
 
-
-def get_smb_platform_data(platform: str, timestamp=time.time()):
+    :param platform: the platform for which to get SMB 2 packet data
+    :param timestamp: a timestamp for calculating the boot-time
+    :return: server_guid, security_blob, capabilities, data_size and server_start_time of the given platform
+    """
     check_platform(platform)
     if platform == "linux":
         server_guid = "ubuntu"
@@ -85,12 +94,16 @@ def get_smb_platform_data(platform: str, timestamp=time.time()):
         security_blob = security_blob_windows
         capabilities = 0x7
         data_size = 0x100000
-        server_start_time = get_rnd_boot_time(timestamp)
+        server_start_time = get_filetime_format(get_rnd_boot_time(timestamp))
     return server_guid, security_blob, capabilities, data_size, server_start_time
 
 
-# Check smb version
-def invalid_version(version: str):
+def invalid_smb_version(version: str):
+    """
+    Prints an error and exits
+
+    :param version: the invalid SMB
+    """
     print("\nInvalid smb version: " + version +
           "\nPlease select one of the following versions: ", smb_versions)
     exit(1)

+ 49 - 16
code/ID2TLib/Utility.py

@@ -10,12 +10,23 @@ platforms = {"win7", "win10", "winxp", "win8.1", "macos", "linux", "win8", "winv
 
 
 def get_rnd_os():
+    """
+    Chooses random platform over an operating system probability distribution
+
+    :return: random platform as string
+    """
     os_dist = Lea.fromValFreqsDict({"win7": 48.43, "win10": 27.99, "winxp": 6.07, "win8.1": 6.07, "macos": 5.94,
                                     "linux": 3.38, "win8": 1.35, "winvista": 0.46, "winnt": 0.31})
     return os_dist.random()
 
 
 def check_platform(platform: str):
+    """
+    Checks if the given platform is currently supported
+    if not exits with error
+
+    :param platform: the platform, which should be validated
+    """
     if platform not in platforms:
         print("\nERROR: Invalid platform: " + platform + "." +
               "\n Please select one of the following platforms: ", platforms)
@@ -23,6 +34,13 @@ def check_platform(platform: str):
 
 
 def get_ip_range(start_ip: str, end_ip: str):
+    """
+    Generates a list of IPs of a given range. If the start_ip is greater than the end_ip, the reverse range is generated
+
+    :param start_ip: the start_ip of the desired IP-range
+    :param end_ip:  the end_ip of the desired IP-range
+    :return: a list of all IPs in the desired IP-range, including start-/end_ip
+    """
     start = ipaddress.ip_address(start_ip)
     end = ipaddress.ip_address(end_ip)
     ips = []
@@ -40,6 +58,13 @@ def get_ip_range(start_ip: str, end_ip: str):
 
 
 def generate_source_port_from_platform(platform: str, previousPort=0):
+    """
+    Generates the next source port according to the TCP-port-selection strategy of the given platform
+
+    :param platform: the platform for which to generate source ports
+    :param previousPort: the previously used/generated source port. Must be 0 if no port was generated before
+    :return: the next source port for the given platform
+    """
     check_platform(platform)
     if platform in {"winnt", "winxp", "win2000"}:
         if (previousPort == 0) or (previousPort + 1 > 5000):
@@ -55,29 +80,37 @@ def generate_source_port_from_platform(platform: str, previousPort=0):
             return previousPort + 1
 
 
-# FIXME: rework copy-pasted code
-# source: http://reliablybroken.com/b/2009/09/working-with-active-directory-filetime-values-in-python/
-# WORK IN PROGRESS
 def get_filetime_format(timestamp):
-    EPOCH_AS_FILETIME = 116444736000000000  # January 1, 1970 as MS file time
-    HUNDREDS_OF_NANOSECONDS = 10000000
+    """
+    Converts a timestamp into MS FILETIME format
+
+    :param timestamp: a timestamp in seconds
+    :return: MS FILETIME timestamp
+    """
     boot_datetime = datetime.fromtimestamp(timestamp)
-    if (boot_datetime.tzinfo is None) or (boot_datetime.tzinfo.utcoffset(boot_datetime) is None):
+    if boot_datetime.tzinfo is None or boot_datetime.tzinfo.utcoffset(boot_datetime) is None:
         boot_datetime = boot_datetime.replace(tzinfo=boot_datetime.tzname())
-    boot_filetime = EPOCH_AS_FILETIME + (timegm(boot_datetime.timetuple()) * HUNDREDS_OF_NANOSECONDS)
+    boot_filetime = 116444736000000000 + (timegm(boot_datetime.timetuple()) * 10000000)
     return boot_filetime + (boot_datetime.microsecond * 10)
 
 
 def get_rnd_boot_time(timestamp, platform="winxp"):
+    """
+    Generates a random boot time based on a given timestamp and operating system
+
+    :param timestamp: a timestamp in seconds
+    :param platform: a platform as string as specified in check_platform above. default is winxp. this param is optional
+    :return: timestamp of random boot time in seconds since EPOCH
+    """
     check_platform(platform)
-    # FIXME: create probability distribution for each OS
     if platform is "linux":
-        # four years
-        timestamp -= randint(0, 126144000)
-    if platform is "macOS":
-        # three months
-        timestamp -= randint(0, 7884000)
+        uptime_in_days = Lea.fromValFreqsDict({3: 50, 7: 25, 14: 12.5, 31: 6.25, 92: 3.125, 183: 1.5625,
+                                               365: 0.78125, 1461: 0.390625, 2922: 0.390625})
+    elif platform is "macos":
+        uptime_in_days = Lea.fromValFreqsDict({7: 50, 14: 25, 31: 12.5, 92: 6.25, 183: 3.125, 365: 3.076171875,
+                                               1461: 0.048828125})
     else:
-        # one month
-        timestamp -= randint(0, 2678400)
-    return get_filetime_format(timestamp)
+        uptime_in_days = Lea.fromValFreqsDict({3: 50, 7: 25, 14: 12.5, 31: 6.25, 92: 3.125, 183: 1.5625,
+                                               365: 0.78125, 1461: 0.78125})
+    timestamp -= randint(0, uptime_in_days.random()*86400)
+    return timestamp