Remote Desktop Services CVE-2019-0708

17.05.2019
9

Microsoft’un aylık yazılım güncelleme döngüsü içerisinde duyurarak yamasını yayınladığı ve belirli sürüm Windows’lar üzerinde Remote Desktop Service vasıtasıyla kimlik doğrulama olmaksızın uzaktan kod çalıştırmaya izin veren CVE-2019-0708 numaralı zafiyet ile Salı günü tanıştık. Resmi advisory belgesi şurada yer alıyor.

Kısaca CVE-2019-0708

Windows’un uzak masaüstü bağlantı servisi olan Remote Desktop Service’in sunucu pozisyonundaki belirli sürümlerini etkileyen bir zafiyettir. Kritiklik seviyesi yüksek çünkü kimlik doğrulama olmaksızın uzaktan kod çalıştırmaya izin veriyor ve bu sırada herhangi bir kullanıcı etkileşimine ihtiyaç duymuyor.  Oluşan algı RDP yani Remote Desktop Protocol zafiyeti şeklinde olsa da bu aslında bir protocol değil uygulama zafiyeti. Protocol’ün yapısında ortaya çıkan bir zafiyet ile protocol’ü operate eden bir uygulamanın işleyişindeki zafiyeti birbirinden ayırmak lazım. Örneğin SSL 3.0’ı tedavülden kaldıran Poodle bir protocol zafiyetiyken, TLS/DTLS uyarlaması olan OpenSSL’de ortaya çıkan Heartbleed bir uyarlama hatasıydı. CVE-2019-0708 zafiyetinde problem Windows’un uzak masaüstü bağlantısı için kullandığı ve aslen bir Remote Desktop Protocol (RDP) uyarlaması olan Remote Desktop Service’e ait process ve driver’ların, sunucuya gelen uzak masaüstü bağlantı isteklerini işlediği esnada ortaya çıkıyor ve bu amaçla hazırlanmış özel paketler yardımıyla istismar edilerek belirli sürüm Windows işletim sistemleri üzerinde kod çalıştırmak mümkün olabiliyor. FreeRDP gibi, xrdp gibi Remote Desktop Protocol’ün non-Microsoft uyarlamaları ise bu zafiyetten etkilenmiyor.

Etkilenen İşletim Sistemleri

  • Windows 7
  • Windows Server 2008 R2
  • Windows Server 2008

Ayrıca resmi desteği sonlanmış olmasına rağmen zafiyetin etki alanını daraltmak adına aşağıdaki etkilenen işletim sistemleri için de yama yayınmış durumda.

  • Windows XP (KB)
  • Windows Server 2003 (KB)

Korunma Yöntemleri

İşlevsellikten ödün vermeden uygulanabilecek tek seçenek Windows güvenlik güncellemelerini yüklemek. Windows Update, WSUS, SCCM veya şu advisory bağlantısını kullanabilirsiniz. Eğer bir sebepten ötürü güncellemeleri yükleyemiyor veya bir süre daha geciktirmeniz gerekiyor ise, aşağıdaki seçenekleri geçici çözüm ve etki azaltma amaçlı değerlendirebilirsiniz.

  • Uzak masaüstü bağlantıları için source-ip denetimi uygulamak.
  • Sunucuyu VPN arkasına almak.
  • Gerekmiyor ise Remote Desktop Service’i devre dışı bırakmak.
  • Remote Desktop Service’i sadece Network Level Authentication ile çalışacak şekilde ayarlamak ki bu aslında her halükarda devrede olması gereken bir ek güvenlik katmandır. Birazdan sebeplerinden ve öneminden ayrıca bahsedeceğim.

Bu arada eğer göz atmak isterseniz 2015’te RDP güvenliğiyle ilgili bazı öneriler yazmıştım.

Network Level Authentication

Pek göz önünde olmasa da etkili bir güvenlik özelliğidir. Örneğin bu case için ele alırsak eğer sunucuda Network Level Authentication (NLA) özelliği aktif ise, Remote Desktop Service binary’leri CVE-2019-0708 zafiyetinden etkilenseler bile kimlik doğrulama işlemi gerçekleşmeden kod çalıştırmak mümkün olamıyor. Neden mi?

