()
Inspect systemd service unit files
Inspect systemd service unit files
Inspect systemd service unit files
def uptux_check_services():
    """Inspect systemd service unit files"""
    # Define known Linux folders for storing service unit definitions
    units = set()
    mask = '*.service'
    units = find_system_files(known_dirs=SYSTEMD_DIRS,
                              search_mask=mask)

    tee("Found {} service units to analyse...\n".format(len(units)),
        box='ok')

    # Test for write access to any service files.
    # Will resolve symlinks to their target and also check for broken links.
    text = 'Found writeable service unit files:'
    text2 = 'Found writeable directories referred to by broken symlinks'
    box = 'vuln'
    tee("")
    tee("Checking permissions on service unit files...",
        box='ok')
    check_file_permissions(file_paths=units,
                           files_message_text=text,
                           dirs_message_text=text2,
                           message_box=box)

    # Only check relative paths if we can abuse them
    if SYSTEMD_PATH_WRITABLE:
        # Look for relative calls to binaries.
        # Example: ExecStart=somfolder/somebinary
        regex = re.compile(r'^Exec(?:Start|Stop|Reload)='
                           r'(?:@[^/]'    # special exec
                           r'|-[^/]'      # special exec
                           r'|\+[^/]'     # special exec
                           r'|![^/]'      # special exec
                           r'|!![^/]'     # special exec
                           r'|)'          # or maybe no special exec
                           r'[^/@\+!-]'   # not abs path or special exec
                           r'.*',         # rest of line
                           re.MULTILINE)
        text = ('Possible relative path in an Exec statement.\n'
                'Unless you have writeable systemd paths, you won\'t be able to'
                ' exploit this:')
        box = 'sus'
        tee("")
        tee("Checking for relative paths in service unit files [check 1]...",
            box='ok')
        regex_vuln_search(file_paths=units,
                          regex=regex,
                          message_text=text,
                          message_box=box)

        # Look for relative calls to binaries but invoked by an interpreter.
        # Example: ExecStart=/bin/sh -c 'somefolder/somebinary'
        regex = re.compile(r'^Exec(?:Start|Stop|Reload)='
                           r'(?:@[^/]'    # special exec
                           r'|-[^/]'      # special exec
                           r'|\+[^/]'     # special exec
                           r'|![^/]'      # special exec
                           r'|!![^/]'     # special exec
                           r'|)'          # or maybe no special exec
                           r'.*?(?:/bin/sh|/bin/bash) '   # interpreter
                           r'(?:[\'"]|)'  # might have quotes
                           r'(?:-[a-z]+|)'# might have params
                           r'(?:[ ]+|)'   # might have more spaces now
                           r'[^/-]'       # not abs path or param
                           r'.*',         # rest of line
                           re.MULTILINE)
        text = ('Possible relative path invoked with an interpreter in an'
                ' Exec statement.\n'
                'Unless you have writable systemd paths, you won\'t be able to'
                ' exploit this:')
        box = 'sus'
        tee("")
        tee("Checking for relative paths in service unit files [check 2]...",
            box='ok')
        regex_vuln_search(file_paths=units,
                          regex=regex,
                          message_text=text,
                          message_box=box)

    # Check for write access to any commands invoked by Exec statements.
    # Thhs regex below is used to extract command lines.
    regex = re.compile(r'^Exec.*?=[!@+-]*(.*?$)',
                       re.MULTILINE)
    # We don't pass message info to this function as we need to perform more
    # processing on the output to determine what is writeable.
    tee("")
    tee("Checking for write access to commands referenced in service files...",
        box='ok')
    service_commands = regex_vuln_search(file_paths=units,
                                         regex=regex,
                                         message_text='',
                                         message_box='')

    # Another helper function to take the extracted commands and check for
    # write permissions.
    text = 'You have write access to commands referred to in service files:'
    box = 'vuln'
    check_command_permission(commands=service_commands,
                             message_text=text,
                             message_box=box)
def uptux_check_services ( ) : # Define known Linux folders for storing service unit definitions units = set ( ) mask = '*.service' units = find_system_files ( known_dirs = SYSTEMD_DIRS , search_mask = mask ) tee ( "Found {} service units to analyse...\n" . format ( len ( units ) ) , box = 'ok' ) # Test for write access to any service files. # Will resolve symlinks to their target and also check for broken links. text = 'Found writeable service unit files:' text2 = 'Found writeable directories referred to by broken symlinks' box = 'vuln' tee ( "" ) tee ( "Checking permissions on service unit files..." , box = 'ok' ) check_file_permissions ( file_paths = units , files_message_text = text , dirs_message_text = text2 , message_box = box ) # Only check relative paths if we can abuse them if SYSTEMD_PATH_WRITABLE : # Look for relative calls to binaries. # Example: ExecStart=somfolder/somebinary regex = re . compile ( r'^Exec(?:Start|Stop|Reload)=' r'(?:@[^/]' # special exec r'|-[^/]' # special exec r'|\+[^/]' # special exec r'|![^/]' # special exec r'|!![^/]' # special exec r'|)' # or maybe no special exec r'[^/@\+!-]' # not abs path or special exec r'.*' , # rest of line re . MULTILINE ) text = ( 'Possible relative path in an Exec statement.\n' 'Unless you have writeable systemd paths, you won\'t be able to' ' exploit this:' ) box = 'sus' tee ( "" ) tee ( "Checking for relative paths in service unit files [check 1]..." , box = 'ok' ) regex_vuln_search ( file_paths = units , regex = regex , message_text = text , message_box = box ) # Look for relative calls to binaries but invoked by an interpreter. # Example: ExecStart=/bin/sh -c 'somefolder/somebinary' regex = re . compile ( r'^Exec(?:Start|Stop|Reload)=' r'(?:@[^/]' # special exec r'|-[^/]' # special exec r'|\+[^/]' # special exec r'|![^/]' # special exec r'|!![^/]' # special exec r'|)' # or maybe no special exec r'.*?(?:/bin/sh|/bin/bash) ' # interpreter r'(?:[\'"]|)' # might have quotes r'(?:-[a-z]+|)' # might have params r'(?:[ ]+|)' # might have more spaces now r'[^/-]' # not abs path or param r'.*' , # rest of line re . MULTILINE ) text = ( 'Possible relative path invoked with an interpreter in an' ' Exec statement.\n' 'Unless you have writable systemd paths, you won\'t be able to' ' exploit this:' ) box = 'sus' tee ( "" ) tee ( "Checking for relative paths in service unit files [check 2]..." , box = 'ok' ) regex_vuln_search ( file_paths = units , regex = regex , message_text = text , message_box = box ) # Check for write access to any commands invoked by Exec statements. # Thhs regex below is used to extract command lines. regex = re . compile ( r'^Exec.*?=[!@+-]*(.*?$)' , re . MULTILINE ) # We don't pass message info to this function as we need to perform more # processing on the output to determine what is writeable. tee ( "" ) tee ( "Checking for write access to commands referenced in service files..." , box = 'ok' ) service_commands = regex_vuln_search ( file_paths = units , regex = regex , message_text = '' , message_box = '' ) # Another helper function to take the extracted commands and check for # write permissions. text = 'You have write access to commands referred to in service files:' box = 'vuln' check_command_permission ( commands = service_commands , message_text = text , message_box = box )