Deserialization
Basic Information
Serileştirme, bir nesneyi saklanabilir bir formata dönüştürme yöntemi olarak anlaşılır; bu, nesneyi depolama veya bir iletişim sürecinin parçası olarak iletme amacı taşır. Bu teknik, nesnenin daha sonra yeniden oluşturulabilmesini sağlamak için yaygın olarak kullanılır ve yapısını ve durumunu korur.
Deserialization ise, serileştirmenin tersine olan süreçtir. Belirli bir formatta yapılandırılmış verileri alıp, tekrar bir nesne haline getirmeyi içerir.
Deserialization tehlikeli olabilir çünkü bu, saldırganların serileştirilmiş verileri manipüle ederek zararlı kod çalıştırmasına veya nesne yeniden yapılandırma sürecinde uygulamada beklenmedik davranışlar oluşturmasına olanak tanır.
PHP
PHP'de, serileştirme ve deserialization süreçlerinde belirli sihirli yöntemler kullanılır:
__sleep
: Bir nesne serileştirildiğinde çağrılır. Bu yöntem, serileştirilmesi gereken nesnenin tüm özelliklerinin adlarını içeren bir dizi döndürmelidir. Genellikle bekleyen verileri taahhüt etmek veya benzer temizlik görevlerini yerine getirmek için kullanılır.__wakeup
: Bir nesne deserialized edildiğinde çağrılır. Serileştirme sırasında kaybolmuş olabilecek veritabanı bağlantılarını yeniden kurmak ve diğer yeniden başlatma görevlerini yerine getirmek için kullanılır.__unserialize
: Bu yöntem, bir nesne deserialized edilirken__wakeup
yerine çağrılır (varsa). Deserialization süreci üzerinde__wakeup
'a göre daha fazla kontrol sağlar.__destruct
: Bu yöntem, bir nesne yok edilmek üzereyken veya script sona erdiğinde çağrılır. Genellikle dosya tanıtıcılarını veya veritabanı bağlantılarını kapatmak gibi temizlik görevleri için kullanılır.__toString
: Bu yöntem, bir nesnenin bir dize olarak işlenmesine olanak tanır. Bir dosyayı okumak veya içindeki işlev çağrılarına dayalı diğer görevler için kullanılabilir ve nesnenin metinsel temsilini etkili bir şekilde sağlar.
Eğer sonuçlara bakarsanız, nesne serileştirildiğinde __wakeup
ve __destruct
fonksiyonlarının çağrıldığını görebilirsiniz. Bazı eğitimlerde __toString
fonksiyonunun bir niteliği yazdırmaya çalışırken çağrıldığını göreceksiniz, ancak görünüşe göre bu artık olmuyor.
Eğer sınıfta uygulanmışsa, __unserialize(array $data)
metodu __wakeup()
yerine çağrılır. Bu, serileştirilmiş veriyi bir dizi olarak sağlayarak nesneyi serileştirmeye olanak tanır. Bu metodu, özellikleri serileştirmek ve serileştirme sırasında gerekli görevleri yerine getirmek için kullanabilirsiniz.
Açıklamalı bir PHP örneğini burada okuyabilirsiniz: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, burada https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf veya burada https://securitycafe.ro/2015/01/05/understanding-php-object-injection/
PHP Deserial + Autoload Sınıfları
Arbitrary php dosyalarını yüklemek için PHP autoload işlevselliğini kötüye kullanabilirsiniz:
PHP - Deserialization + Autoload ClassesReferans Değerleri Seri Hale Getirme
Herhangi bir nedenle bir değeri başka bir seri hale getirilmiş değere referans olarak seri hale getirmek istiyorsanız:
PHPGGC (ysoserial for PHP)
PHPGGC PHP deserialization'larını kötüye kullanmak için payload'lar oluşturmanıza yardımcı olabilir.
Uygulamanın kaynak kodunda bir deserialization'ı kötüye kullanmanın bir yolunu bulamayabileceğinizi unutmayın, ancak harici PHP uzantılarının kodunu kötüye kullanabilirsiniz.
Bu nedenle, mümkünse, sunucunun phpinfo()
'sunu kontrol edin ve internette (hatta PHPGGC'nin gadgets'lerinde) kötüye kullanabileceğiniz bazı olası gadget'ları arayın.
phar:// metadata deserialization
Eğer sadece dosyayı okuyan ve içindeki php kodunu çalıştırmayan bir LFI bulduysanız, örneğin file_get_contents(), fopen(), file() veya file_exists(), md5_file(), filemtime() veya filesize()** gibi fonksiyonlar kullanarak.** phar protokolünü kullanarak bir dosya okurken meydana gelen bir deserialization'ı kötüye kullanmayı deneyebilirsiniz. Daha fazla bilgi için aşağıdaki gönderiyi okuyun:
phar:// deserializationPython
Pickle
Nesne unpickle edildiğinde, __reduce__ fonksiyonu çalıştırılacaktır. Kötüye kullanıldığında, sunucu bir hata dönebilir.
Before checking the bypass technique, try using print(base64.b64encode(pickle.dumps(P(),2)))
to generate an object that is compatible with python2 if you're running python3.
For more information about escaping from pickle jails check:
Bypass Python sandboxesYaml & jsonpickle
Aşağıdaki sayfa, yamls python kütüphanelerinde güvensiz deserialization'ı istismar etme tekniğini sunmakta ve Pickle, PyYAML, jsonpickle ve ruamel.yaml için RCE deserialization yükü oluşturmak için kullanılabilecek bir araçla bitmektedir:
Python Yaml DeserializationClass Pollution (Python Prototype Pollution)
Class Pollution (Python's Prototype Pollution)NodeJS
JS Magic Functions
JS PHP veya Python gibi "sihirli" fonksiyonlara sahip değildir, sadece bir nesne oluşturmak için çalıştırılacak. Ancak, doğrudan çağrılmadan bile sıklıkla kullanılan bazı fonksiyonlar vardır, örneğin toString
, valueOf
, toJSON
.
Eğer bir deserialization'ı istismar ederseniz, bu fonksiyonları diğer kodları çalıştırmak için tehlikeye atabilirsiniz (potansiyel olarak prototype pollution'ı istismar ederek) ve çağrıldıklarında rastgele kod çalıştırabilirsiniz.
Bir fonksiyonu doğrudan çağırmadan çağırmanın başka bir "sihirli" yolu, bir async fonksiyondan dönen bir nesneyi tehlikeye atmaktır (promise). Çünkü, eğer o dönüş nesnesini **"then" adında bir fonksiyon türünde bir özellik ile başka bir promise'e dönüştürürseniz, başka bir promise tarafından döndürüldüğü için çalıştırılacaktır. Daha fazla bilgi için bu bağlantıyı takip edin.
__proto__
ve prototype
kirlenmesi
__proto__
ve prototype
kirlenmesiBu tekniği öğrenmek istiyorsanız aşağıdaki eğitime göz atın:
NodeJS - __proto__ & prototype PollutionBu kütüphane fonksiyonları serileştirmeye olanak tanır. Örnek:
Serileştirilmiş nesne şöyle görünecektir:
Örnekte, bir fonksiyon serileştirildiğinde _$$ND_FUNC$$_
bayrağının serileştirilmiş nesneye eklendiğini görebilirsiniz.
node-serialize/lib/serialize.js
dosyasında aynı bayrağı ve kodun bunu nasıl kullandığını bulabilirsiniz.
Son kod parçasında görebileceğiniz gibi, eğer bayrak bulunursa eval
fonksiyonu kullanılarak fonksiyon serileştirilir, bu nedenle temelde kullanıcı girişi eval
fonksiyonu içinde kullanılmaktadır.
Ancak, sadece bir fonksiyonu serileştirmek onu çalıştırmaz, çünkü kodun bir kısmının y.rce
'yi çağırması gerekir ve bu oldukça olasılık dışıdır.
Yine de, serileştirilmiş nesneyi değiştirerek bazı parantezler ekleyerek nesne serileştirildiğinde serileştirilmiş fonksiyonun otomatik olarak çalışmasını sağlayabilirsiniz.
Son kod parçasında son parantezi ve unserialize
fonksiyonunun kodu nasıl otomatik olarak çalıştıracağını fark edin:
Daha önce belirtildiği gibi, bu kütüphane _$$ND_FUNC$$_
sonrasındaki kodu alacak ve çalıştıracak eval
kullanarak. Bu nedenle, otomatik olarak kod çalıştırmak için fonksiyon oluşturma kısmını ve son parantezi silip sadece bir JS tek satırı çalıştırabilirsiniz aşağıdaki örnekteki gibi:
You can find here bu güvenlik açığını nasıl istismar edeceğiniz hakkında daha fazla bilgi.
funcster'ın dikkate değer bir yönü, standart yerleşik nesnelerin erişilemezliğidir; bunlar erişilebilir kapsamın dışındadır. Bu kısıtlama, yerleşik nesneler üzerinde yöntemleri çağırmaya çalışan kodun çalıştırılmasını engeller ve console.log()
veya require(something)
gibi komutlar kullanıldığında "ReferenceError: console is not defined"
gibi istisnalara yol açar.
Bu sınırlamaya rağmen, tüm standart yerleşik nesneler dahil olmak üzere küresel bağlama tam erişimin geri kazanılması, belirli bir yaklaşım aracılığıyla mümkündür. Küresel bağlamı doğrudan kullanarak, bu kısıtlamayı aşmak mümkündür. Örneğin, aşağıdaki kod parçası kullanılarak erişim yeniden sağlanabilir:
Daha fazla bilgi için bu kaynağı okuyun source.
serialize-javascript paketi yalnızca serileştirme amaçları için tasarlanmıştır ve yerleşik bir deserialization yeteneği yoktur. Kullanıcılar, deserialization için kendi yöntemlerini uygulamaktan sorumludur. Resmi örnek, serileştirilmiş verileri deserializing etmek için eval
'in doğrudan kullanımını önermektedir:
Eğer bu fonksiyon nesneleri deseralize etmek için kullanılıyorsa, bunu kolayca istismar edebilirsiniz:
Daha fazla bilgi için bu kaynağı okuyun source.
Cryo kütüphanesi
Aşağıdaki sayfalarda, bu kütüphaneyi kötüye kullanarak rastgele komutlar çalıştırma hakkında bilgi bulabilirsiniz:
Java - HTTP
Java'da, deserialization geri çağırmaları deserialization süreci sırasında çalıştırılır. Bu yürütme, bu geri çağırmaları tetikleyen kötü niyetli yükler oluşturan saldırganlar tarafından istismar edilebilir ve zararlı eylemlerin potansiyel olarak yürütülmesine yol açabilir.
Parmak İzleri
Beyaz Kutu
Kod tabanında potansiyel serileştirme zafiyetlerini tanımlamak için arama yapın:
Serializable
arayüzünü uygulayan sınıflar.java.io.ObjectInputStream
,readObject
,readUnshare
fonksiyonlarının kullanımı.
Aşağıdakilere ekstra dikkat edin:
Dış kullanıcılar tarafından tanımlanan parametrelerle kullanılan
XMLDecoder
.XStream
'infromXML
metodu, özellikle XStream sürümü 1.46 veya daha düşükse, çünkü serileştirme sorunlarına duyarlıdır.readObject
metodu ile birlikte kullanılanObjectInputStream
.readObject
,readObjectNodData
,readResolve
veyareadExternal
gibi yöntemlerin uygulanması.ObjectInputStream.readUnshared
.Genel
Serializable
kullanımı.
Siyah Kutu
Siyah kutu testleri için, java serileştirilmiş nesnelerini belirten belirli imzalar veya "Sihirli Baytlar" arayın ( ObjectInputStream
'den kaynaklanan):
Onaltılık desen:
AC ED 00 05
.Base64 deseni:
rO0
.Content-type
başlığıapplication/x-java-serialized-object
olarak ayarlanmış HTTP yanıt başlıkları.Önceki sıkıştırmayı belirten onaltılık desen:
1F 8B 08 00
.Önceki sıkıştırmayı belirten Base64 deseni:
H4sIA
..faces
uzantısına sahip web dosyaları vefaces.ViewState
parametresi. Bu desenleri bir web uygulamasında keşfetmek, Java JSF ViewState Deserialization hakkında detaylı bir inceleme yapılmasını gerektirmelidir.
Açık olup olmadığını kontrol et
Eğer Java Deserialized exploitinin nasıl çalıştığını öğrenmek istiyorsanız Basic Java Deserialization, Java DNS Deserialization ve CommonsCollection1 Payload belgelerine göz atmalısınız.
Beyaz Kutu Testi
Bilinen güvenlik açıklarına sahip herhangi bir uygulamanın kurulu olup olmadığını kontrol edebilirsiniz.
You could try to check all the libraries known to be vulnerable and that Ysoserial can provide an exploit for. Or you could check the libraries indicated on Java-Deserialization-Cheat-Sheet. You could also use gadgetinspector to search for possible gadget chains that can be exploited. When running gadgetinspector (after building it) don't care about the tons of warnings/errors that it's going through and let it finish. It will write all the findings under gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt. Please, notice that gadgetinspector won't create an exploit and it may indicate false positives.
Black Box Test
Using the Burp extension gadgetprobe you can identify which libraries are available (and even the versions). With this information it could be easier to choose a payload to exploit the vulnerability.
Read this to learn more about GadgetProbe.
GadgetProbe is focused on ObjectInputStream
deserializations.
Using Burp extension Java Deserialization Scanner you can identify vulnerable libraries exploitable with ysoserial and exploit them.
Read this to learn more about Java Deserialization Scanner.
Java Deserialization Scanner is focused on ObjectInputStream
deserializations.
You can also use Freddy to detect deserializations vulnerabilities in Burp. This plugin will detect not only ObjectInputStream
related vulnerabilities but also vulns from Json an Yml deserialization libraries. In active mode, it will try to confirm them using sleep or DNS payloads.
You can find more information about Freddy here.
Serialization Test
Not all is about checking if any vulnerable library is used by the server. Sometimes you could be able to change the data inside the serialized object and bypass some checks (maybe grant you admin privileges inside a webapp). If you find a java serialized object being sent to a web application, you can use SerializationDumper to print in a more human readable format the serialization object that is sent. Knowing which data are you sending would be easier to modify it and bypass some checks.
Exploit
ysoserial
The main tool to exploit Java deserializations is ysoserial (download here). You can also consider using ysoseral-modified which will allow you to use complex commands (with pipes for example).
Note that this tool is focused on exploiting ObjectInputStream
.
I would start using the "URLDNS" payload before a RCE payload to test if the injection is possible. Anyway, note that maybe the "URLDNS" payload is not working but other RCE payload is.
When creating a payload for java.lang.Runtime.exec() you özel karakterler kullanamazsınız, örneğin ">" veya "|" çıktıyı yönlendirmek için, "$()" komutları çalıştırmak için veya hatta argümanları bir komuta boşluklarla ayırarak geçiremezsiniz ( echo -n "hello world"
yapabilirsiniz ama python2 -c 'print "Hello world"'
yapamazsınız). Payload'ı doğru bir şekilde kodlamak için bu web sayfasını kullanabilirsiniz.
Tüm olası kod yürütme payload'larını Windows ve Linux için oluşturmak ve ardından bunları savunmasız web sayfasında test etmek için aşağıdaki scripti kullanmaktan çekinmeyin:
serialkillerbypassgadgets
You can use https://github.com/pwntester/SerialKillerBypassGadgetCollection birlikte ysoserial ile daha fazla exploit oluşturmak için. Bu aracın daha fazla bilgisi, aracın sunulduğu konuşmanın slaytlarında bulunmaktadır: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1
marshalsec
marshalsec farklı Json ve Yml serileştirme kütüphanelerini Java'da istismar etmek için yükler oluşturmak için kullanılabilir.
Projeyi derlemek için pom.xml
dosyasına bu bağımlılıkları eklemem gerekti:
Maven'ı kurun ve projeyi derleyin:
FastJSON
Bu Java JSON kütüphanesi hakkında daha fazla bilgi edinin: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html
Labs
Bazı ysoserial payload'larını test etmek istiyorsanız bu web uygulamasını çalıştırabilirsiniz: https://github.com/hvqzao/java-deserialize-webapp
Neden
Java, çeşitli amaçlar için çok fazla serileştirme kullanır:
HTTP istekleri: Serileştirme, parametrelerin, ViewState'in, çerezlerin vb. yönetiminde yaygın olarak kullanılmaktadır.
RMI (Uzak Yöntem Çağrısı): Tamamen serileştirmeye dayanan Java RMI protokolü, Java uygulamalarında uzak iletişim için bir köşe taşıdır.
HTTP üzerinden RMI: Bu yöntem, tüm nesne iletişimleri için serileştirmeyi kullanan Java tabanlı kalın istemci web uygulamaları tarafından yaygın olarak kullanılmaktadır.
JMX (Java Yönetim Uzantıları): JMX, nesneleri ağ üzerinden iletmek için serileştirmeyi kullanır.
Özel Protokoller: Java'da, standart uygulama, ham Java nesnelerinin iletimini içerir; bu, gelecek istismar örneklerinde gösterilecektir.
Önleme
Geçici nesneler
Serializable
arayüzünü uygulayan bir sınıf, serileştirilemeyecek herhangi bir nesneyi sınıf içinde transient
olarak işaretleyebilir. Örneğin:
Serializable'ı Uygulaması Gereken Bir Sınıfın Serileştirilmesinden Kaçının
Belirli nesnelerin sınıf hiyerarşisi nedeniyle Serializable
arayüzünü uygulaması gereken senaryolarda, istemeden deserialization riski vardır. Bunu önlemek için, aşağıda gösterildiği gibi, sürekli bir istisna fırlatan final
bir readObject()
metodu tanımlayarak bu nesnelerin deserializable olmadığından emin olun:
Java'da Deserialization Güvenliğini Artırma
java.io.ObjectInputStream
'i Özelleştirmek, deserialization süreçlerini güvence altına almak için pratik bir yaklaşımdır. Bu yöntem, aşağıdaki durumlarda uygundur:
Deserialization kodu kontrolünüz altındadır.
Deserialization için beklenen sınıflar biliniyor.
Deserialization'ı yalnızca izin verilen sınıflarla sınırlamak için resolveClass()
yöntemini geçersiz kılın. Bu, yalnızca açıkça izin verilen sınıfların, örneğin deserialization'ı yalnızca Bicycle
sınıfıyla sınırlayan aşağıdaki örnekte olduğu gibi, deserialization'ını önler:
Güvenlik Geliştirmesi için Java Ajansı Kullanımı kod değişikliğinin mümkün olmadığı durumlarda bir geri dönüş çözümü sunar. Bu yöntem esasen zararlı sınıfların kara listeye alınması için bir JVM parametresi kullanır:
Dinamik olarak deserialization'ı güvence altına almanın bir yolunu sağlar, anlık kod değişikliklerinin pratik olmadığı ortamlarda idealdir.
rO0 by Contrast Security örneğine bakın.
Serileştirme Filtrelerinin Uygulanması: Java 9, serileştirilmiş nesnelerin deserialization işleminden önce karşılaması gereken kriterleri belirlemek için güçlü bir mekanizma sağlayan ObjectInputFilter
arayüzü aracılığıyla serileştirme filtrelerini tanıttı. Bu filtreler, deserialization süreci üzerinde ayrıntılı kontrol sunarak küresel veya akış başına uygulanabilir.
Serileştirme filtrelerini kullanmak için, tüm deserialization işlemlerine uygulanan küresel bir filtre ayarlayabilir veya belirli akışlar için dinamik olarak yapılandırabilirsiniz. Örneğin:
Dış Kütüphaneleri Kullanarak Güvenliği Artırma: NotSoSerial, jdeserialize ve Kryo gibi kütüphaneler, Java deserialization'ını kontrol etme ve izleme için gelişmiş özellikler sunar. Bu kütüphaneler, deserialization'dan önce serileştirilmiş nesneleri analiz etme ve özel serileştirme stratejileri uygulama gibi ek güvenlik katmanları sağlayabilir.
NotSoSerial, güvensiz kodun çalıştırılmasını önlemek için deserialization süreçlerini engeller.
jdeserialize, serileştirilmiş Java nesnelerinin deserialization'ını yapmadan analiz edilmesine olanak tanır ve potansiyel olarak zararlı içeriği tanımlamaya yardımcı olur.
Kryo, hız ve verimliliğe vurgu yapan alternatif bir serileştirme çerçevesidir ve güvenliği artırabilecek yapılandırılabilir serileştirme stratejileri sunar.
Referanslar
Deserialization ve ysoserial konuşması: http://frohoff.github.io/appseccali-marshalling-pickles/
Gadgetinspector hakkında konuşma: https://www.youtube.com/watch?v=wPbW6zQ52w8 ve slaytlar: https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf
Marshalsec belgesi: https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true
Java ve .Net JSON deserialization belgesi: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf, konuşma: https://www.youtube.com/watch?v=oUAeWhW5b8c ve slaytlar: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf
Deserialization CVE'leri: https://paper.seebug.org/123/
JNDI Enjeksiyonu & log4Shell
JNDI Enjeksiyonu nedir, RMI, CORBA & LDAP aracılığıyla nasıl kötüye kullanılır ve log4shell'i nasıl istismar edilir (ve bu zafiyetin bir örneği) aşağıdaki sayfada bulabilirsiniz:
JNDI - Java Naming and Directory Interface & Log4ShellJMS - Java Mesaj Servisi
Java Mesaj Servisi (JMS) API'si, iki veya daha fazla istemci arasında mesaj göndermek için kullanılan bir Java mesaj odaklı ara yazılım API'sidir. Üretici-tüketici sorununu çözmek için bir uygulamadır. JMS, Java Platformu, Kurumsal Sürümü (Java EE) bir parçasıdır ve Sun Microsystems'te geliştirilen bir spesifikasyonla tanımlanmıştır, ancak o zamandan beri Java Topluluk Süreci tarafından yönlendirilmiştir. Uygulama bileşenlerinin Java EE tabanlı olarak mesaj oluşturmasına, göndermesine, almasına ve okumasına olanak tanıyan bir mesajlaşma standardıdır. Farklı bileşenler arasında iletişimi gevşek bir şekilde bağlanmış, güvenilir ve asenkron hale getirir. (Kaynak: Wikipedia).
Ürünler
Bu ara yazılımı kullanarak mesaj gönderen birkaç ürün bulunmaktadır:
İstismar
Temelde, tehlikeli bir şekilde JMS kullanan birçok hizmet vardır. Bu nedenle, bu hizmetlere mesaj göndermek için yeterli ayrıcalıklara sahipseniz (genellikle geçerli kimlik bilgilerine ihtiyacınız olacaktır), tüketici/abone tarafından deserialization yapılacak zararlı nesneler serileştirebilirsiniz. Bu, bu istismarda o mesajı kullanacak tüm istemcilerin enfekte olacağı anlamına gelir.
Bir hizmetin zayıf olduğunu hatırlamalısınız (çünkü kullanıcı girdisini güvensiz bir şekilde deserialization yapıyorsa) ancak yine de zafiyeti istismar etmek için geçerli gadget'lar bulmanız gerekir.
JMET aracı, bilinen gadget'lar kullanarak birkaç zararlı nesne serileştirerek bu hizmetlere bağlanmak ve saldırmak için oluşturulmuştur. Bu istismarlar, hizmet hala zayıfsa ve kullanılan gadget'lardan herhangi biri zayıf uygulamanın içinde ise çalışacaktır.
Referanslar
JMET konuşması: https://www.youtube.com/watch?v=0h8DWiOWGGA
.Net
.Net bağlamında, deserialization istismarları, bir nesnenin deserialization'ı sırasında belirli kodları çalıştırmak için gadget'ların istismar edilmesi gibi çalışır.
Parmak İzi
Beyaz Kutu
Kaynak kodu, aşağıdaki durumların varlığı için incelenmelidir: