MdiseCTF 0x02 – Türk Bayrağı Ödüllü CTF Çözüm ve Kazananlar

Merhaba

Geçtiğimiz çarşamba günü başlayan ve 13 Eylül Pazar günü son bulan MdiseCTF 0x02 – Türk Bayrağı Ödüllü CTF Yarışmasının  çözümleri ele alınacaktır. Buyrun sizlerin yaşamış olacağınız süreçleri adım adım ele alarak çözüme ulaşalım.

Login ve WAF

https://0x02.mehmetince.net/ CTF adresi ziyaret edildiğinde bir adet login sayfası çıkmaktaydı. HTML kodlarında herhangi bir ip ucu yoktu. Ayrıca hatalı kullanıcı adı ve parola ikililerinde “Kullanıcı mevcut değildir” gibi bilgi ifşasına neden olan “hatalı” hata mesajlarıda yoktu. Weak password anlamında yapılabilecek testlerde başarısız olacaktı zira kullanıcı adı ve parola admin ve iRlTUqc2Ruk1QIJ7eRTp9ycmDhAPN idi.

Peki bu tür durumlarda ne yapmalı ? sorusuna cevap olarak akla ilk gelen saldırı sql injection yöntemidir. “or”1=”1 gibi bilinen SQL Injection payload’ları ise Web Application Firewall tarafından tespit edilerek engelleniyordu. Bir çok deneme sonunda görülecektir ki ilişkisel veri tabanı sistemlerine yönelik sql injection saldırısı WAF tarafından tespit edilerek başarısız olacaktır. Bu noktada aklımıza gelmesi gereken şey NoSQL Injection olmalıydı. Bu konu daha önce MDISec blogda MongoDB ve NoSQL Injection Zafiyetleri yazısı ile ele alınmıştı.

Yukarıda ki payload ile NoSQL Injection bypass gerçekleştirilebilir.

Excel

Login sonrası erişilen admin sayfasında bizi bir mesaj karşılamaktaydı. “Tebrikler, ilk asama tamam..! Buyrun buradan devam edin. Click” tıklama sonrası ise aşağıdaki request’i bir adet XML dosyasına erişilmiş olacaktı. https://0x02.mehmetince.net/admin.php?c=download Bu XML dosyasını Excel ile açtığınızda aşağıdaki bilgilere erişiliyor olacaktı.

Screen Shot 2015-09-13 at 10.36.39 PM

Bu Excel’e ilk bakışta aşağıdaki bilgilere erişmek son derece kolaydır.

  • 25 adet isim, soyisim, doğum tarihi, encrypted, pass_reminder kolonları olan veri bulunmaktadır.
  • 26. satır ulaşmamız gereken bayraktır.
  • Encrypted isimli kolon belli ki kullanıcı parolalarının tutulduğu yerdir.
  • Reminder ise kullanıcıların parolalarını hatırlatmak adıyla girdikleri bilgidir.

Şimdi ise sıra şifreli metinlerimizin olduğu encrypted alanında ki verileri analiz etmede. Çünkü FLAG alanında ki veriye erişmek istiyorsak öncelikle şifreleme algoritması hakkında bilgi sahibi olmalıyız.

Cipher

İlk iş base64 bilgiyi decode edip hex olarak alt alta yazarak bakalım.

Çıktı olarak tüm cipher-text’lerin hex halini yazdırdık ve çıktı aşağıda ki gibi oldu.

İlk olarak plain-text uzunluklarını analiz edeceğiz. Bu sayede kullanılan encryption algoritması bilinen block-cipher’dan birisi mi ? sorusuna cevap üretmeliyiz. Bunun için script’imizde ufak bir modifikasyon ile bit size’larını ölçeceğiz.

Görüldüğü üzere FLAG datamız 65 karakterden oluşmakta. Bunun haricinde diğer satırlara baktığımızda 4 ile 10 arasında değişimler gözlemlenmektedir. Bu durumda “Hangi bilinen algoritma şifreleme işlemi sonucu 4 ile 10 karakterlik çıktılar verebilir ?” sorusu akıllara gelmektedir.

