這篇文章將為大家詳細講解有關怎樣從Windows 10 SSH-Agent中提取SSH私鑰,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
在這個周末我安裝了Windows 10 Spring Update,最令我期待的就是它的內置OpenSSH工具,這意味著Windows管理員不再需要使用Putty和PPK格式的密鑰了。隨后,我花了些時間來探索并了解該版本所支持的特性。最終沒有令我失望,我驚喜地看到ssh-agent.exe也被包含在內。在MSDN的一篇關于使用新Windows ssh-agent文章的以下部分,引起了我的注意:
過去我曾有過劫持ssh-agent.的相關經驗,并嘗試過一些有趣的測試,所以我決定開始查看Windows是如何“安全地”用這個新的服務來存儲您的私鑰的。我將在這篇文章中概述我的方法和步驟,這是一個非常有趣的過程。好了,話不多說讓我們開始我們的旅程吧!
私鑰由DPAPI保護并存儲在HKCU注冊表hive中。我在這里發布了一些PoC代碼,從注冊表中提取并重構RSA私鑰。
測試要做的第一件事就是使用OpenSSH生成幾個密鑰對并將它們添加到ssh-agent中。
首先,我使用ssh-keygen.exe生成了一些受密碼保護的測試密鑰對:
然后確保新的ssh-agent服務正在運行,并使用ssh-add將私鑰對添加到正在運行的agent中:
運行ssh-add.exe -L顯示當前由SSH agent管理的密鑰。
最后,在將公鑰添加到Ubuntu box之后,我驗證了我可以從Windows 10進入SSH,而不需要解密我的私鑰(因為ssh-agent正在為我處理):
為了了解SSH代理是如何存儲和讀取我的私鑰,我開始靜態檢查ssh-agent.exe。然而,我的靜態分析技能很弱,所以我放棄了,并最終決定采用動態跟蹤這個過程的方式,看看它在做什么。
我使用了Sysinternals的procmon.exe,并為包含“ssh”的任意進程名稱添加了一個過濾器。
隨著procmon捕獲事件,我再次進入我的Ubuntu機器。查看所有的事件,我看到ssh.exe打開了一個TCP連接到Ubuntu,以及ssh-agent.exe進入并從Registry中讀取了一些值:
這里有兩個非常重要的點:
進程ssh-agent.exe讀取來自HKCU\Software\OpenSSH\Agent\Keys的鍵值
讀取這些值后,立即打開了dpapi.dll。
正因為如此,我現在知道某種受保護的數據被存儲在注冊表中并從注冊表中被讀取,ssh-agent正在使用微軟的數據保護API。
果然,在注冊表中,可以看到我使用ssh-add添加的兩個鍵項。密鑰名稱是公開密鑰的指紋,并且存在一些二進制blobs:
我能夠pull注冊表值并操作它們?!白⑨尅弊侄沃皇茿SCII編碼文本,是我添加的密鑰的名稱:
(默認值)只是一個字節數組,沒有解碼出任何有意義的東西。我有一個預感,這是“加密”私鑰,那么我是否能pull并解密它呢。我把字節pull到了一個Powershell變量:
雖然我知道很多后利用工具可以濫用它來取出憑據,但我對DPAPI并不太熟悉,因此我也知道其他人可能已經實現了一個wrapper。通過Google搜索,我找到了一個簡單的單線程wrapper。
我仍然不知道這是否可行,但我試圖使用DPAPI去解除字節數組的保護。Base64編碼結果如下:
Add-Type -AssemblyName System.Security $unprotectedbytes = [Security.Cryptography.ProtectedData]::Unprotect($keybytes, $null, 'CurrentUser') [System.Convert]::ToBase64String($unprotectedbytes)
返回的Base64看起來不像是私鑰,但我只是為了好玩而解碼它,然而對于里面出現的“ssh-rsa”字符串我感到非常的驚喜。
這部分是我花時間最長的一部分。我知道我有某種鍵的二進制表示,但我無法找出格式或如何使用它。
我用openssl,puttygen和ssh-keygen來生成各種RSA密鑰,但從來沒有得到類似于我擁有的二進制文件的任何東西。
最后,在大量的Google之后,我從NetSPI找到了一篇關于從Linux上的ssh-agent的內存轉儲中取出OpenSSH私鑰的文章:https://blog.netspi.com/stealing-unencrypted-ssh-agent-keys-from-memory/
難道是二進制格式相同嗎?我從博客中獲取了Python腳本,并為它提供了我從Windows注冊表中獲得的不受保護的base64 blob:
可以正常工作了!我不知道原作者soleblaze是如何找出二進制數據的正確格式的,但在這里我要特別感謝他所做的以及他的分享!
在證明可以從注冊表中提取私鑰后,我將PoC分享到了GitHub。
第一個是Powershell腳本(extract_ssh_keys.ps1),用于查詢注冊表中被ssh-agent保存的任何密鑰。然后使用DPAPI與當前用戶上下文來解除二進制保護,并將其保存在Base64中。由于我不知道如何在Powershell中解析二進制數據,所以我把所有的密鑰保存到了一個JSON文件中,然后我可以在Python中導入。Powershell腳本只有幾行:
$path = "HKCU:\Software\OpenSSH\Agent\Keys\" $regkeys = Get-ChildItem $path | Get-ItemProperty if ($regkeys.Length -eq 0) { Write-Host "No keys in registry" exit } $keys = @() Add-Type -AssemblyName System.Security; $regkeys | ForEach-Object { $key = @{} $comment = [System.Text.Encoding]::ASCII.GetString($_.comment) Write-Host "Pulling key: " $comment $encdata = $_.'(default)' $decdata = [Security.Cryptography.ProtectedData]::Unprotect($encdata, $null, 'CurrentUser') $b64key = [System.Convert]::ToBase64String($decdata) $key[$comment] = $b64key $keys += $key } ConvertTo-Json -InputObject $keys | Out-File -FilePath './extracted_keyblobs.json' -Encoding ascii Write-Host "extracted_keyblobs.json written. Use Python script to reconstruct private keys: python extractPrivateKeys.py extracted_keyblobs.json"
我大量借用了parse_mem_python.py中的代碼,并將其更新為Python 3,用于下一個腳本:extractPrivateKeys.py。從Powershell腳本生成的JSON將輸出所有的RSA私鑰:
這些RSA私鑰是未加密的。雖然我創建它們時,添加了一個密碼,但它們使用ssh-agent未加密存儲,所以我不再需要密碼。
為了驗證,我將密鑰復制回了Kali linux box中驗證了指紋,并將其應用到了SSH中!
關于怎樣從Windows 10 SSH-Agent中提取SSH私鑰就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。