# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)


function Get-ShadowFileCredentials {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$FilePath
    )

    # Initialize an array to store extracted user data
    $credentials = @()

    # Check if the file exists
    if (-Not (Test-Path -Path $FilePath)) {
        Write-Error "File not found: $FilePath"
        return
    }

    # Read the shadow file
    $shadowFile = Get-Content -Path $FilePath

    # Parse each line in the shadow file
    foreach ($line in $shadowFile) {
        # Ignore empty lines or comments (if any)
        if ($line -match '^\s*$' -or $line -match '^\s*#') {
            continue
        }

        # Split the line into fields using colon as a delimiter
        $fields = $line -split ':'

        # Extract username and password hash
        $username = $fields[0]
        $passwordHash = $fields[1]

        # Create an object to store the extracted information
        $userObject = [PSCustomObject]@{
            Username     = $username
            PasswordHash = $passwordHash
        }

        # Add the object to the array
        $credentials += $userObject
    }

    # Output the array of credentials
    return $credentials
}

# Example usage:
$shadowData = Get-ShadowFileCredentials -FilePath "c:\temp\configs\shadow"
$shadowData | Format-Table -AutoSize


<# shadow - linux password file

root:$6$examplehash$E5iNRLtC5/j/kCkRhYlOro.Y9PzE0Gv8jlsfLZUNwlEm7HMBZSO9.mUvefOrKT6BjKSO4obQ.EtCZKhQgmgwV0:19000:0:99999:7:::
user1:$6$examplehash$OwhxlyS5hoxfFE4tmtyOR8Hw1k8PLqokP9FYxYP8QMG3wO0u.0Xvd4g/0Udr6BQZilJk4k7XwlxJ6p0RJ2IL5/:19000:0:99999:7:::
nobody:*:19000:0:99999:7:::
daemon:*:19000:0:99999:7:::

#>