DES, AES veya Bilinen Block Cipher’lar

Crypto 101 – [2] Block Cipher Encryption ve DES Analizi yazısında ele alındığı üzere, DES 64bitlik yani 8 byte’lık karakterler halinde şifreleme işlemi gerçekleştirmektedir. 64bit’ten küçük blocklar için, örneğin 1337 parolasını şifrelerken, padding adı verilen veriyi 64 bit’e tamamlama işlemi gerçekleştirilmektedir. Bu durumda veriniz 8 byte’tan küçük olsa bile çıktınız 8 ve 8’in katları halinde olacaktır.

Bizim encrypted alanımızda 4,6,9,10 ve 65 byte’lık şifreli veriler bulunmaktadır. Bu bağlamda ne DES nede AES gibi bilinen hiçbir block cipher algoritmasının burada kullanılmadığı aşikardır.

XOR ?

Hex çıktısını sort uniq ile sıralayalım.

Görüldüğü üzere 6b 5d 61 67 04 50 encrypted alanı 4 kere geçmekte. Yani 25 kişiden 4 kişinin parolası aynı cipher-text’e sahip. Bu durum bize şifreleme mekanizması içerisinde herhangi bir zaman değeri, kişiye özel üretilmiş karakter katarı vb durumların olmadan doğrudan kullanıcı parolalarının encryption’a girdiğini göstermektedir.

Bir diğer dikkan çeken nokta ise 6b 5d 61 67 serisinin 8 farklı kullanıcının parolasında geçmesidir.

Bu bilgiler ışığında, kullanılan şifreleme mekanizmasının sadece basit, düz bir XOR olduğunu düşünebiliriz. Bunun nedeni ise FLAG alanı haricinde ki verilerin en fazla 10 byte uzunlukta olmasıdır. Herhangi bir Block Cipher algoritmasının kullanılmadığına emin olduğumuz için FLAG’i decrypt edebilmemiz, onun içinde geriye kalan 25 satırlık veriyi kullanarak private key’i elde etmemiz gerektiğini düşünmemiz son derece mantıklı olacaktır.

Known plaintext attack

Known plaintext attack, saldırganın şifreleme algoritmasına giren plain-text’i ve algoritmanın çıktı olarak verdiği cipher-text’i bildiği ama algoritmanın kendisini veya algoritmada kullanılan private key’i bilmediği durumlarda kullanılan yöntemdir. Eğer şifreleme algoritması known-plaintext attack’a karşı zaafı varsa, OTP XOR gibi, bu iki bilgiden private key’i elde etmek mümkündür.

Peki biz plain-text’i nereden bulacağız ? sorusuna ise iki cevap var, reminder alanı ve Most Common Passwords. Öncelikle reminder alanına bakalım.

Reminder alanında ki veriler aslında basit anlamda bir çok bilgiyi vermekte. Örneğin;  “Dört’e kadar” anlamına gelen until4 büyük ihtimalle parolası “1234” olan kullanıcıyı ifade etmekte. Bir diğer örnek ise “Her zaman olduğu gibi” anlamına gelen “as usual” büyük ihtimalle yer yüzünün en çok kullanılan parolası olan 123456‘yı ifade etmekte. Yahut reminder’ı “ma birth day” olan kişinin parolası, doğum tarihi veya doğum tarihinin iki kere yazılması ile elde edilen bilgidir. ( Excel’de birth_day alanının boş yere koymadığımızı unutmayın!)

Bu bağlamda ben 123456’dan yola çıkarak private key’i elde etmeye çalışacağız. Zaten 6b 5d 61 67 04 50 bilgisinin de 4 defa 25 kişilik listede tekrar etmesi, “Dünyanın en çok kullanılan parolasının, bizim 25 kişilik listemizde de en çok kullanılmış parola olması” ihtimalini son derece güçlendiren bir bulgudur.

