Python Pickle ile Remote Code Execution Zafiyetleri

Merhaba

Diğer bir çok programlama dillerinde olduğu gibi, python’da da serialize işlemi yapılabilmektedir. Serialize işlemleri kullanıcı tarafından gönderilen girdiler üzerinde yapıldığında ise ciddi güvenlik açıklıkları oluşabilmektedfir. Daha önce PHP üzerinden anlatılan PHP Object Injection Saldırıları ve Korunması zafiyetinin bir benzeri Python içinde mevcuttur.

Pickle

Python dökümantasyonunda pickle için aşağıdaki tanım yapılmıştır.

 

The pickle module implements a fundamental, but powerful algorithm for serializing and de-serializing a Python object structure.

Pickle ile örnek bir Python objesi serializasyonu gerçekleştirelim.

import pickle

class Kullanici(object):
     isim = "Mehmet"      

print pickle.dumps(Kullanici())

Kullanici isminde ki sınıf serialize edilmiştir. Serialize edilmiş olan sınıfın string şeklinde ifade edilmiş hali aşağıdadır.

mince@prodaft tmp $ python a.py 
ccopy_reg
_reconstructor
p0
(c__main__
Kullanici
p1
c__builtin__
object
p2
Ntp3
Rp4
.

Bu çıktı syntax açısından okunması zor olduğu için bundan sonraki kodlarda serialize edilen sınıflar base64 ile encode edilecektir.

__reduce__ Fonksiyonu

Bir python objesi unserialize edilirken fonksiyon çağırılmak istenirse bu durumda __reduce__ fonksiyonu kullanılabilir. Python dökümantasyonunda ifade edilen açıklama şu şekildedir.

One alternative is for the object to implement a __reduce__() method. If provided, at pickling time __reduce__() will be called with no arguments, and it must return either a string or a tuple.

Bu durumda eğer kullanıcı girdileri unserialize edilmeye çalışılırsa, kullanıcı tarafından zararlı işlemler gerçekleştiren __reduce__ fonksiyonları tanımlanmış sınıflar oluşturulabilir. Bu durumda sonucunda ise hedef sunucuda istenilen komut çalıştırılabilir olacaktır.

import pickle
import os

class Kullanici(object):
     isim = "Mehmet"
     def __reduce__(self):
          return (os.system, ('ls',))

serialize = pickle.dumps(Kullanici())
pickle.loads(serialize)

Yukarıda kodlar analiz edildiğinde, komut satırında LS çalıştırılmaktadır. Serialize edilmiş Kulllanici sınıfı unserialize edilmek istenildiğinde __reduce__ fonksiyonu çağırılacaktır. Bu fonksiyonda komut satırında system()  fonksiyonu ile ls komutunu çalıştırmaktadır.

Bu zafiyetten Etkilenen Sistemler

Twisted Network Framework’u, Flask ve Django gibi popüler frameworkler serialization işlemi için Pickle kullanmaktadırlar.  Bir sonraki yazıda Django üzerinde bu zafiyetin neden olabileceği durumlar analiz edilecektir ve exploitation kısımları anlatılacaktır. Ayrıca bu zafiyeti barındıran hacking oyununa http://amateria.smashthestack.org:89/ adresinden erişebilir ve kendinizi test edebilirsiniz.