SSH Özel Anahtarlarını Windows 10 ssh-agent’tan Çıkarma


Bu hafta sonu Windows 10 Bahar Güncellemesini yükledim ve yeni yerleşik OpenSSH araçlarıyla oynamaya başlayacağım için oldukça heyecanlıydım.

Windows yöneticilerinin artık Putty ve PPK formatlı anahtarları kullanması gerekmediği için OpenSSH’yi Windows’ta yerel olarak kullanmak harika. Etrafta dolaşıp hangi özelliklerin desteklendiğine dair daha fazla bilgi okumaya başladım ve şunu görünce hoş bir sürpriz yaşadım: ssh-agent.exe dahildir.

Bu MSDN makalesinde yeni Windows ssh-agent’ın kullanımına ilişkin bazı referanslar buldum ve bu bölüm hemen dikkatimi çekti:

Özel anahtarları güvenli bir şekilde saklayın

Geçmişte SSH aracılarının ele geçirilmesiyle çok eğlenmiştim, bu yüzden Windows’un bu yeni hizmetle özel anahtarlarınızı nasıl “güvenli bir şekilde” sakladığını görmeye karar verdim.

Bu yazıda metodolojimi ve bunu çözmeye yönelik adımları özetleyeceğim. Bu eğlenceli bir araştırma yolculuğuydu ve PowerShell ile çalışma konusunda daha iyi hale geldim.

tl;doktor

Özel anahtarlar DPAPI ile korunur ve HKCU kayıt defteri kovanında saklanır. RSA özel anahtarını kayıt defterinden çıkarmak ve yeniden oluşturmak için burada bazı PoC kodları yayınladım

Test ettiğim ilk şey, birkaç anahtar çifti oluşturmak için normal olarak OpenSSH yardımcı programlarını kullanmak ve bunları ssh aracısına eklemekti.

İlk olarak, kullanarak bazı şifre korumalı test anahtar çiftleri oluşturdum. ssh-keygen.exe:

Powershell ssh-keygen

Sonra yeni olduğundan emin oldum. ssh-agent hizmet çalışıyordu ve özel anahtar çiftlerini kullanarak çalışan aracıya ekledi ssh-add:

Powershell ssh-ekleme

Koşma ssh-add.exe -L o anda SSH aracısı tarafından yönetilen anahtarları gösterir.

Son olarak, genel anahtarları bir Ubuntu kutusuna ekledikten sonra, özel anahtarlarımın şifresini çözmeye gerek kalmadan Windows 10’dan SSH girişi yapabileceğimi doğruladım (çünkü ssh-agent bununla benim için ilgileniyor):

Powershell SSH'den Ubuntu'ya

SSH Aracısının özel anahtarlarımı nasıl sakladığını ve okuduğunu anlamak için biraz araştırdım ve statik olarak inceleyerek başladım. ssh-agent.exe. Ancak statik analiz becerilerimin çok zayıf olduğu ortaya çıktı, bu yüzden pes ettim ve süreci dinamik olarak izlemeye ve ne yaptığını görmeye karar verdim.

kullandım procmon.exe Sysinternals’dan “ssh” içeren herhangi bir işlem adı için bir filtre eklendi.

İle procmon Olayları yakaladıktan sonra tekrar SSH’yi Ubuntu makineme bağladım. Bütün olaylara baktığımda şunu gördüm: ssh.exe Ubuntu’ya bir TCP bağlantısı açın ve sonunda gördüm ssh-agent.exe harekete geçin ve Kayıt Defterinden bazı değerleri okuyun:

SSH Procmonu

Aklıma iki şey geldi:

  • süreç ssh-agent.exe HKCU\Software\OpenSSH\Agent\Keys’den değerleri okur
  • Bu değerleri okuduktan sonra hemen açılıyor dpapi.dll

Bundan dolayı artık bir tür korumalı verinin Kayıt Defterinde saklandığını ve Kayıt Defterinden okunduğunu biliyordum ve ssh-agent Microsoft’un Veri Koruma API’sini kullanıyordu

Tabii ki, Kayıt Defterine baktığımda, kullanarak eklediğim anahtarlar için iki giriş görebiliyordum. ssh-add. Anahtar adları genel anahtarın parmak izleriydi ve birkaç ikili blob mevcuttu:

Kayıt SSH Girişleri

Kayıt SSH Değerleri

Kendime PowerShell’in çirkin sözdizimini (gelenek olduğu gibi) hatırlatmak için StackOverflow’u bir saat okuduktan sonra, kayıt defteri değerlerini alıp bunları değiştirebildim. “Yorum” alanı yalnızca ASCII kodlu metindi ve eklediğim anahtarın adıydı:

Powershell Reg Yorumu

(default) değer yalnızca anlamlı bir şeyin kodunu çözemeyen bir bayt dizisiydi. Eğer onu çekip şifresini nasıl çözeceğimi bulabilirsem, bunun “şifreli” özel anahtar olduğuna dair bir önsezim vardı. Baytları bir Powershell değişkenine çektim:

Powershell anahtar baytları