Hatırlarsınız Windows XP ve daha önceki sürümlerde bir Remote Desktop oturumu açarken gerekli credential bilgilerini uzak sunucuda gösterilen bir logon screen’de username/password alanlarına giriyorduk. Bu şu demek: Biz henüz bir credential bilgisi girmemiş -yani kimlik doğrulamamış- olmamıza rağmen uzak sunucu bizim için bir oturum başlangıcı yaptı, Csrss.exe gibi, Winlogon.exe gibi birtakım system process’leri çalıştı, bir miktar işlemci kaynağı tüketildi, bellek alanı ayrıldı, credential bekleyen bir logon screen oluşturuldu, event log yazıldı ve bağlantı isteğimiz Remote Desktop Service tarafından işlenmiş oldu. Ama belki de tüm bu hazırlık boşuna yapıldı çünkü biz zaten geçerli bir credential bilgisine sahip değildik ve birazdan bağlantı penceresini kapatacağız :) İşte bu noktada iki önemli problem var:

  1. Logon işlemine devam etmeyecek birkaç oturum başlangıcı etkisiz gözüküyor olabilir ama logon screen’e gelene kadar ki bu aşamaları programatik olarak çok sayıda ve eş zamanlı tekrar eden bir kod tasarlayarak yeteri miktarda oturum açma talebi oluşturup uzak sunucuyu yanıt veremez hale getirmek mümkün. Bu da Remote Desktop Service yapısını DOS ataklara karşı zayıf hale getiriyor.
  2. Henüz kimlik doğrulama yapmamış olmanıza rağmen Remote Desktop Service process’lerine istek/paket gönderip etkileşime geçebilir ve fonksiyonlarını işleterek olası hatalarından faydalanabilirsiniz. Tıpkı bu case’de yani CVE-2019-0708’de olduğu gibi…

Bu gibi bazı risklerden ötürü Windows Server 2008’den itibaren bir front authentication mekanizması olan Network Level Authentication özelliği geldi. Bu sayede, Remote Desktop bağlantısı gerçekleştirmek isteyen bir istemci, bağlantı için gerekli credential bilgisini uzak sunucuda onun adına herhangi bir oturum başlangıcı yapılmadan önce hazırlayıp CredSSP isimli bir güvenlik protokolü vasıtasıyla sunucuya önden gönderebiliyor. Sunucu ise önce aldığı credential bilgisini kontrol ediyor ve ancak yetkili bir kullanıcı ise Remote Desktop oturumunu başlatıp süreci ilerletiyor. İşte tam da bu yüzden sonraki Windows Server’lara uzak masaüstü bağlantısı yaparken credential bilgisini bir logon screen’e değil de mstsc.exe gibi istemcilerin client-side’da oluşturduğu pop-up pencerelerine giriyoruz.

CVE-2019-0708 özelinde baktığımızda, NLA aktif olan sunucuda zafiyetten etkilenen Remote Desktop Service bir front authentication mekanizmasının arkasında kaldığından, saldırganın kimlik doğrulamadan kod çalıştırması mümkün olamıyor. Eğer saldırgan uzak sunucu üzerinde geçerli bir credential bilgisine sahip ise, bu durumda Network Level Authentication aşamasını geçip kodu çalıştırabilir. Ama bu senaryoda olay farklı bir hal almış oluyor.

NLA sunucu tarafında aktif edilen bir özelliktir:

NLA

Registry

HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\UserAuthentication : 1

PowerShell İle Uzaktan

Get-WmiObject -ComputerName "ComputerName" -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices  -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(1)

AD Domain Ortamında GPO

Computer Configuration \ Administrative Templates \ Windows Components \ Remote Desktop Services \ Remote Desktop Session Host \ Security \ Require user authentication for remote connections by using network level authentication : Enabled

Exploit

Henüz bilinen bir exploit yok ancak etki alanının genişliği, etkileşim gerektirmemesi, uyarlandığı taktirde kendi kendine yayabilme potansiyeli, reverse engineering için elde patch olması gibi iştah kabartan faktörlerden ötürü zafiyetin exploit edilmesi çok da uzun sürmeyebilir. Ben henüz çalışan bir kod görmedim. Şu an ortada bolca fake exploit duyurusu ve spekülasyon dolaşıyor. Bir de bunları ciddiye alıp paylaşan ve yanlış bilginin yayılmasına vesile olan magazin takımı var. Bu fake exploint’lerden timeline’a en sık düşen ikisi şöyle:

