簡述:
這個周末我安裝了Windows 10 Spring Update,并且使用新系統內置OpenSSH工具。
系統內置了openssh,win管理員再也不需要使用Putty以及PPK格式的秘鑰,我開始研究系統都新添加了什么新的功能,研究發包含ssh-agent.exe,
我在MSDN文章中找到關于Windows ssh-agent新的資料,并且這部分立即引起了我的注意:
過去我曾多次劫持SSH,所以我決定開始研究Windows如何“安全”地將私鑰存儲到這個新服務中。
我將在這篇文章中概述我的方法和步驟以找出答案。這是一個有趣的研究過程,我使用Powershell來完成。
OpenSSH
私鑰使用DPAPI進行保護并存儲在HKCU注冊表配置單元中。我在這里發布了一些PoC代碼來從注冊表中提取和重建RSA私鑰
我測試的第一件事是通常使用OpenSSH實用程序生成幾個密鑰對并將它們添加到ssh-agent中。
首先,我使用以下命令生成一些密碼保護的測試密鑰對ssh-keygen.exe。
然后確保ssh-agent服務正在運行,使用ssh-add將私鑰對加入正在運行的agent中。
運行會ssh-add.exe -L顯示當前由SSH代管理的密鑰。
最后,在將公鑰添加到Ubuntu機器后,我證實我可以從Windows 10進行SSH連接,而不需要解密我的私鑰(因為ssh-agent在后臺為我處理):
監控SSH Agent
為了弄清楚SSH Agent如何存儲和讀取我的私鑰,我探索了一下,并開始靜態檢查ssh-agent.exe。然而,我的靜態分析技術比較弱,所以我放棄了,決定動態地跟蹤這個過程,看看它在做什么。
我使用了Sysinternals中的procmon.exe,添加了過濾規則,過濾出進程名中包含“ssh”字符串的那些進程
隨著procmon捕獲事件,我再次使用SSH連接我的Ubuntu機器。仔細查看所有事件,我看到了ssh.exe打開與Ubuntu的TCP連接,然后終于看到ssh-agent.exe行動起來,并從注冊表中讀取一些值:
我注意到了兩件事:
1、ssh-agent.exe進程會讀取注冊表中的HKCUSoftwareOpenSSHAgentKeys;
2、讀取這些注冊表鍵值后,該進程會立刻打開dpapi.dll。
根據這些信息,我知道系統將受保護的某些數據存儲到注冊表中并進行讀取,并且ssh-agent使用的是微軟的Data Protection API.aspx)
測試注冊表值
果然,在注冊表中,我可以看到兩個我添加的密鑰ssh-add。密鑰名稱是公鑰的指紋,并且存在一些二進制數據塊:
我花了一個小時查看StackOverflow上的相關資料,終于成功通過PowerShell導出這些注冊表值并進行修改。其中comment字段為經過ASCII編碼的文本,對應我之前添加的秘鑰名:
而(default)值為一個字節數組,解碼后看不到任何有直觀意義的信息。我預感這些數據為“經過加密的”私鑰,我可以嘗試讀取并解密這段數據。我將這些數據賦值到一個PowerShell變量中:
解密私鑰
我對DPAPI并不是特別熟悉,但我知道有些后滲透利用工具會濫用這一功能來獲取敏感數據及憑據數據,因此有一些人已經實現了一些封裝包。Google一番后,我找到了atifaziz提供了一條線索,結果比我想象的還要簡單(從中我也知道為什么人們會喜歡使用PowerShell)。
我不知道這種方法能否可行,但還是嘗試使用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私鑰。
這會不會與我現有的二進制格式相同?我下載了那篇文章中提供的Python腳本,然后輸入我從Windows注冊表中提取的未經保護的base64數據:
的確成功了!我并不清楚原作者soleblaze如何找到二進制數據的正確格式,但還是向他表示誠摯的感謝,感謝他提供的Python工具以及發表的文章。
技術匯總
經過這些步驟,我們可以從注冊表中提取出私鑰,因此我將這些步驟匯總成兩個腳本,大家可以參考我的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"
我大量借用了soleblaze提供的parse_mem_python.py代碼,并且更新了Python3以用于下一個腳本:extractPrivateKeys.py。提供從Powershell腳本生成的JSON將輸出找到的所有RSA私鑰:
這些RSA私鑰都采用明文格式。即使我在創建私鑰的過程中添加了密碼保護,ssh-agent還是沒有將其加密存儲。
為了驗證私鑰的有效性,我將秘鑰拷貝回Kali系統中,驗證了秘鑰的指紋信息,并且可以使用該秘鑰來登錄SSH。
后續工作
我的PowerShell開發能力比較弱,因此公布的代碼仍屬于PoC范疇。其實完全可以使用PowerShell來完整重構秘鑰,我也沒有特別推崇使用Python,這次使用是因為soleblaze原始代碼采用的就是Python代碼,因此編寫起來更加方便。
隨著管理員在Windows 10中逐步開始使用OpenSSH,我希望這種技術能加入后續利用框架中,這些私鑰的價值很高,對滲透測試人員來說非常有用。
1024你懂的国产日韩欧美_亚洲欧美色一区二区三区_久久五月丁香合缴情网_99爱之精品网站
責任編輯:韓希宇
免責聲明:
中國電子銀行網發布的專欄、投稿以及征文相關文章,其文字、圖片、視頻均來源于作者投稿或轉載自相關作品方;如涉及未經許可使用作品的問題,請您優先聯系我們(聯系郵箱:cebnet@cfca.com.cn,電話:400-880-9888),我們會第一時間核實,謝謝配合。