Her ne kadar birçok post-sömürme aracının sırları ve kimlik bilgilerini ortaya çıkarmak için onu kötüye kullandığını bilsem de DPAPI’ye pek aşina değildim, dolayısıyla diğer insanların muhtemelen bir sarmalayıcı uyguladığını biliyordum. Biraz Googling bana, hayal ettiğimden çok daha basit, tifaziz’in basit bir oneliner’ını buldu (tamam, sanırım insanların neden Powershell’i sevdiğini anlıyorum…. ;))

Bunun işe yarayıp yaramayacağını hâlâ bilmiyordum ama DPAPI kullanarak bayt dizisinin korumasını kaldırmaya çalıştım. Belki mükemmel biçimde oluşturulmuş bir OpenSSH özel anahtarının geri geleceğini umuyordum, bu yüzden sonucu base64 ile kodladım:

1
2
3
4
Add-Type -AssemblyName System.Security
$unprotectedbytes = [Security.Cryptography.ProtectedData]::Unprotect($keybytes, $null, 'CurrentUser')

[System.Convert]::ToBase64String($unprotectedbytes)

Geri dönen Base64, özel bir anahtar gibi görünmüyordu, ama yine de sırf eğlence olsun diye şifresini çözdüm ve orada “ssh-rsa” dizesini gördüğümde çok hoş bir sürpriz yaşadım! Doğru yolda olmam gerekiyordu.

Baz 64'ün kodu çözüldü

Bu kısım aslında en uzun zamanımı aldı. Bir anahtarın bir tür ikili temsiline sahip olduğumu biliyordum, ancak formatı veya nasıl kullanılacağını çözemedim.

Çeşitli RSA anahtarları oluşturmakla uğraştım openssl, puttygen Ve ssh-keygenancak sahip olduğum ikili dosyaya benzeyecek hiçbir şey bulamadım.

Sonunda, çok fazla Google’da arama yaptıktan sonra, NetSPI’den, OpenSSH özel anahtarlarının bellek dökümlerinden çıkarılmasıyla ilgili harika bir blog yazısı buldum. ssh-agent Linux’ta: https://blog.netspi.com/stealing-unencrypted-ssh-agent-keys-from-memory/

İkili format aynı olabilir mi? Blogdan bağlantısı verilen Python betiğini indirdim ve Windows kayıt defterinden aldığım korumasız base64 blob’unu besledim:

ayrıştırma_mem.py

İşe yaradı! Orijinal yazar soleblaze’in ikili verinin doğru formatını nasıl bulduğuna dair hiçbir fikrim yok, ancak yaptığı ve paylaştığı için çok müteşekkirim. Harika Python aracı ve blog yazısı için tüm övgüler kendisine aittir.

Kayıt defterinden özel bir anahtar çıkarmanın mümkün olduğunu kendime kanıtladıktan sonra hepsini iki komut dosyasında bir araya getirdim.

GitHub Deposu

Birincisi bir Powershell betiğidir (extract_ssh_keys.ps1) içinde kayıtlı anahtarlar için Kayıt Defterini sorgulayan ssh-agent. Daha sonra ikili dosyanın korumasını kaldırmak ve Base64’e kaydetmek için mevcut kullanıcı bağlamıyla DPAPI’yi kullanır. Powershell’de İkili verileri ayrıştırmaya nasıl başlayacağımı bile bilmediğim için, tüm anahtarları daha sonra Python’a aktarabileceğim bir JSON dosyasına kaydettim. Powershell betiği yalnızca birkaç satırdan oluşur:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$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"

Kodu büyük ölçüde ödünç aldım parse_mem_python.py soleblaze tarafından oluşturuldu ve bir sonraki komut dosyası için Python3’ü kullanacak şekilde güncellendi: extractPrivateKeys.py. Powershell betiğinden oluşturulan JSON’u beslemek, bulunan tüm RSA özel anahtarlarının çıktısını alacaktır:

Özel anahtarların çıkarılması

Bu RSA özel anahtarları şifrelenmemiş. Onları oluşturduğumda bir şifre eklemiş olmama rağmen, şifrelenmemiş olarak saklanıyorlar. ssh-agent bu yüzden artık şifreye ihtiyacım yok.

Doğrulamak için anahtarı bir Kali linux kutusuna kopyaladım, parmak izini doğruladım ve bunu SSH’de kullandım!

Anahtarı kullanma

Sonraki Adımlar

Açıkçası PowerShell-fu’m zayıf ve yayınladığım kod daha çok PoC için. Özel anahtarları tamamen PowerShell’de yeniden oluşturmak muhtemelen mümkündür. Ayrıca Python kodu için de kredi almıyorum – bunların hepsi onun orijinal uygulaması için tek başına alevlenmeli.

Ayrıca bunun silah haline getirilip kullanım sonrası çerçevelere eklendiğini de görmeyi çok isterim çünkü Windows 10’da yöneticiler tarafından çok daha fazla OpenSSH kullanımı görmeye başlayacağımızı düşünüyorum ve bu anahtarların redteamcılar ve pentester’lar için çok değerli olabileceğinden eminim 🙂

Geri bildirim ve yorumlar hoş geldiniz!

-ropnop’un tadını çıkarın


Ayrıca bakınız



Source link