Skip to content

Hack Karadeniz 2022 CyberCafe sorusu için yazdığım writeup

License

Notifications You must be signed in to change notification settings

f4T1H21/HackKaradeniz22-Web-CyberCafe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 

Repository files navigation


Selam, ben Şefik Efe. HackKaradeniz 2022 yarışmasındaki sorular arasından bir tek bu soru için writeup hazırlıyorum. Bunun sebeplerinden bir tanesi benim için ayrıcalıklı bir yere sahip olması.

Gelelim genel değerlendirmeye, soru iki aşamadan oluşuyor İkinci aşaması kaliteli ve ileri seviye denebilecek nitelikte. Aynı zamanda yarışma esnasında bana en çok 'vakit kaybettiren' sorudur kendisi, ki bunun da sebebini en son anlayacaksınız.

Buradan CyberCafe yazarına selam gönderiyor, Flag'i daha adam akıllı bir yere koyamadınız mı diye soruyor ama yine de böyle bir soruyu yazdığından dolayı teşekkür ediyorum.

Ayrıca Yusuf Saraçlıoğlu arkadaşıma da kafamda başka bir soruya bakmak varken bana bu soruda hatırı sayılır miktarda foothold verdiğinden dolayı da teşekkür ediyorum.

Twitter: @f4T1H21
LinkedIn: Şefik Efe
HackTheBox: f4T1H


Bilgi toplama

Açıklamayı incelediğimizde bir test domaini ile karşı karşıya olduğumuz söyleniyor. Uygulama, henüz ürün (production) ortamında olmadığından dolayı arama motoru crawlerlarının erişmesi istenmeyen dizin/dosyalar olabilir. Bunları kontrol için /robots.txt dosyasına bakabiliriz.

Scope'umuz belli oldu: challenge105.hackkaradeniz.xyz/k1j2uzn2q00b

Her şeyden önce hızlı bir dizin taraması sonucunda /k1j2uzn2q00b/includes isimli bir dizin görüyoruz.

Tüyo: /includes dizini içerisindeki varsa php dosyalarının isimleri bize backend'te neler döndüğüne dair fikir verebilir.

root@f4T1H:~# gobuster -q dir -u https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/ -w /usr/share/wordlists/dirb/common.txt -x .txt,.php,.js -e -t 75 
https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/assets (Status: 301)
https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/images (Status: 301)
https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/includes (Status: 301)
https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/index.php (Status: 200)
https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/logout.php (Status: 302)
https://challenge105.hackkaradeniz.xyz/k1j2uzn2q00b/vendors (Status: 301)

dbconnection ve searchdb anahtar kelimeleri bir SQL Injection sorusuyla karşı karşıya olduğumuzu söylüyor olabilir.

Dikkat ederseniz daha web sitesini adam akıllı incelemeden ne tür zaafiyetler arayacağımızı ve hangi payloadları kullanacağımızı tahmin edebiliyoruz.

Artık anasayfayı incelemenin vakti geldi.

SQLi Auth Bypass

/k1j2uzn2q00b/index.php dosyasında bir login form var. Az önceki tahminlerimizden yola çıkarak SQLi ile bypass etmeyi denediğimizde başarılı sonuç alıyoruz.

Bilgi toplamaya devam

Bu arada veritabanı türünü de payloadlarda yorum olarak işaretlemek maksadıyla kullandığımız # işaretinden yola çıkarak, MySQL olarak saptadık.

Bence burada üstünde durulabilecek noktalardan bir tanesi, sabit değişkeninin bypass payloadı girilen password parametresi olduğu, bağımsız değişkenlerinin username parametresine girilecek admin' and 1=1# ve admin' and 1=0# payloadları sonucunda sunucudan dönen cevabın da bağımlı değişkenler olduğu bir deney yapılmasıdır.

Bir başka deyişle:
Eğer ki bizim kontrol ettiğimiz tek değişken username bölümüne birilen payloadlar iken sözkonusu iki payload'a sunucu tarafından farklı cevap dönülüyorsa o zaman bütün veritabanına username parametresi üzerinden yapılacak bir enjeksiyonla erişim kazanmak denenebilinirdi.

Lâkin istenilen çözümün bu olduğunu düşünmediğimden ve açılan sayfayı merak ettiğimden dolayı yarışma esnasında bunu kafamın bir köşesine yazdım ve ilerlemeye devam ettim.

Açılan sayfaya serice göz attıktan sonra, kullanıcılarla alakalı sayfalar ve bir arama sayfası olduğunu görüyoruz. İlk tahminleri alalım ??

Kullanıcıların listelendiği iki sayfayı şekildeki iki kırmızı ok ile gösterdim.

Söz konusu sayfaları incelediğimizde iki tane acayip önemli şey görüyoruz.

  1. Kullanıcıya ait ID
  2. Kullanıcı ismi

Az sonra önemini anlayacağımız bu iki mâlumâtı bir kenara not aldıktan sonra, arama sayfasını inceleyelim.

Bir XSS almadan devam etmek olmaz, buradan TOKİ yolunda emin adımlarla ilerlediğimi de beyan etmek istiyorum :)

Kullanıcıların Entry ID lerine veya kullanıcı adlarına göre arama yapılabilinen basit bir arama sayfası gibi görünüyor. Test etmek için az önceki Shanu Dev isimli kullanıcıya ait Entry ID değerini girdiğimizde kullanıcıyı karşımıza getirdi.

