Loading...

DynoRoot – (Dynamic Host Configuration to Root) RedHat ve Türevi Dağıtımlarda Uzaktan Kod Çalıştırma Zafiyeti

Barkın Kılıç

Merhaba, bu yazımızda CVE 2018-1111 zafiyet kimlik numarasına ait RedHat ve türevi dağıtımlarda tespit edilmiş DHCP istemcilerinin uzaktan kod çalıştırma bulgusundan bahsedeceğiz.

Linux sistemlerin özellikle masaüstü ya da istemci olarak kullanılan sürümlerinde ağ ayarları genelde dahil olunan ağın otomatik olarak ayar dağıtımı yapan DHCP servisi tarafından ayarlanmaktadır. Bu ayarlamalar esnasında IP adresi, alt ağ maskesi, ağ geçidi IP adresi, isim sunucu IP adresleri vb. gibi birçok ayar otomatik olarak istekte bulunan istemciye teslim edilmektedir. Bunları sistem içerisinde ilgili ayar dosyalarına kaydeden ve ilgili komutları çalıştırarak sistemi güncelleyen komut veya betikler mevcuttur. Son dönemlerde bu görevi Linux sistemlerde SYSTEMD’nin de gelmesi ile beraber Network-Manager ismindeki uygulama ya da servis üslenmektedir. Bu servis arka planda çalışarak herhangi bir ağ bağlantısı gerçekleştikten sonra (Ethernet kartına kabloyu takmak ya da kablosuz bağlantının seçilmesi ve bağlanılması gibi) otomatik olarak devreye girer ve DHCP isteğinden tutun bunların sonucunda gerçekleşecek aksiyonların sağlıklı bir şekilde tamamlanması, takip edilmesi ve zaman içerisinde bakımının yapılmasına kadar kullanıcıdan bağımsız olarak otomatik bir şekilde gerçekleştirmektedir. Bu gerçekleştirilen birçok işlem en üst seviye sistem yetkisi gerektirdiğinden ötürü de sistem üzerinde “root” kullanıcısının yetkileri ile çalışmaktadır. Dağıtımlar arasında özellikle popüler olarak kullanılan son kullanıcı işletim sistemi türevlerinde (Ubuntu, Fedora, Gentoo vb,) bu servisin işlemlerine müdahale etmek ya da özelleştirmek için betik desteği bulunmaktadır.

Bahsedeceğimiz zafiyette ise tespit edilen problem bu servis betiklerinden birinde bulunmuştur. Sadece bir dağıtıma özel, geliştiricileri tarafından eklenmiş ve bütün türevlerini etkileyen bu betik ise ön tanımlı olarak çalışmakta ve istek sonucunda gelen DHCP cevaplarını doğru ya da güvenli bir şekilde işleyemediği için kritik bir zafiyete sebebiyet vermektedir.

Şimdi gelelim zafiyetin detaylarına; Network-Manager ismindeki servisin DHCP isteklerine gelen cevapları karşılayan “Dispatcher” ismindeki eklentisi, kendisine ait bir servis dizini altında yer alan betikleri istek dahilinde çalıştırmaktadır. Görevi ise gelen ilgili cevaplar için gerekli aksiyonu belirli adımlara göre dağılımını sağlamak ve ona göre çeşitli elemeler ya da değişikliklerden sonra işleme almaktır. Bu betiklerin sistem üzerindeki yeri ise aşağıdaki ekran görüntüsünde gösterilmiştir.

Google’da çalışan Felix Wilhelm ismindeki bir güvenlik araştırmacısı Redhat ve türevinde bulunan, bu dağıtımı geliştirmekte olan yazılımcıların yazmış olduğu bir “Dispatcher” betiğinde DHCP isteklerinde yer alan değerleri yorumlayan kodun bir sıkıntısını keşfetmiş ve bunu Twitter üzerinden duyurmuştur. Ayrıca keşfettiği bu sıkıntının kritikliğinin sadece root yetkileri ile uzak sistemde kod çalıştırmak olmadığını, zafiyeti tetikleyecek sömürü kodunun da çok basit olduğunu, hatta bir tweete sığabilecek uzunlukta olduğunu da bildirisine eklemiştir.

İlgili betiğin detaylarını da paylaşan araştırmacı kodun problemli olan kısmına dikkat çekerek açıklamasına devam etmiştir.

Bu bildirimi yapan güvenlik araştırmacısı zafiyetin sömürü kodunu ve detaylarını paylaşmamıştır. Bu zafiyet Twitter üzerinde açıklandığı zaman içerisinde dağıtımın geliştiricileri tarafından ilgili güvenlik yama paketleri çıkarılmış ve dağıtımın paket yansılarına eklenmiştir.

Bundan ötürü en kısa zamanda güncellenmesini tavsiye etmektedir.

