Powershell, Microsoft tarafından sistem konfigürasyonlarının yönetilebilmesi amacıyla sunulan bir komut satırı aracı ve aynı zamanda bir programlama dilidir. Powershell, Windows 7 işletim sisteminden itibaren, tüm işletim sistemi versiyonlarına entegre olarak gelir. Windows işletim sistemlerinin tam kontrolünü sağlama olanağı sunması ve kullanım kolaylığı nedeniyle sistem yönetiminin önemli bir parçasıdır.
Powershell saldırganlar tarafından yaygın olarak Post-Exploitation işlemleri gerçekleştirmek amacıyla kullanılmaktadır. Bunun en önemli sebebi, Powershell’in Windows işletim sisteminin bir parçası olmasıdır. Bu nedenle Powershell, saldırganların hedef sistem üzerinde normal bir kullanıcı gibi hareket etmesine olanak verir. Powershell’den yararlanan bir saldırgan, işletim sistemi üzerinde zararlı komutlar çalıştırabilir ve bu işlemleri bir kullanıcı kimliği ile gerçekleştirerek güvenlik önlemlerini atlatabilir. Ayrıca Powershell üzerinden gerçekleştirilen işlemlerin sadece bellekte çalışması nedeniyle, Powershell saldırganların fileless malware yazılımları kullanmalarına olanak vermektedir.
Bu yazıda, hedef sistem üzerinden bir Powershell oturumu elde etmeye çalışan ve sistem üzerinde Powershell ile ilerlemeyi planlayan saldırganlara engel olmak için gereken Powershell güvenlik sıkılaştırmalarından bahsedilecektir.
Güvenli Powershell
Powershell saldırganlar tarafından yoğun bir şekilde kullanılmaktadır. Saldırganlar için Powershell’in sağladığı en önemli özellikler aşağıda yer almaktadır:
- Zararlı dosyaları bellekte çalıştırabilme
- Ağ soketlerine kolay erişim sağlama
- Win32 API’sine doğrudan erişim sağlama
- WMI erişimi
- Güçlü bir script ortamı sunması
- Kriptografi kütüphanelerine kolay erişim sağlama
- COM nesnelerini kullanabilmesi
Bu özelliklere sahip olması, Powershell’i saldırganlar için bir saldırı vektörü haline getirmektedir. Saldırganlar tarafından kullanılması, Powershell’i kurumlar için bir tehdit unsuru haline getirebilir. Ancak Powershell’in devre dışı bırakılamaması durumu göz önüne alındığında, saldırganlara engel olmak için Powershell daha güvenli hale getirilebilir.
Powershell kullanımının kısıtlanması için alınabilecek önemli güvenlik tedbirleri aşağıda yer almaktadır.
Powershell CLM (Constrained Language Mode)
Powershell CLM, Windows API’lerinin çağrılması için kullanılan hassas bileşenlere erişimi kısıtlar. Powershell CLM özelliğinin aktif edilmesi durumunda, cmdlet’lerin kullanımına izin verilir ancak API’ler ile etkileşimde bulunan komutlar engellenir.
Powershell CLM moduna ait kısıtlamalar aşağıda yer almaktadır:
- Bir Powershell modülüne ait script ve manifest dosyalarının joker karakterler (*,? vs.) kullanılarak aranması engellenir. Aranan bir dosyanın bulunabilmesi için tam adının belirtilmesi gerekir. Böylece herkes tarafından görüntülenmesi istenmeyen dosyaların açığa çıkması önlenir.
- Saldırganların Win32 API’lerini çağıramamaları için COM nesneleri engellenir.
- Yalnızca beyaz listede olan .NET kütüphanelerinin kullanımına izin verilir. Bunun nedeni bazı .NET kütüphanelerinin Win32 API’lerini çağırma özelliği bulunmasıdır.
- .NET Core sınıfları tanımlanmasına olanak veren Add-Type cmdlet engellenir.
- Powershell sınıflarının kullanımı engellenir.
- Powershell değişken türlerinin dönüşümü engellenir.
- Dil modları arasında kodların referans alınmasını sağlayan dot-sourcing işlemi engellenir.
- Komut çözünürlüğü ile bir dil modu üzerinde çalıştırılamayacak olan komutların görüntülenmesi engellenir. Örneğin CLM modunda oluşturulan bir fonksiyon, Full Language modunda görüntülenemez.
- XAML tabanlı workflowlar Powershell tarafından kısıtlanamadığı için engellenir. Ancak güvenilir XAML tabanlı workflowların çalıştırılmasına izin verilir.
- Import-LocalizedData cmdlet için “SupportedCommand” parametresi devre dışı bırakılır.
- Invoke-Expression cmdlet’in yalnızca CLM modunda çalıştırılmasına izin verilir.
- Set-PSBreakpoint cmdlet UMCI aracılığıyla engellenir.
- Komut tamamlama özelliğinin yalnızca CLM modunda kullanılmasına izin verilir.
- DSC Configuration keywordleri devre dışı bırakılır.
- DATA bölümünde desteklenen komutlara ve scriptlere izin verilmez.
- Sistemin kilitlenmesi durumunda Start-Job cmdlet’in kullanımı engellenir.
- Sistem genelinde bir kilitlenme olması durumunda, script debugger ile birlikte çalıştırılan komutlar ve scriptler her zaman kısıtlı modda çalışır.
Resim 2.1.1’de “Full Language” moduna sahip bir powershell uygulaması yer almaktadır. Bu uygulama üzerinde hedef sistemden oturum elde etmeye olanak veren bir script çalıştırıldı.
Bu işlem sonucunda hedef sistemden bir powershell oturumu elde edildi.
Aynı işlem dil modu değiştirilerek yeniden gerçekleştirildi. Bu işlem sonucunda kısıtlama nedeniyle hata alındı.
Powershell CLM, hedef sisteme erişimi olan saldırganların kolay hareket etmesini önlemek amacıyla iyi bir çözümdür. Ancak Powershell CLM’i tek başına kullanmanın dezavantajları bulunmaktadır. Bu dezavantajlardan biri, CLM modunun sadece oturuma özgü olmasıdır. Bu nedenle bir powershell oturumunu sonlandıran ve yeni bir oturum açan saldırgan CLM kısıtlamalarını atlatarak işlemlerine “Full Language” modunda devam edebilir. Başka bir dezavantaj ise CLM modunun normal bir kullanıcının kullanmak isteyebileceği komut dosyalarını bozabilmesidir.
ISE ve powershell komut satırı uygulamaları çalıştırıldığında, CLM modunun varsayılan olarak aktif edilmesini sağlayan __PSLockdownPolicy adlı bir çevre değişkeni bulunmaktadır. Ancak saldırganlar çevre değişkenlerini değiştirebilecekleri için __PSLockdownPolicy kullanımı kesin bir çözüm değildir.
CLM için en iyi çözüm, bu özelliği Device Guard UMCI (User Mode Code Integrity) ile birlikte kullanmaktır. Device Guard, Kernel ve User modlarda çalıştırılan yazılımlara karşı koruma sağlar. Device Guard, sistem üzerinde çalıştırılabilecek uygulamaların tanımlanması için bir ‘White List’ çözümü sunar. Bu durum yalnızca güvenilir uygulamaların çalıştırılmasını sağlayan bir ortam oluşturulmasına olanak tanır. Device Guard, Kernel mod güvenliği için belirli sürücülerin imzalanmasını sağlar veya belirli sürücülerin listeye eklenmesine olanak verir. Böylece listede olmayan sürücülerin çalıştırılması engellenebilir. Ayrıca Device Guard, hangi uygulamaların çalıştırılabileceğinin belirlenmesini sağlayan kullanıcı modu koruması (UMCI) sağlar. Saldırganlar UMCI politikalarını devre dışı bırakamazlar. Bu nedenle CLM’i kullanmanın en iyi yolu CLM için bir Device Guard UMCI politikası oluşturmaktır.
NOT: Powershell uygulamasının yalnızca 5.1 versiyonu Device Guard politikalarını kabul eder. Powershell Core 6 ve açık kaynak Powershell sürümleri Device Guard politikalarını kabul edemez.
Powershell Aktivitelerinin Loglanması
Zararlı işlemlerin tespit edilmesi için, Powershell ile gerçekleştirilen işlemlerin loglanması gerekir. Bu özellik Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell altında yer alan “Turn on PowerShell Transcription”, “Turn on Module Logging” ve “Turn on PowerShell Script Block Logging” politikaları ile aktif edilebilir.
Module Logging
Powershell 3.0 versiyonundan itibaren gelen bu özellik, ardışık olarak çalıştırılan komutların ayrıntılarını loglar. Turn on Module Logging politikası aktif edilerek loglama işlemi gerçekleştirilebilir. Bu politikanın seçenekleri arasında yer alan “Show” butonu ile açılan pencere üzerinden, loglanacak olan modül adları belirtilebilir. “*” işareti ile tüm modüllerin loglanması sağlanabilir. Modül logları, olay logları arasına Application and Sevices Logs > Microsoft > Windows > Powershell > Operational altında 4103 ID değeri ile kaydedilir.
Script Logging
Script Logging, bir script dosyası çalıştırıldıktan sonra bu dosya içerisinde yer alan tüm kod bloğunu kaydeder ve script’in tüm aktivitelerini loglar. Turn on PowerShell Script Block Logging politikası aktif edilerek loglama işlemi gerçekleştirilebilir. Modül logları, Application and Sevices Logs > Microsoft > Windows > Powershell > Operational altında yer alan olay logları arasına 4104 ID değeri ile kaydedilir.
“Log script block execution start / stop events” seçeneği aktif edilerek, komut dosyalarının başlatılması ve durdurulması işlemlerinin loglanması sağlanabilir. Bu durumlar, 4105 ve 4106 ID değerleri ile kaydedilir.
Transcription Logging
Bu özellik başlatılan ve sonlandırılan tüm Powershell oturumlarının loglanmasını sağlar. Bu özelliğin aktif edilmesi durumunda, loglar belirtilen bir metin dosyasına kaydedilir. Her bir işlem, yapılacak analizlere yardımcı olmak için meta veriler ile birlikte kaydedilir. Turn on PowerShell Transcription politikası aktif edilerek loglama işlemi gerçekleştirilebilir. Log dosyaları, “Transcript output directory” seçeneği ile belirtilen dizin altına kaydedilir. Dizin belirtilmemesi durumunda, loglar kullanıcının “Documents” dizini altına kaydedilir.
Powershell 2.0
Powershell, önceki sürümlerle uyumlu olacak şekilde tasarlanmıştır. Bu nedenle yeni sürümler üzerinde Powershell 2.0 versiyonu aktif olarak gelir. Böylece Powershell 2.0 üzerinden; cmdletler, modüller ve scriptler çalıştırılabilir.
Powershell 2.0, Powershell 3.0 ve sonraki sürümler üzerinde yapılan güvenlik güncellemelerinin önemli çoğunluğundan yoksundur. Powershell 2.0, saldırganlar tarafından güvenlik önlemlerini atlatmak için kullanılabilir. Microsoft Powershell 2.0 versiyonunu güncel Windows versiyonlarından kaldıramamaktadır. Bunun sebebi; System Center uygulamaları, bazı SQL Server sürümleri, bazı Exchange sürümleri gibi birçok Microsoft uygulamasının Powershell 2.0 kullanmasıdır.
Powershell 2.0 versiyonunun güvenlik risklerini değerlendirmek amacıyla hedef sistemden powershell oturumu elde etmeye olanak veren bir komut çalıştırıldı.
Bu script ilk olarak Powershell 5.1 üzerinde çalıştırıldı. Ancak zararlı kodlar içerdiği için Windows Defender tarafından engellendi. Powershell 2.0 üzerinde çalıştırılan komut ise antivirüs uygulamasının atlatılmasına sebep oldu. Böylece hedef sistemden bir komut satırı oturumu elde edildi.
Powershell üzerinden Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2 komutu çalıştırılarak, Powershell 2.0 devre dışı bırakılabilir.
Execution Policy
Execution Policy, kullanıcıların çalıştıracakları scriptler ile sisteme zarar vermelerini önlemek amacıyla Powershell’in hangi koşullarda çalıştırılması gerektiğini belirleyen kurallardır. Get-ExecutionPolicy cmdlet ile mevcut politika görüntülenebilir.
Execution Policy, Set-ExecutionPolicy cmdlet ile ayarlanabilir. Execution Policy seçenekleri aşağıda yer almaktadır:
Restricted: Bu politika powershell uygulaması üzerinde sadece tek satırlık komutlar çalıştırılmasına olanak verir. Bu nedenle kullanıcılar tarafından hiçbir script çalıştırılamaz. Restricted politikası diğer politikalara göre en güvenli politika olarak kabul edilir.
AllSigned: Bu politika sadece güvenilir otoriteler tarafından imzalanmış olan scriptlerin çalıştırılmasına izin verir.
RemoteSigned: Bu politika kullanıcılar tarafından oluşturulan scriptlerin çalıştırılmasına izin verir. İnternet üzerinden indirilen scriptlerin çalıştırılması için güvenilir otoriteler tarafından imzalanmış olması gerekir.
Unrestricted: Bu politika scriptlerin çalıştırılması için imza kontrolü yapmaz ve herhangi bir kısıtlama getirmez. Ancak internet üzerinden indirilen scriptlerin çalıştırılması durumunda uyarı verir.
Bypass: Bypass politikası, bir scriptin veya bir komutun tamamen kısıtsız bir şekilde çalıştırılmasına olanak veren en güvensiz politikadır.
Windows Server 2012 R2 ve Windows Server 2016 işletim sistemleri dışındaki tüm sistemlerde varsayılan çalıştırma politikası “Restricted” politikasıdır. Windows Server 2012 R2 ve Windows Server 2016 işletim sistemlerinde ise varsayılan olarak “RemoteSigned” politikası uygulanır.
Bu özelliğin güvenli hale getirilmesi için “AllSigned” politikasının ayarlanması önerilmektedir.
JEA (Just Enough Administration)
JEA, Powershell’in tüm özellikleri için rol tabanlı erişim kontrolü sağlayan bir Powershell güvenlik teknolojisidir. JEA, kullanıcıların uzak sunucuya yüksek yetkilerle bağlanmasına, ancak o oturum üzerinde kısıtlı işlemler yapmalarına izin verir. Örneğin, JEA ile bir kullanıcının sadece belirtilen komutları, cmdletleri vs. çalıştırması sağlanabilir. Ayrıca JEA konfigürasyonlarının aktif edilmesi durumunda, kullanıcıların tüm aktiviteleri loglanır.
JEA ile kısıtlanan bir kullanıcı uzak sunucuya, o kullanıcı için oluşturulan bir sanal hesap ile erişim sağlar. JEA; Powershell 5.0 ve üzeri versiyonlarda, Windows 10, Windows Server 2016 ve güncellenmiş olan eski sürüm Windows işletim sistemlerinde bulunur.
JEA ile kısıtlamaların tanımlanması için konfigürasyon dosyaları oluşturulmalıdır. Bu konfigürasyon dosyaları ile kullanıcı rolleri tanımlanır. Dosya içerisinde bir kullanıcının sunucu üzerinde çalıştırabileceği komutlar, kullanabileceği parametreler ve içe aktarabileceği modüller tanımlanabilir. Dosyanın oluşturulması için ‘New-PSRoleCapabilityFile’ cmdlet kullanılmalıdır. Bu cmdlet ile oluşturulan dosya, bir kullanıcıya atanacak olan rolün konfigürasyonlarını içerir.
Resim 2.5.1’de Powershell Remoting servisi için oluşturulan bir konfigürasyon dosyası yer almaktadır. Bu dosyada, bir kullanıcının kısıtlı yetkilerle uzak powershell oturumu elde etmesi için gerekli tanımlamalar yapılacaktır.
Uzak kullanıcının kısıtlı Powershell oturumu elde etmesi için SessionType parametresine ‘RestrictedRemoteServer’ değeri atandı. Kullanıcının sanal bir hesap üzerinden yönetici oturumu elde etmesi için RunAsVirtualAccount parametresine $true değeri atandı. RoleDefinitions parametresine ise ‘unprivileged’ adlı kullanıcı hesabı için proc_admin adlı bir rol atandı. Bu rol JEA ile tanımlanacaktır.
Resim 2.5.3’te bir JEA konfigürasyon dosyası oluşturuldu. Bu dosya ile proc_admin olarak adlandırılan rol için gerekli tanımlamalar yapılacaktır.
NOT: Dosya adının Powershell Remoting konfigürasyon dosyasında tanımlanan rol adı ile aynı olması gerekmektedir. Role ait JEA tanımlamalarının kullanılması için, JEA konfigürasyon dosyasının yer aldığı dizinde .psrc uzantısına bakılmaksızın rol adı ile aynı ada sahip olan konfigürasyon dosyası aranır.
proc_admin rolüne sahip olacak tüm kullanıcılar için gerekli tanımlamalar yapıldı. Bu role sahip olan bir kullanıcı; VisibleCmdlets parametresi ile tanımlanan Get-Process, Start-Process ve Stop-Process cmdletleri ve VisibleExternalCommands parametresi ile tanımlanan whoami ve hostname komutlarını çalıştırabilir.
Powershell Remoting ve JEA konfigürasyon dosyalarında gerekli tanımlamalar yapıldıktan sonra, Powershell Remoting konfigürasyon dosyasının kullanılabilmesi için Register-PSSessionConfiguration cmdlet kullanılmalıdır.
‘unprivileged’ adlı kullanıcı hesabı ile yapılan ilk denemede WinRM oturumu elde etme işlemi başarısız oldu. Bunun sebebi kullanıcının WinRM oturumu elde etmek için gerekli yetkilere sahip olmamasıdır. Ancak oluşturulan rol ile yapılan oturum denemesi sonucunda, winrm virtual users\winrm va_1_win-ep0sfpt4tqd_unprivileged adlı sanal hesap üzerinden kısıtlı bir Powershell oturumu elde edildi. Resim 2.5.6’da elde edilen kısıtlı oturum ve JEA konfigürasyon dosyasında yapılan tanımlamalara göre çalıştırılabilecek olan cmdletler yer almaktadır.
Resim 2.5.7’de görüldüğü üzere hedef sistemden alınan oturum yüksek yetkilerle elde edildi. Ancak JEA bu yetkilerin tamamının kullanılabilmesine izin vermemektedir.
WinRM (Windows Remote Management)
WinRM, uzak kullanıcıların bir sistemden Powershell oturumu elde etmelerine olanak veren bir servistir. Bu servis SOAP tabanlı WS-Management protokolünü kullanır. WS-Management, bir sistemin yönetim bilgilerinin bulunması ve değiştirilmesi için tasarlanmıştır. WinRM yalnızca yönetici yetkilerine sahip kullanıcıların oturum elde etmesine izin verir. WinRM servisi HTTP(S) protokolü üzerinden haberleşir ve varsayılan olarak 5985 (HTTP) ve 5986 (HTTPS) numaralı TCP portlarını kullanır. WinRM servisi Network Service hesabı altında çalışır ve kullanıcıların oturum elde etmeleri için izole processler oluşturur. Bu nedenle bir kullanıcının elde ettiği oturuma başka bir kullanıcı erişemez.
WinRM servisi varsayılan olarak aynı ağda bulunan tüm uzak sunucuların erişimine açıktır. Bu nedenle yönetici kimlik bilgilerine sahip tüm sistemler, WinRM servisi aktif olan tüm sunuculara erişim sağlayabilir. Bu nedenle WinRM servisinin aktif olarak kullanılmadığı sunucularda, WinRM servisi kapatılmalıdır. WinRM servisinin açık olması gereken sunucularda ise gelen bağlantılar sınırlandırılabilir. Bu işlem için Windows Firewall üzerinden WinRM portlarına erişim sağlayabilecek olan istemci adreslerine izin verilebilir. Ayrıca WinRM oturumu elde edilebilecek kullanıcıların belirlenmesi için yönetici grupları ve Remote Management Users grubu üzerinde ayarlamalar yapılabilir.
Başka bir kısıtlama olarak Allow remote server management through WinRM adlı politika aktif edilebilir. Bu politika, sunucunun birden fazla ağ interface’i olduğu durumlarda hangi interfaceler üzerinden dinleme işlemi yapılacağının belirlenmesini sağlar. ‘IPv4 filter’ ve ‘IPv6 filter’ seçenekleri ile dinleme işleminin yapılacağı interface adresleri belirtilebilir.
Ayrıca GPO üzerinden aşağıdaki politika ayarları uygulanarak WinRM sıkılaştırması sağlanabilir.
Not: Bu makaleyi Powershell Sıkılaştırma Dokümanından PDF formatında indirebilirsiniz.
Yazar: Ramin KARIMKHANI