Ring0 CTF Web Çözümleri

Cezeri

Yönetici
Konu karmaşası olmaması adına tek başlıkta toplayalım dedik.
Çözümler eklendikçe konuya post geçilecektir.


"Propaganda Mail" sorusu


Selamlar,

İnternette bulunan online CTF’ler arasından en beğendiklerimden birisi olan RingZeroTeam CTF’inde bulunan web sorularından “Propaganda Mail” sorusunun çözümünü anlatacağım. Bu soru genel manada RCE ve zayıf filtreleme konularını içermektedir.

Soru Linki ; Propaganda mail 12

Üye olup giriş yapıp soruya gittiğinizde aşağıda ki gibi bir ekranla karşılaşacaksınız.

2019-06-22%2021-32-43%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Burada bulunan “Download Propaganda Package” butonuna basarak kullanılan scripti indirip inceliyoruz.

2019-06-22%2021-49-12%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Bu kodlar incelendiğinde, 11. satırda “Command Execution” zafiyetlerinden çok iyi bildiğimiz “shell_exec” fonksiyonunun kullanıldığını görebiliyoruz.

shell_exec('cd ' . $path . ' && python ' . $module . ' ' . $_REQUEST['target'] . ' 2>&1')

Şimdi bu fonksiyona nasıl erişebiliyoruz, erişebilmek için hangi koşulları sağlamamız gerekiyor onu inceleyelim.

  • 1 numaralı bölümde “target” ve “module” adlı iki parametre göndermemiz durumunda scriptin çalışacağını görüyoruz.
  • 2 numaralı kısımda “target” parametremizin email adresi olup olmadığını kontrol etmek adına “FILTER_VALIDATE_EMAIL” fonksiyonu kullanılmış.
  • 3 numaralı kısımda ise shell_exec kullanılarak, önce $path değişkeni olarak belirlenen “/var/www/html/propaganda/utils” dizinine geçiş yapılıyor ve daha sonra bu “utils” dizininde bulunan ve bizim “module” parametresi ile gönderdiğimiz python scripti “target” parametresini içerisine alarak çalıştırılıyor.

“index.php” dosyasında yapılan işlemler bu şekildeydi. Şimdide son maddede belirttiğimiz “utils” dizininde bulunan python scriptlere bir göz atalım.

2019-06-22%2022-07-11%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


“utils” dizininde 3 adet python script bulunuyor ve 3 scriptin içeriği de birebir aynı. Bu scriptler mail göndermiyor sadece kendisine verilen parametreyi alarak, ekrana “Email sent to [TARGET]” şeklinde bir yazı basıyor. Yani bu scriptlerde bizim için önemli bir durum yoktur.

Şimdi biz index.php dosyamızda bulunan shell_exec fonksiyonunu çalıştırmak adına çeşitli sorgular gireceğiz.

Bu sorgularda dikkat etmemiz gereken mevzu ise FILTER_VALIDATE_EMAIL adlı fonksiyon. Bu fonksiyon bizim “boşluk” - “parantez” gibi karakterlerimizi engelliyor, ve girdiğiniz değerin “@xx.com” olarak sonlanıp sonlanmadığını kontrol ediyor. Dolayısıyla girdiğimiz değerleri bu doğrultuda modifiye etmemiz gerekmektedir.

Normal şartlarda shell_exec fonksiyonu kullanılmış olsaydı “$(ls)@test.com” komutunu kullanarak “ls” komutunun çıktısını alabilirdik ama “FILTER_VALIDATE_EMAIL” fonksiyonu gereğince parantezleri kullanamıyoruz. Fakat bu fonksiyon “backtick” özel karakterini filtrelemiyor ve biz komutlarımızı bu karakter vasıtasıyla çalıştırabiliyoruz.

`ls`@test.com payloadını kullanarak “ls” komutunun çıktısını alabiliyoruz.

2019-06-22%2022-40-41%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC



Şimdi kök dizine inip burada hangi dosyalar olduğuna bakalım. Bu amaçla `ls /`@test.com payloadını giriyoruz.

2019-06-22%2022-47-49%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Fakat gördüğünüz üzere hata ile karşılaşıyoruz. Bunun nedeni yukarıda anlattığımız üzere “boşluk” karakterinin FILTER_VALIDATE_EMAIL fonksiyonu ile engellenmiş olmasıdır.

Bu filtreyi atlatırken de daha önce açtığımız Godaddy Firewall Bypass → RCE Bypass 3 adlı konuda anlattığımız üzere boşluk karakterine alternatif olarak “$IFS” değerini kullanabiliyoruz.

2019-06-22%2022-49-08%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Bu şekilde kök dizinde bulunan dosyaları listeleyebiliyoruz fakat birden fazla dosya bulunmasına rağmen sadece 1 adet dosyayı gösterdi. Bunu atlatmak amacıyla “çift tırnak” karakteri ile komut olarak olarak anlaşılmasını sağlıyoruz ve "`ls$IFS/`"@test.com payloadı ile tam çıktıyı elde ediyoruz.

2019-06-22%2022-51-59%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Bu çıktıda görüldüğü üzere “flag_weak_filter_or_regex.txt” adlı dosya bizim flag değerini içeriyor.
Final payload olarak "`cat$IFS/flag_weak_filter_or_regex.txt`"@test.com değerini giriyoruz ve flag değerini elde ediyoruz.