Bu yazının asıl konusu olan zafiyetin teknik detayları ve sömürü kodunun ortaya çıkarılması ise bundan sonra anlatılmaktadır.

Herhangi bir RedHat türevi indirerek (RedHat, Fedora, CentOS vb.) kurulumunu yapıp, daha sonra bahsi geçen betiği tespit edip incelemek ile başlayabiliriz. Aşağıdaki ekran görüntüsünde http://repo.boun.edu.tr/centos/7.5.1804/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso adresinden indirilmiş en son sürüm CentOS imajı ile kurulmuş bir sistemi inceleme için hazırlıyoruz ve bu sistem üzerinde “Dispatcher” betiklerinin içerisine bakıyoruz. Aşağıdaki ekran görüntüsünde ise zafiyetin barındığı betiği görüyoruz.

İçerisini okuyarak başlayalım;

Burada “eval” komutu ile bir değişken tanımı oluşturulmaya ve “export” komutu ile bütün kabuklar içerisinde bu tanımın geçerliliğinin sağlanmasına çalışıldığı görülüyor. Aranan şey ise “DHCP4_” paramatresi ile başlayacak ve bulduğu değerleri sonrasında bir dizi işleme tabi tutulacaktır. Bu kısımda açılmış olan alt kabuk kodunun içerisinde yer alan “while” döngüsünde “read” komutu ile parametreler bir bir işleme sokulmuştur. Nasıl bir çıktı ürettiğini görmek ve buradan nasıl bir sömürü ortaya konulabileceğini belirlemek için komutun çıktısını bir dosyaya kaydedelim ve bir DHCP isteği oluşturarak dönülen cevapları inceleyelim.

Betik dosyasını herhangi metin editörü ile açarak ekran görüntüsünde yer alan “tee” komutunu ve çıktıyı bir dosyaya kaydedecek parametresini ekliyoruz.

Bundan sonrasında DHCP istemcisini sistemde “nmcli” komutu ile başlatarak kendi kontrolümüzde olan bir sunucu üzerinde trafiği “Wireshark” ya da benzeri bir araçla inceleyebiliriz. Kendimize ait bir DHCP servisi için Linux sistemlerde çalışan “Dnsmasq” yazılımından faydalanabiliriz. Bu servisi kurmak için Debian ve türevi sistemlerde “apt-get install dnsmasq” ile kurulum gerçekleştirilebilir.

Bu işlemi ve bu yazıda yer alan saldırı maksatlı kullanılacak bütün işlemleri gerçekleştirmek için “Kali Linux” dağıtımını kurban/hedef sistemle aynı ağ içerisinde yer alacak şekilde oluşturmamız yeterli olacaktır.

Sonrasında ise komut satırından servisi başlatarak kurbanın isteklerini ve bizim verdiğimiz cevapları görüntüleyeceğiz. Komut satırından servisi başlatmak için şu şekilde bir söz dizimi belirtilmesi gerekiyor: “dnsmasq –interface=eth0 –bind-interfaces –except-interface=lo –dhcp-range=10.1.1.2,10.1.1.10,1h –conf-file=/dev/null –dhcp-option=6,10.1.1.1 –dhcp-option=3,10.1.1.1”.

Beraberinde Wireshark yazılımı başlatıp ilgili ağ arayüzünü dinleyerek DHCP paketlerini ayıklamamız yeterli olacaktır.

İstemci tarafından DHCP isteğini şu söz dizimi ile tetikleyebiliriz: “nmcli conn up id ens33”.

Bununla DHCP istekleri oluşturulup Wireshark aracında istemcinin talep ettiği DHCP parametrelerini görmeyi bekliyoruz. Aşağıdaki ekran görüntüsünde istemcinin daha önce bulunduğu ağda IP adresi almadığı için ilk olarak yapacağı iş ağda bir DHCP sunucusu olup olmadığını keşfetmek, bunu da “DHCP Discover” paketi ile gerçekleştiriyor. Sonrasında bu keşif isteğini teslim alan sunucu ağda var olduğunu istemciye iletmek için “DHCP Offer” paketini cevap olarak dönüyor. Sunucudan cevabı alan istemci “DHCP Request” paketi oluşturuyor ve gönderiyor. Sunucuda son olarak bütün sorulan soruların cevabını “DHCP ACK” paketine koyarak istemciye geri gönderiyor ve süreç sonlanıyor.

İstemcinin talep ettiği değerler ve sunucunun cevabında yer alan bilgiler aşağıdaki ekran görüntülerinde gösterilmiştir.