1) cve-2019-0708.com isimli site. Satın alan kişinin upload edip internet’e dağıtmayacağından o kadar emin ki adam 89$’a direkt exploit’in source code’unu satıyor. Demo görsellerinde user mode olmayan bu zafiyet ile kullanıcı oturumunda uygulama başlatması ise bir diğer fake alameti. Ama bak köşeyi dönmüştür ona bir şey diyemem :) Twitter buraya para ödeyen insanlarla dolu.

cve-rdp

2) İlk günlerde ortaya çıkan ve CVE-2019-0708 isimli bir github repo’su. Birazcık dikkatli olmak yeterli.

Zafiyetin Etki Alanı

Gerekli güvenlik güncellemelerini almamış ve NLA aktif olmayan Windows 7 ve alt sürümler zafiyetten etkileniyor demiştik. CVE-2019-0708 duyurulduğu dakikalarda şöyle bir göz ucuyla shodan.io ‘da listelenen ve genele açık şekilde RDP çalıştıran Windows sayısına baktım. O gün Twitter’da da yazmıştım. Dünya genelinde 2 milyondan fazla sistem sadece burada listeleniyor ki muhtemelen sayı çok daha fazla. Peki bu Windows’lardan kaç tanesi gerçekten zafiyetin etki kapsamına giriyor olabilir? Yani RDP erişimi açık olup da üzerinde Network Level Authentication aktif olmayan Windows sayısı nedir? O gece güncellemeler yüklenmeden önce bu sorunun yanıtını aradım…