2019-06-22%2022-57-47%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC



Demo Uygulama ;


Vakit buldukça bu CTF’in Web ve SQL Injection kategorilerinde bulunan kaliteli soruların çözümlerini paylaşacağız.

Jonturk @ JRBops
 

Cezeri

Yönetici
"Read the unreadable" sorusu

RingZer0 ekibinin bu sorusunun çözümünde HTTP İstek Başlıklarından bir tanesi olan “Range” başlığını incelenecektir. Reel hedefler üzerinde pek işinizi göreceğini düşünmüyorum fakat farklı konular adına ufuk açıcı bir soru olabileceği için paylaşıyorum.

Soru Linki ; Read the Unreadable 1

2019-06-24%2021-56-58%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Soruya girdiğinizde “Bu sayfanın içeriği FLAG kelimesini içerdiğinden engellendi” gibi bir ibare ile karşılaşıyoruz. Bizim izleyeceğimiz yol site içeriğini belirli aralıklara bölerek içerisinde FLAG kelimesi geçmeyecek şekilde isteklerde bulunmak olacak.

Bu noktada yardımımıza “Range” HTTP Başlığı koşuyor. Range başlığı ; kaynağın yalnızca bir bölümünü istediğini belirtir. İstenen bölüm, başlık içerisinde byte değerlere bölünerek ayrılabilir.

Genel manada kullanımı ; “Range: bytes=880-1000/*” şeklinde olabilmekte. Bu istek sonucunda 120 byte karakterin çıktısını alıyoruz. Hemen test edelim.

2019-06-24%2022-40-07%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Daha önceki soruların FLAG değerlerinden bilindiği üzere soruların cevaplarının formatı “FLAG-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx” şeklindedir. Sayfayı bytelara bölerken FLAG kelimesinin olmadığı aralığı bulmamız gerekiyor. Flag değerleri 37 karakterden oluşuyor. İlk karakter olan “F” harfinin olmadığı 36 karakterlik atlamalar yaparak isteklerde bulunacağız ve kolaylıkla sonuca ulaşacağız.


Bu amaçla basit bir python scripti yazıp, işlemimizi otomatize edip flag değerini elde edelim.

2019-06-24%2023-13-20%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Bu script, yukarıda bahsettiğimiz gibi 36 bytelık aralıklarla isteklerde bulunacak ve içerisinde “LAG-” kelimesinin olduğu ve aynı zamanda sayfamızın engellendiğini ifade eden “blocked” kelimesinin olmadığı aralığı bulup ekrana FLAG değerini ve kullanılan payloadı basacak.

2019-06-24%2023-15-05%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Çıktıdan görüldüğü üzere “Range: bytes=1068-1104/*” şeklinde bir istek atarak FLAG değerini elde ettik.

Manuel kontrolümüzüde gerçekleştirelim ;

2019-06-24%2023-17-30%20ekran%20g%C3%B6r%C3%BCnt%C3%BCs%C3%BC


Jonturk @ JRBops
 

Cezeri

Yönetici
" Facebook will never forget this one"

Bu sorunun amacı XXE yöntemine değinmek. XXE, sitenin parse etmeye çalıştığı XML verisini manipüle ederek “File Read” ve/veya “Command Execution” tarzı zafiyetler elde etmemize olanak sağlayan bir güvenlik zafiyetidir.

NOT : XXE konusunu detaylı bir şekilde forumda ele alacağız.

Şimdi sorumuza geçelim.

“Facebook will never forget this one” Soru Linki 1





Kaynak koda bakarsanız JavaScript ile yazılmış scriptte bir XML isteği ile tarih bilgisi ekrana bastırılıyor.


01bb451be7dff18283fb1d5707513b7a9d9fcbed.png



Soru linkine girdiğinizde BurpSuite ile inceleme yaparsanız, “tarih ve saat” bölümünün otomatik POST edilen XML verisinden getirildiğini görebilirsiniz. Bu POST isteğini BurpSuite Repeater bölümüne alıp incelemesini yapalım.

11cc5d332bedb46d8f6055b1b5c48a1fd3e64c8a.png



POST edilen veriyi URL Decode ettiğimizde <date> şeklinde belirtilen tag içerisinde gönderilen tarih bilgisinin ekrana basıldığını görebiliyoruz.


d4134cda883a7053a7b1ca984cb6e47fe13018b5.png



tag içerisine eklediğimiz herhangi bir yazı ekrana basılıyor, biz bu XML isteğinde dışardan “/etc/passwd” dosyasının alınacağı bir ENTITY tanımlayarak ekrana bu ENTITY içeriğini bastıracağız ve /etc/passwd dosyasının içeriğini okuyacağız.

Bu amaçla ;

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jonturk [<!ELEMENT vvHack ANY ><!ENTITY xxe SYSTEM "file://../../../../../../../../../../../etc/passwd" >]>

şeklinde bir ENTITY oluşturuyoruz ve bunu <date> </date> tagları arasına çağırıyoruz ve /etc/passwd dosyası içindeki FLAG değerini elde ediyoruz.


88fdeb392ce7da78409147445e2ad155abc8c553.png
 
Moderatör tarafında düzenlendi:
Üst