Apache Solr Injection Üzerine Araştırma


Öncelikle Herkese iyi bayramlar. Kurban bayramınız mübarek olsun. Bayrama özel bir yazı yayınlayım dedim. Bu yazımda bir araştırmacı kardeşimin Apache Solr Injection üzerine yaptığı güzel  bir araştırmayı çevirip, yorumlayıp, kendimden birşeyler katarak anlatmaya çalışacam. İsterseniz başlayalım.
Öncelikle Apache Solr nedir? onu açıklayalım:
Apache Solr , Apache Lucene projesinden Java ile yazılmış açık kaynaklı bir kurumsal arama platformudur. Başlıca özellikleri arasında tam metin araması, vurgulamayı vurgulama, yönlü arama, dinamik kümeleme ve belge ayrıştırma bulunur. Bir veritabanı gibi tehdit edebilirsiniz: sunucuyu çalıştırır, bir koleksiyon oluşturur ve kendisine farklı türde veri gönderirsiniz (örneğin metin, xml belgeleri, pdf belgeleri, hemen hemen her format). Solr bu verileri otomatik olarak endeksler ve üzerinde arama yapmak için hızlı ama zengin bir REST API arayüzü sunar. Sunucuyla konuşmak için tek protokol HTTP ve evet, varsayılan olarak kimlik doğrulama yapılmadan erişilebilir, bu da SSRF, CSRF ve HTTP İstek Sahteciliği saldırıları için mükemmel bir kurban olur.

Solr API hızlı genel bakış

Bir Solr örneği başlattığınızda (örneğin, "./bin/solr start -e dih" komutunu kullanarak) 8983 numaralı bağlantı noktasında bir web sunucusu oluşturur:
Varsayılan örnek, içindeki bazı verilerle gelir, böylece hemen arayabiliriz. Bu, "Apple" anahtar kelimesini tüm belgelerde arayan ve sonucu JSON biçiminde döndüren basit bir sorgudur:
Daha karmaşık bir sorgu şöyle görünebilir:
Buradaki ana parametreler:
  • /solr/db/select - koleksiyon adıdır, "/ select", SearchHandler tarafından işlenen bir arama işlemi gerçekleştirmek istediğimiz anlamına gelir.
  • q={!dismax+df=name}Apple - Bu sorgu "dismax" sorgu ayrıştırıcısını kullanarak "Apple" anahtar sözcüğünü içeren "ad" alanını arar. Parantezler arasındaki veriler Solr yerel parametreleri olarak ayrıştırılır.
  • fl=*,score,similar:[subquery] - "fl", döndürülecek alan listesinin kısaltmasıdır, [subquery] transformatörü , başka bir arama sorgusu ile elde edilen belgeye veri eklenmesini sağlar. Bizim durumumuzda alt sorgu "bilgisayar" anahtar kelimesini arar.
Aramanın dışında güncelleme işlemi yapma, yapılandırma görüntüleme ve değiştirme, hatta çoğaltma işlemi yapma imkanı da vardır. Solr Web Arayüzüne erişimimiz varsa, herhangi bir veriyi yükleyip değiştirebilir ve hemen hemen her işlemi yapabiliriz. Varsayılan olarak, hiçbir kullanıcı veya rol yoktur; bu onu SSRF, CSRF ve HTTP İstek Kaçakçılığı saldırıları için mükemmel bir hedef yapar.
Bu kadar açıklamadan sonra şimdi Apache Solr Injection olayını anlatmaya(çevirmeye) başlayabiliriz

Apache Solr Enjeksiyonu

Bir veritabanı gibi, çoğu durumda, Solr Rest API'sine son kullanıcılar tarafından doğrudan erişilemez ve yalnızca diğer uygulamalar tarafından dahili olarak kullanılır. Bu durumlarda, Solr kullanan web uygulamalarına karşı birkaç yeni saldırıyı anlatacaz.