3-4 saat kadar zaman ayırıp ufak bir tarama ve kontrol mekanizması tasarladım. Akabinde bunu hızlıca kodladım. Kabaca şöyle çalışıyor:

  • Verilen IP adres listesini tarıyor, RDP çalıştıran sistem tespit ettiğinde Remote Desktop bağlantısı deniyor, NLA’nın aktif olup olmadığını kontrol edip sonucu bir DB’ye yazıyor. Sonrasında bu verileri DB query’ler ile raporlayıp istatistik oluşturmak için kullanıyorum.
  • Uzak sunucuda NLA’nın aktif olup olmadığını tespit etmek için başta Remote Desktop Service’e programatik olarak istek gönderip yanıtları anlayacak bir yöntem aradım. Farklı RDP Client uyarlamalarına baktım. Kütüphane araştırdım. Ama kolayca entegre edebileceğim bir şey bulamadım. Bulabildiğim bazı şeyleri da anlayacak kadar zamanım olmadı. Bu yüzden RDP client olarak bizim mahalleden mstsc.exe’yi kullanmak zorunda kaldım. Bu seçim işleri bir miktar zorlaştırdı çünkü mstsc.exe programatik olarak kullanım için uygun bir araç değil ve GUI tabanlı yani komut satırına çıktı desteği falan hak getire. Bu yüzden bağlantı sonucunu anlamak pek kolay olmadı. En son mstsc.exe process’lerinin window handle id’leriyle yakaladığım pencere başlıklarını okuyarak çözdüm. Biraz dandik ve kırılgan bir çözüm oldu ama işe yaradı.Güncelleme/21.05.2019: Hafta sonu biraz daha zaman ayırıp bu sefer remote desktop protocol için ağ/paket seviyesinde bazı analizler yaptım ve RDP iletişimi başlangıcında karşılıklı olarak gidip gelen ve bazı Remote Desktop Service (ve client) bilgileri içeren paketler tespit ettim. Özellikle belirli bir paket içerisinde yer alan veriyi kullanarak Remote Desktop Services versiyon bilgisini, büyük oranda işletim sistemi sınıfını ve kesin olarak NLA’nın aktif olup olmadığını anlamayı başardım.

    nla1

    Birkaç örneği şöyle:

    030000130ed00000123400 0200 080000000000 - NLA disable. Windows Server 2012 R2 sınıfı.
    030000130ed00000123400 0209 080000000000 - NLA disable. Windows Server 2008 R2 ve Windows 7 sınıfı.
    030000130ed00000123400 0300 080005000000 - NLA enable. OS ve RDS sürümü bilgisi tespit edilemez.
    0300000b06d00000123400 - NLA disable. Windows XP ve sınıfı. (Eski sürüm RDS'lerin veri tipleri biraz farklı)
    0300000b06d00000000000 - NLA disable. Xrdp.

    Bir grup sistem üzerinde deneyerek yöntemi doğruladıktan sonra kod içerisine bir network packet sniffer (tshark) entegre ederek Remote Desktop başlangıcı sırasında belirlediğim paketleri capture ve parse edecek bir filtre ile birlikte Salı gecesi yaptığım taramada kullandığım 15.000 adet IP adresi için tekrar ateşledim.

    Bu paketteki veri aslında işletim sistemi sürümüne değil işletim sistemi üzerinde çalışan RDP uyarlamasının (örneğin RDS, xrdp) markasına işaret ediyor ve buradan da Windows işletim sistemi grubuna ulaşmak mümkün oluyor. Örneğin belirli patch seviyesindeki Windows 7 ve Windows Server 2008 R2 üzerinde aynı versiyon Remote Desktop Service çalıştığı için paket içerisindeki veri ikisinde de 030000130ed000001234000209080000000000 diziliminde olurken, bu değer örneğin bir Windows Server 2012 R2 sınıfında gözlemlenmiyor çünkü onun üzerindeki RDS’in versiyon bilgisi kendi içinde farklı ilerliyor ve kendi grubuna has bir değer çeşitliliğine sahip. CVE-2019-0708 zafiyetinin sadece belirli sürüm Windows’lar üzerindeki Remote Desktop Services’leri etkilemesinin sebebi de tam olarak bu; Remote Desktop Services versiyon farkları… Tarama sonuçları GROUP BY ile konsolide ettiğimde OS dağılımı ve NLA durumları şu şekilde oldu:

    os-group-by

    İşin ilginci bu paket ve içerisindeki veri ile ilgili herhangi bir kaynak veya çalışma yok sanırım ya da ben bulamadım. Çünkü OS sınıfını ve Remote Desktop Service versiyon bilgisi keşfetmek için gayet kullanışlı bir yöntem gibi gözüküyor. Bu konu üzerinde çalışma yapılabilir.

  • Uzak sistemin işletim sistemi sürümünü anlamak için birkaç araç ve yöntem denedim ama maalesef hem yavaş kalarak tarama süresini ciddi uzattılar hem de toplu taramalarda pek başarılı sonuç vermediler. Yine bir fonksiyon yazıp mstsc.exe process’lerinin pencerelerinden jpg formatında screen capture’lar alıp bu jpg’leri bir online OCR servisine post edip text’e dönüştürdüm ve logon screen jpge’de yer alan Windows işletim sistemi bilgisini almayı denedim. OCR sonuçları da pek istediğim gibi olmayınca OS detection’ı pas geçtim. Yukarıda bahsettiğim gibi ağ/paket seviyesinde capture yaparak OS’leri büyük oranda tespit etmeyi başardım.
  • Tarama için paralel çalışan 3 sunucu kullandım. 2 farklı tarama turu yaptım.
    • İlk turda tamamı Türkiye’de yer alan, rastgele seçilmiş, 3 farklı kurumsal subnet kapsamına giren ve toplamda 100.000 adet IP adresinden oluşan bir liste kullandım.
    • İkinci turda ise çok daha hedef odaklı bir tarama için yine tamamı Türkiye’de yer alan ve RDP erişimi genele açık olduğu bilinen 15.000 adet IP adresi içeren bir liste kullandım.

nla-control

Ben şahsen daha fazla sistem üzerinde NLA aktif olacağını düşünmüştüm ama sonuçlar gerçekten tedirgin edici.

Toplamda 100.000 IP adresinden oluşan rastgele 3 farklı subnet’e ait tarama sonuçları şöyle:

  • RDP erişimi açık IP adresi oranı: %1
  • RDP erişimi açık %1 arasında NLA aktif sistem oranı: %28
  • RDP erişimi açık %1 arasında NLA aktif olmadığı için potansiyel risk taşıyan sistem oranı: %72

Toplamda 15.000 IP adresinden oluşan ve RDP erişimi genele açık olduğu bilinen hedef odaklı listeye ait tarama sonuçları:

  • RDP erişimi açık IP adresi oranı: %84
    • RDP erişimi açık IP adreslerinden %51,1’i zafiyetten etkilenmiyor: OS sürümü korunaklı veya NLA aktif.
    • RDP erişimi açık IP adreslerinden %48,9’u zafiyetten etkileniyor: Etkilenen OS sürümü + NLA aktif değil.
  • RDP erişimi açık %84 arasında NLA aktif sistem oranı: %5
  • RDP erişimi açık %84 arasında NLA aktif olmadığı için bu gibi zafiyetlerde risk potansiyeli olan sistem oranı: %95

Sonuçlarla ilgili birkaç not:

  • Rastgele seçtiğim 100.000 adetlik listede tespit edilen RDP erişimi açık sistemlerin %60 kadarı, 15.000 adet IP adresinden oluşan hedef odaklı listede yer almıyordu.
  • RDP erişimi açık ama NLA aktif olmayan sistem oranını değerlendirirken aralarında zafiyetten etkilenmeyen Windows sürümlerinin de yer aldığını unutmayın. İşletim sistemi sürümünü hızlı ve hatasız tespit edebilecek sağlıklı bir yöntem bulamadığım için programatik olarak bu sorunun yanıtına tam ulaşamadım ama diğer bazı veriler ışığında yaklaşık bir oran söylemek gerekir ise aralarından %35 kadarı Yaklaşık %51’i zafiyetten etkilenmeyen sürüme sahip şekilde çalışıyor.

Sonuç

Bu oranlar dünya geneline yansıtıldığında ve exploit edilebildiği taktirde kendi kendini yayabilen bir modele evrilme ihtimali yüksek olduğundan durum aslında baya ciddi gözüküyor. Zafiyeti kullanabilen bir worm’un internet’e açık sistemler üzerinden yayılmaya başlaması ve devamında bu zayıf sistemlerin bağlı olduğu iç ağlara atlaması çok zor olmayacaktır. Bu yüzden Microsoft da konuyu şöyle bir anons ile duyurdu ve atak yüzeyini daraltmak adına doğru bir hareket olarak Windows XP gibi desteklenmeyen sürümlere de yama yayınladığını açıkladı. Muhtemelen her geçen saat zayıf sistem sayısı azalıyor ve atak yüzeyi giderek daralıyor çünkü Windows update’ler çalışıyor, yüklemeler yapılıyor, önlemler alınıyor. Ama tüm bunlara rağmen geride zararlı bir kodun yayılması için yeterli sayıda zayıf sistem mutlaka kalacaktır diye düşünüyorum…

Yorumlar (9)

  1. Ahmet Şirin

    Güzel, açıklayıcı ve faydalı bir yazı olmuş. Ellerinize sağlık…

  2. Leyla Yağcı

    Başından sonuna son derece açık ve net bir şekilde durumu özetleyen yazınızın paylaşımı için teşekkür ederim. Emeğinize sağlık.

  3. Harun Güzeldere

    Abi özlemiştik :)

  4. Rıza Şahan

    Hocam, uzun süre sonra detaylı bir yazı ile merhaba demeniz güzel oldu. Biraz daha yakın aralıklarla bekliyoruz. Teşekkürler.

  5. ihsan

    Serhat Hocam Merhaba,

    yukarıdaki makale ile ilgili değil ama https://www.cvedetails.com/cve/CVE-2015-1635/ konulu zafiyet ilgili olarak sorun olacak size;
    Cve-2015-1635 zafiyeti ilgili araştırma yaptım ve microsoft çözüm olarak KB3042553 yüklenmesini iletmiş fakat bunun yüklenmesi için ise KB2919355 update paketini olması gerektiğini iletmiş ve bu guncellemede sistemimde yuklu, bu zafiyeti gidermek için ne yapabilirim,
    Teşekkürler,

  6. Serkan

    Hocam yazılarınıza ara mı verdiniz? Twitter üzerinde de pek aktif değilsiniz artık?

  7. Serhat AKINCI

    İhsan – KB3042553 bir Windows 7 güvenlik güncellemesi. KB2919355 ise Windows 8.1’e ait olarak gözüküyor. Yani aslında bu iki paketin birbiri ile ilişkisi yok. Zafiyeti hani Windows sürümü üzerinde kapatmak istiyorsan o sürüme uygun paketi yüklemen yeterli.

  8. Serhat AKINCI

    Serkan – Biraz öyle galiba :) Aslında buralardayım ve çok daha fazla konu üzerinde çalışıyorum. Ama her zamankinden fazla yazabileceğim şeye sahipken hiçbir şey yazmamak bana da tuhaf gelmiyor değil.. Zaman ilerledikçe, zaman ayırdığın şeyler de değişiyor sanırım.

  9. Anıl ALAN

    Merhabalar, umarım uzun süre sonra tekrardan benzer içeriklerle yazı yazmaya devam edersiniz :)

Yorum Ekle

* Gerekli

* Gerekli

* Tercihen