Boolean Based Blind SQLi tespiti

Şimdi geldik zurnanın zırt dediği yere, burada SQLi var mı yok mu nasıl anlayacağız.

SQLMAP'i gerekli parametrelerle çalıştırmadığımızda SQLi olmadığını söylemekteydi o sırada doğru parametreleri girmediğimi fark etmedim ve devam edip manuel olarak da test etmek istedim.

Bildiğimiz gibi SQLi'ların türleri vardır:

  • UNION tabanlı
  • Hata tabanlı
  • Boolean tabanlı (Blind)
  • Zaman tabanlı   (Blind)
  • Out Of Band    (Blind)

Her çeşidi anlamanın değişik yolları var. Yarışma esnasında birkaç ' denemesinden sonra UNION ve Hata tabanlı enjeksiyonları eledim ve Boolean tabanlı enjeksiyon tespiti yapmaya koyuldum.

Şimdi sizi backend'te nasıl bir sorgunun çalıştığını ve bizden alınan girdinin sorgunun neresine konuşlandırıldığını tasavvur etmeye davet ediyorum.

Basitçe aşağıdaki gibi bir şey düşünebiliriz.

SELECT numara,id,kullanici_ismi, FROM kullanicilar WHERE id = '{girdi}' OR kullanici_ismi LIKE '%{girdi}%';

Dikkat edersek eğer, sorguda birden fazla yere bizden alınan girdi konuluyor. Sorgudaki ilk girdi alanından sonra gelen her şey payload'ımızın sonuna koyacağımız # ile yorum hâline geleceğinden dolayı sorguda eğer ID kontrolü daha önceyse ID'yi, kullanıcı ismi kontrolü daha önceyse de kullanıcı ismini doğru olduğunu bildiğimiz değer olarak kullanabiliriz.

Önce ID seçeneği için iki payload yazdım ve çalıştırdığımda farklı sonuçlar aldım ki bu da demek oluyor ki girdimizdeki sorgu ifadeleri başarılı bir şekilde MySQL veritabanı tarafından işleniyor.

285255862' and 1=1#
285255862' and 1=0#

Var yok oyunumun işe yaradığını gördüğümde heyecanlandım ve emin olabilmek için hemen BurpSuite'in Intruder aracını kullanarak veritabanındaki geçerli şemanın ilk tablosunun isminin ilk harfini dumpladım.

Exploitation

Bu aşamada eğer izlemediyseniz Mehmet İnce Hoca'nın Boolean Based SQLi ve exploitation yollarını anlattığı videoyu izlemenizi tavsiye ederim.

Script yazmadan önce giden HTTP requestlerinin detaylarını ve girdinin hangi parametrede gittiğini saptadım.

Ardından scripti yazmaya başladım. Mantığını programlarken geçen senenin (2021) Aralık ayında PortSwigger'ın web güvenliği akademisini çözerken Boolean tabanlı Blind SQLi'ların exploitation aşamasını otomatikleştirmek için yazdığım program, exploitation için yazdığım script üzerinde çalışırken işimi çok kolaylaştırdı.

https://github.com/f4T1H21/Blind-SQL-Injection

Veritabanındaki şemaların, tabloların ve kolonların isimlerinin sorgusunu; ve SUBSTR, LIMIT, ASCII gibi yardımcı metotları da karşı sistemde denemeden önce Docker üzerinde oluşturduğum ve kullandıktan sonra otomatik silinen yerel veritabanımda hızlıca denedim ve nihai sorguları yazdım.

İhtiyacım olduğunda hızlıca veri tabanı oluşturmak ve kullandıldıktan sonra otomatik silinmesini sağlamak için yazdığım one-liner'ı da GitHub'da bulabilirsiniz. https://github.com/f4T1H21/mysql-docker-oneliner

Vee, sonuç: parametreden enjeksiyonu başarıyla gerçekleştirip flag'i elde ettim.

Problem

Flag veritabanının en saçma kolonlarından bir tanesindeydi. O kolona rastlayana kadar tabloların hepsinin isimlerini çıkarmam gerekti.

Her ne kadar otomatik de olsa bir karakter dumplamak için ortalama 8.5 HTTP request'i gittiğinden dolayı ve ara sıra kontrol etmem gerektiğinden dolayı süreç uzayıp gitti.

Hatta bir ara bu durumdan sıkılıp yetkililere flag'in konumunu sordum. Veritabanındaki admin parolalarının yazılı olduğu kolondan 32 hanelik bir parolayı da (exploitation'da başarılı olduğumun referansı olması için) ekleyerek gönderdiğim mesaja daha detaylı bakmam gerektiği cevabını vererek konuyu kapattılar.

Neyse, en sonunda AdminRegDate isminde adminlerin sisteme kayıt tarihlerinin yazdığı kolonda buldum Flagi.

Bulduğumda o zamana kadar çektiğim veriler ise bir ctf sorusu için gereksiz fazlaydı.


Okuduğunuz için teşekkür ediyorum. Yapıcı geri bildirimlere açığım. İyi çalışmalar, hoşça kalın.

Twitter: @f4T1H21
LinkedIn: Şefik Efe
HackTheBox: f4T1H