İstemcinin talepte bulunduğu isteğin her aldığı ikinci ekran görüntüsünde sunucudan “1,28,2,121,15, 6,12,40, 41,42,26,119, 3,121, 249, 33, 252, 42” seçeneklerinin cevaplarını istediğini ve bunların ne anlama geldiği ile ilgili açıklamaları yanlarında başlık olarak görüyoruz. Burada bilinmesi gereken önemli nokta DHCP protokolünün detayları ve bu parametrelerin ne anlama geldikleri ile beraber ne türde değerler alabileceklerine hakim olabilmekte bulunuyor.

Bunun için tavsiye edilebilecek kaynak olarak RFC (Request For Comment) belgelerini ve detaylarını incelemekte fayda vardır. Şu adreste bulunun içerik incelenebilir; http://www.networksorcery.com/enp/protocol/bootp/options.htm

Sunucu tarafı bu isteğe sadece “53, 54, 51, 58, 59, 1, 28, 3, 6, 255” değerlerini cevaplayarak döndüğünü yukarıdaki 3. ekran görüntüsünden görebiliyoruz. Hemen burada isteğin sonucunda çıktıyı bir dosyaya yazması için düzenlemiş olduğumuz ilgili betiğin çıktısını inceliyoruz.

Görüyoruz ki birçok “export” komutu ile değişkenleri beraberinde oluşturularak “eval” komutu içine aktarılabilmektedir. Peki burada zafiyet olduğunu ve bu zafiyetin nasıl tetiklenebileceğini görmek için ne yapmalıyız? Cevap istemcinin talep ettiği seçenekler ve bu seçeneklerden hangilerine istediğimiz keyfi girdileri belirtebileceğimizi bulmakta yatıyor. Örnek olarak bir değeri kendimize hedef seçelim istemcinin talep ettiklerinden ve ona keyfi bir değer atayalım.

Bu örnekte “Host Name” parametresi olan 12 numaralı seçeneği hedef alacağız. DHCP servisimize 12 numaralı seçenek için komut çalıştıracak keyfi değerlerimizi yerleştirerek kendisini tekrar başlatalım.

İstemci tarafında DHCP isteğini tekrar tetiklememiz gerekiyor.

Wireshark üzerinden isteğimiz gönderildiğini kontrol edelim.

Gayet güzel bir şekilde keyfi seçtiğimiz ve istemcinin talep etmiş olduğu 12 numaralı seçeneğe istediğimiz komut çalıştıracak sömürü kodunu yerleştirmiş bulunuyoruz. Bu kodun sonucunda “id” komutunun çıktısı “/tmp” altında “komutciktisi.txt” adındaki bir dosyaya yazılması gerekiyor. Komutun çalışıp çalışmadığını “/tmp” dizini altını kontrol ederek gerçekleştirebiliriz.

Herhangi bir dosya oluşmamış. Peki betiğin ürettiği çıktıyı kontrol edersek ne göreceğimize bakalım. Çıktı çok uzun olacağı için “grep” komutu ile göndermiş olduğumuz “hostname” değerini aratacak şekilde ayıklıyoruz.

Gördüğümüz kadarı ile bizim başarılı bir şekilde göndermiş olduğumuz değer sistem tarafından işleme alınıp oluşturulmamış. Sebebini görmek için kayıt dosyasını inceleyelim.

Kayıt dosyasının ekran görüntüsünde işaretli ilgili satırdan anladığımız Network-Manager’ın IP isteği yapmak için kullandığı “dhclient” programı, aldığı değerlerde bazı kontroller gerçekleştirerek şüpheli bulduğu içerikleri elemeye tabi tuttuğudur. Bundan ötürü bizim gönderdiğimiz değer elenerek “Dispatcher” betiğine temiz şekilde gönderiliyor ve zafiyeti tetikleyememiş oluyoruz. Peki “dhclient” yazılımı hangi değerleri elemeye tabi tutuyor, hangisine bakmıyor ve bu bakmadığı değerlerden hangisi istemci tarafından isteniyor? Bu soruların cevabını bulabilirsek zafiyeti tetikleme şansımız olabilecektir. İnternetten “dhclient” yazılımının kaynak kodunu indirerek incelemeye alırsak hangi değerlere eleme uyguluyor sorusunun cevabını bulabiliriz.

Ekran görüntüsünde yer aldığı gibi ilgili adresten kaynak kodun içerisinde hata mesajını aratarak hangi seçeneklerde bozuk değer bulduğunda bu hata mesajını bize veriyor görebiliyoruz.

İncelememiz sonucunda:

  • DHO_DOMAIN_NAME:
  • DHO_HOST_NAME:
  • DHO_NIS_DOMAIN:
  • DHO_NETBIOS_SCOPE:
  • DHO_DOMAIN_SEARCH:
  • DHO_ROOT_PATH:

seçeneklerinin filtrelemeye tabi tutulduğunu keşfettik. İstemcinin talep ettikleri seçeneklerden bunları çıkardığımızda içerisine düz metin olarak keyfi içerik girebileceğimiz diğer seçeneklerin kalması gerekiyor.