Solr Parametreleri Enjeksiyonu (HTTP kaçakçılığı)

Bir hedef web uygulaması, Solr'a HTTP API çağrıları yaparken güvenilmeyen kullanıcı girişi kullanıyorsa, potansiyel olarak verileri URL Kodlaması ile düzgün şekilde kodlamaz. Yalnızca bir "q" parametresini kabul eden ve Solr'a sunucudan sunucuya HTTP isteği yaparak arama işlemini gerçekleştiren basit bir java web uygulaması:
@RequestMapping("/search")
@Example(uri = "/search?q=Apple")
public Object search1(@RequestParam String q) {

    //verilen anahtar sözcüğü solr içinde arar
    String solr = "http://solrserver/solr/db/";
    String query = "/select?q=" + q + "&fl=id,name&rows=10";
    return http.get(solr + query);
}


Bu parametreye hiçbir URL kodlaması uygulanmadığından, 'q=123%26param1=xxx%26param2=yyy' gibi yükler göndererek, Solr arama isteğine ek HTTP sorgu parametreleri enjekte edilebilir ve isteğin nasıl yapılacağı mantığı değiştirilebilir işlenmiş. Buradaki '% 26' karakteri, HTTP sorgusunda bir parametre sınırlayıcı olan '&' karakterinin kodlanmış sürümüdür.
Bir kullanıcıdan web uygulamasına normal bir istek:

GET /search?q=Apple
Web uygulamasından Solr sunucusuna aşağıdaki talebe yol açar:

GET /solr/db/select?q=Apple
Bir kullanıcıdan web uygulamasına kötü amaçlı bir istek:

GET /search?q=Apple%26xxx=yyy
Web uygulamasından Solr sunucusuna aşağıdaki talebe yol açar:

GET /solr/db/select?q=Apple&xxx=yyy

Burada görebileceğiniz gibi, parametre enjeksiyon güvenlik açığı nedeniyle, 'q' parametresi web uygulaması tarafından çözülür, ancak Solr sunucusuna yapılan istekte uygun şekilde kodlanmaz.  Yani, asıl soru, onunla ne yapabiliriz? İsteğin yine de '/ select' e gönderileceğini göz önüne alındığında, Sorl tarafında kötü niyetli bir şey yapmak için hangi parametreleri gönderebiliriz?  Peki, Solr birçok farklı sorgu parametresini destekliyor, ancak istismar için en ilginç olanı:
shards=http://127.0.0.1:8983/ - shards parametresini belirterek, hedef Solr sunucusunu ters proxy gibi davranarak bu isteği başka bir veya kendi zararlı Solr düğümümüze gönderebiliriz. Saldırganların, Solr sunucusuna rasgele veri beslemesine veya güvenlik duvarı korumalı Yönetici api'sine erişmesine olanak tanır.
qt=/update - istek için işleyiciyi yeniden yazmanıza izin verir (/ select / güncelleme veya başka herhangi bir seçim). Hassas uygulama her zaman '/ solr / db / select' isteğini gönderecek olsa da, bu isteğin bir arama isteği olarak işleneceğini düşünen sahte geliştiriciler oluşturabilir. Aslında, 'qt' ve 'shards' parametrelerini kullanarak '/ update' veya '/ config' Solr bitiş noktalarına ulaşabiliriz.
shards.qt = / update ayrıca istek işleyicisini yeniden yazmaya izin veriyor
stream.body=xxx - Tüm istek gövdesinin yeniden yazılmasına izin verir. En son sürümlerde devre dışı, ancak eski Solr sürümlerinde vardır.
Bu parametreleri Solr sorgusuna 'kaçırabilirsek', Solr örneği içinde veri değişikliğine, hatta bazı durumlarda RCE'ye yol açabilecek ciddi bir güvenlik açığı olabilir.

Sömürü örnekleri (Exploitation)

Solr config özelliklerini değiştirmek için exploit isteği şöyle görünebilir:

GET /search?q=Apple&shards=http://127.0.0.1:8983/solr/collection/config%23&stream.body={"set-property":{"xxx":"yyy"}}
Başka bir koleksiyondan veri sorgulamak için

GET /solr/db/select?q=Apple&shards=http://127.0.0.1:8983/solr/atom&qt=/update?stream.body=[%257b%2522id%2522:%25221338%2522,%2522author%2522:%2522orange%2522%257d]%26wt=json&commit=true&wt=json
Başka bir koleksiyondaki verileri güncellemek için:

GET /solr/db/select?q=orange&shards=http://127.0.0.1:8983/solr/atom&qt=/select?fl=id,name:author&wt=json
Bu güvenlik açığından yararlanmanın bir diğer yolu Solr yanıtını değiştirmektir. "Fl" parametresi, sorgu tarafından döndürülmesi gereken alanları listeler. Örneğin, aşağıdaki istekleri bildirerek yalnızca 'ad' ve 'fiyat' alanlarını döndürmek istiyoruz:

GET /solr/db/select?q=Apple&fl=name,price
Bu parametre işaretlendiğinde, belgeye ilave alanlar enjekte etmek için ValueAugmenterFactory (fl = name: [value v = 'xxxx']) kaldırabilir ve sorgunun içine enjekte edilen değeri ('xxxx') belirtebiliriz. Dahası, Xml Transformer (fl = name: [xml]) ile birlikte verilen değeri sunucu tarafında ayrıştırabilir ve bunu kaçışmadan sonuç belgesine dahil edebiliriz. Bu teknik örneğin XSS için kullanılabilir:

GET /solr/db/select?indent=on&q=*&wt=xml&fl=price,name:[value+v='<a:script+xmlns:a="http://www.w3.org/1999/xhtml">alert(1)</a:script>'],name:[xml]

ps no XXE burada maalesef  yok(en az 7.6)  
pps RawValueTransformerFactory solr 5.2+ sürümünde tanıtıldı

Solr Yerel Parametre Enjeksiyonu

Yalnızca "q" (query) parametresi güvenilmeyen girişden geldiğinde ve uygun şekilde kodlandığında daha sık görülen durumdur; örneğin:
@RequestMapping("/search")
public Object select(@RequestParam(name = "q") String query) {
    // verilen anahtar kelimeyi solr içinde bulur ve sonuç
    return httprequest(solrURL + "/db/select?q=" + urlencode(query));
}

Bu durumda, bu çözümleyici tarafından kullanılan çözümleyici türünü ve Solr yerel parametrelerini belirtmek yine de mümkündür , örneğin:

GET /search?q={!type=_parser_type_+param=value}xxx
Bu saldırı 2013 yılında tekrar açıklandı , ancak 2017 yılına kadar kimse onu nasıl kullanacağını bilmiyordu. 2017'de, CVE-2017-12629'u bildirdik ve 'xmlparser' ayrıştırıcısını kullanarak XXE'yi tetiklemenin ve bunu Solr parametreleri enjeksiyon güvenlik açığına yükseltmenin bir yolunu keşfettik:

GET /search?q={!xmlparser v='<!DOCTYPE a SYSTEM "http://127.0.0.1:/solr/gettingstarted/upload?stream.body={"xx":"yy"}&commit=true"'><a></a>'}
CVE-2017-12629'un çalışmadığı ya da yamanın uygulanmadığı diğer Solr versiyonlarında , yerel parametrelerin enjeksiyonu neredeyse zararsızdır. Muhtemelen DoS'a neden olmak için kullanılabilir, ancak lucene sözdizimini kullanarak bile ağır sorgulamalar yapabiliriz, bu yüzden DoS burada gerçekten sayılmaz. Yerel parametreler enjeksiyonundan yararlanmanın başka bir olası yolu, başka bir koleksiyondan verilere erişmek için Join Query Parser'ı kullanmaktır:

GET /search?q={!join from=id fromIndex=anotherCollection to=other_id}Apple
Ancak başka bir koleksiyonun aynı kimlikleri içermesi gerektiği için her zaman mümkün değildir. Bu nedenle, birileri yerel parametreler enjeksiyonundan yararlanmanın daha iyi bir yolunu bulana kadar, CVE-2017-12629'un yamalı olduğu göz önüne alındığında, bunu bir güvenlik açığı olarak görmezdim .

RCE Alma Yolları

Saldırganlar normalde küme içinde depolanan verilerle ilgilenmiyor (hassas olmayabilir), ancak RCE veya yerel dosya okumayı elde etmekle ilgileniyorlar. Neyse ki, buna izin veren birkaç güvenlik açığı var. Ben burada sadece cve-2019 olarak yazılmış kısımı çeviriyorum. Ayrıntılı bakmak isteyen için link verebilirim (cve-2017den bu yana olan açıkları)

[CVE-2019-0193] dataImportHandler aracılığıyla Uzaktan Kod Yürütme

Hedef Solr sürümü : 1.3 - 8.2  
Gereksinimler: DataImportHandler etkinleştirilmelidir, varsayılan olarak bu değildir.
Solr, veritabanlarından veya URL'lerden veri almak için yararlı olan isteğe bağlı bir DataImportHandler'a sahiptir, içe aktarılan her belge için Solr sunucusunda yürütülecek dataConfig parametresinin komut dosyası etiketine isteğe bağlı JavaScript kodu eklemek mümkündür.
Solr sunucusuna doğrudan bağlantı yoluyla Exploit:
Test ederken, 'varlık' bölümünde belirtilen URL'nin Solr tarafından erişilebilir olduğundan ve Xpath değerlendirmesi için geçerli bir XML belgesi döndürdüğünden emin olun.
DataImportHandler'dan yararlanmanın bir başka yolu da "com.sun.rowset.JdbcRowSetImpl" sürücüsü ile birlikte dataSource tipi "JdbcDataSource" kullanmaktır:
Bu şekilde, 'com.sun.rowset.JdbcRowSetImpl' sınıfını temel alan bilinen gadget zinciri ile bir seri kaldırma saldırısı tetikleriz. 'JndiName' ve 'autoCommit' özellikleri için iki ayarlayıcıya ihtiyaç duyuyor ve bizi savunmasız 'InitialContext.lookup' işlemine götürüyor, bu yüzden sıradan bir JNDI çözümleme saldırısı olarak faydalanabiliriz.

Sonuç olarak;

Solr örneğinin internete ya da ters proxy'nin arkasına bakması veya yalnızca dahili web uygulamaları tarafından kullanılması farketmeksizin, Solr arama parametrelerinin değiştirilmesine izin vermek önemli bir güvenlik riskidir. Yalnızca Solr kullanan bir web uygulamasının erişilebilir olduğu durumlarda, Solr (yerel) Parametre Enjeksiyonundan yararlanarak, Solr kümesindeki tüm verileri en azından değiştirmek veya görüntülemek, hatta uzaktan kod yürütme elde etmek için bilinen güvenlik açıklarından yararlanmak mümkündür.

Yazıyı burada noktalıyorum. Kusurum olmuşsa Affola. Başka bir yazıda görüşmek üzere..:)

***Haşiye: Solr Üzerinde yayınlanan CVE'ler (CVE-2012-6612, CVE-2013-6407, CVE-2013-6408,CVE-2019-0193,CVE-2019-0192,CVE-2017-12629) bu cve numaraları ile google üzerinden daha ayrıntılı araştırma yapabilirsiniz. Herkese iyi çalışmalar..:)

Yorumlar

Bu blogdaki popüler yayınlar

Bazı JavaScript Kütüphaneleri Ve Zafiyetleri

NASA Reflected XSS Write Up

Herşey Bir Tırnakla Başladı