Harika! Z0RS1f bilgisi bize yaklaşımımızın doğru olduğunu gösterdi. Ama bir başka problemi de doğurdu. 123456 şifresini tahmin etmekte başarılıydık ama 123456 verisi bizim private key’imizden kısa olabilir. Bu nedenle en baştada ki HEX listesimize dönüp daha uzun bir parolayı tahmin etmeliyiz. Zaten İlk 6 karakteri artık decrypt edebilir durumdayız.

4 adet 123456 parolasının olduğunu biliyorduk. Ama 2 adet daha içerisinde 123456 bütününü barındıran parola olduğu görülmektedir. Bu parolaların reminder’ları var mı ? ona baktığımızda ise hex karşılığı 6b 5d 61 67 04 50 45 0b 63 5f olan parolanın reminder’ı “one to 9” yani “birden dokuza kadar” anlamına gelmekte.

Harika..! Gördüğünüz üzere ZoRS1fr3Zn bilgisini elde ettik. Burada fark edilen şey Z karakterinin tekrar ederek devam etmesi. Bunun sebebi ise parolanın, 123456789’dan daha uzun olan ama başlangıcı kesinlikle 123456789 olması! Private key’den daha uzun bir plain-text geldiği için cycle işlemi gerçekleştirilerek ilk karaktere dönülüp XOR işlemi devam etmektedir. Bu bağlamda

Private Key = ZoRS1fr3

dir.

Flag

Elde edilen key ile tüm metin deşifrelenir ve …

ve sonuç olarak aşağıdaki  bilgi elde edilir.

Değerlendirme Süreci ve Başvuranlar

Değerlendirme süreci şu şekilde olmakta.

  1. Sadece ve sadece tam/doğru çözümü gönderen kişiler seçilir.
  2. Çözümü ilk gönderen kişi 100 puan, ikinci gönderen kişi 95 puan şeklinde azalan değerler çözüm gönderen yarışmacılara sırasıyla verilir. En son ise 70 sabitlenecektir. Bu değer T ile ifade edilir.
  3. Yazılan raporlara değerlendirme ekibi tarafından 100 üzerinden puan verilir. Bu değer R ile ifade edilir.
  4. T değerinin %25,  R değerlerinin %30’u alınır.
  5. Her katılımcı için 0-20 arasından random seçilen değerin %50’si alınır.
  6. Bu üç değer toplanır ve
  7. En yüksek puanı alan yarışmayı kazanır.

Kazanan Kişi

Algoritmamızı uyarlayan ufak bir python kodu..!

Bu sonuçlara göre;

Kazanan = Kadir Çetinkaya..!

Katılan herkese için teşekkürler.

  • Ömer Altundal

    Bence çok öğretici olmuş. Pentest yapanların ilk olarak yaptığı Brute Force denemeleri ve SQLi aramalarının boşa gittiği durumda havlu atılmaması gerektiğini öğrendim :) Bir de CloudFlare’in NOSQL injection parametrelerini filtrelemediğini öğrendim (Ya da mdisec bunu sen mi iptal ettin?)

    • Teşekkürler :-) Cloudflare WAF rule konusunda son derece başarılı. Rule listesinden popüler sistemler için cloudflare tarafından optimize edilmiş set’leri seçebiliyorsunuz. Ben PHP + WordPress rule set’ini seçili bıraktım. Zaten firmalarda mevcut sistemlerini korumak adına bu tür rule set’ler seçmekte. Ama bu WAF’ın arkasına Nodejs ile yazılmış yeni bir uygulamayı koyduğumuzda “WAF bizi korur!” düşüncesinin anlamsız olduğunu gösterdiğimiz bir uygulama olsun istemiştim.

      • Ömer Altundal

        Bir bilgi de buradan geldi (: Sallanan dut ağacının altında çarşafı açmış, dolmasını bekler durumdayız :) eline sağlık.