Ekran görüntüsünde istemcinin talep ettiği parametrelerden filtrelemeye tabi tutulanları işaretledik. “DHO_NETBIOS_SCOPE, DHO_ROOT_PATH” seçeneklerini talep etmediğini görüyoruz. Geriye kalanlar içerisinde ise düz metin girebileceğimiz yani IP adresi formatında bir değer içermeyen tek kısım “252” kimlik bilgisine sahip “Private/Proxy autodiscovery” olarak belirtilen ve WPAD kısaltma adına sahip alandır. Bunu atak vektörü olarak kullandığımızda başarıya ulaşıp ulaşamayacağımızı ve zafiyetin nasıl tetiklenebileceğini incelemeye yoğunlaşmamız gerekiyor.

Aynı sömürü kodunu bu sefer “252” şeçeneği için yazarak “Dnsmasq” servisimizi tekrar başlatıyoruz.

İstemci için DHCP isteğini yenilememiz gerekli.

Bundan sonra Wireshark üzerinde isteğe cevap olarak sömürü kodunun doğru gönderildiğini kontrol edelim.

Kayıt dosyalarında şüpheli bir girdi olduğuna dair içerik olup olmadığını kontrol edelim.

Bu sefer filtrelemede herhangi bir engele takılıp takılmadığımızı kayıt çıktısından görebiliyoruz. Peki komutumuz başarılı şekilde çalışmış ve ilgili dosyamız oluşmuş mu onu kontrol edelim.

Dosyamızın oluşmadığını görüyoruz. Yani sömürü kodu çalışmamış anlamına geliyor. Peki betiğin göndermiş olduğumuz değeri nasıl işlediğine bakalım.

Göndermiş olduğumuz değer işlenmiş ekran görüntüsünde görüldüğü üzere, ama burada komut çalıştırabilmek için ‘ (tırnak) işaretleri içerisinde yer alan değerlerin yine bir ‘ (tırnak) işareti ile kesilmesi ve sonrasında çalıştırmak istediğimiz kodun yer alması gerekiyor. Bu durumda ancak kod çalıştırma şansına sahip olabileceğiz. Bunu da aşağıda yer alan ekran görüntüsünde olduğu gibi düz metin sonrasında hemen ‘ (tırnak) işaretini yerleştirerek başarmamız mümkündür.

Bu şekilde düzenlediğimiz “dnsmasq” servisimizi tekrar başlatalım.

İstemci tarafında DHCP isteğini tekrardan tetikliyoruz.

İlgili dosyamızın oluşup oluşmadığını kontrol edelim.

Dosyamızın olmadığını görüyoruz. Betiğin ürettiği çıktıya baktığımızda söz diziminin gönderdiğimiz tırnak işareti ile kapatılarak değişken tanımından düzgün bir şekilde çıkış yaptığını, sonrasında ise 2 adet ‘ (tırnak) işareti ile yine bir değişken tanımı için hata düzeltimi adına yer açıldığını görüyoruz. Bu kısımda bizim açımızdan sorun teşkil eden bir şey bulunmuyor, hâlâ tırnak işaretlerinin dışında yer almakta ; (noktalı virgül) işareti ile başlayan sömürü kodumuz. Fakat en sonda yer alan ‘ (tırnak) işareti ile söz diziminin bozulduğunu görebiliriz. Bu kısmın bize teşkil ettiği sorunun etrafından dolanmak için ise gönderdiğimiz sömürü kodunun sonuna # (diyez) karakterini ekleyerek bu karakterden sonra gelen bütün değerlerin “Bash” kabuğu tarafından yorum satırı olarak değerlendirilmesini sağlamamız gerekiyor. Bunun için “dnsmasq” servisimizi ilgili değişikliği gerçekleştirerek son bir defa daha başlatıyoruz.

İstemci tarafında tekrardan DHCP yenilemesi yapmamız gerekli.

Sonrasında istediğimiz komutun çalıştığını “/tmp” dizini altını kontrol ederek görebiliriz.

Betiğin yorumlamasını kontrol ederek sömürü kodumuzun nasıl iletildiğini daha detaylı görerek yazımızın sonuna geliyoruz.

Buradaki zafiyet “Dispatcher” betiği içerisinde yer alan “read” komutunun kendisine gönderilen değerleri düzgün elememesinden kaynaklandığı görülmektedir. Bu betiği geliştiren yazılımcının tek yapması gereken “read -r” parametresi ile komutun düzgün elemesini aktif etmesi olacaktı. Yamalanmış “Network-Manager” paketinde ilgili değişikliği görebilirsiniz.

Hepinize güvenli günler dilerim.

Ref: https://dynoroot.ninja