angstromCTF 2019 Rev Bölüm 1: Beğeniyorum

Bu yıl angstrom’da tersine dönen birkaç zorluğu çözmeyi başardım, yani Rev’e Giriş (çok basit olduğu için bunun üzerine yazmıyorum), Beğeniyorum, Bir Isırık ve Yüksek Kaliteli Kontroller. Bunları yazmak için oldukça geç ama bunlardan çok keyif aldım, bu yüzden onları yazıyorum! Keyfini çıkarın!

Bunun bunu yapmanın en verimli yolu olmadığını unutmayın ve sadece sorunu çözmek için attığım adımları tekrar izliyorum. Ayrıca bunun için bir Linux Manjaro dağıtımı kullandığımı da unutmayın (CyberStart Game VM tam olarak: D)

Beğendim

First , dosyanın yürütüldüğünde gerçekte ne yaptığını görelim. ./<program_name> kullanarak şunu görürüz:

Sonuç olarak, programın kodun bölümlerini çalıştırmak için karşılaştırma koşullarını kullanan “doğrulama” tipi bir program olduğunu görebiliyoruz. Daha sonra, kullanıcı girdisini karşılaştırdığı dizenin programa sabit kodlanmış olup olmadığını görmek için strings komutunu kullanabiliriz:

Tamam .. bu yüzden, sabit kodlanmış dizeyi, “okrrrrrrr” ve daha fazlasını elde ediyoruz gibi görünüyor: iki tamsayı girmemizi gerektirecek başka bir aşama var. Bu tam sayılar, “okrrrrrrr” ile birlikte Flag dizgesine biçimlendirilecek ve bu olacak. Ancak ne yazık ki, bu iki tam sayı programa sabit kodlanmış değil… bu yüzden biraz tersine dönmenin zamanı geldi!

Bundan önce, işe yarayıp yaramadığını görmek için “okrrrrrrr” yi gerçekten test edelim:

Her şey yolunda.

Artık favori sökücümüzü açabiliriz. Şahsen ben hem gdb hem de radare2 kullanıyorum (bu zorluklar için gdb kullanacağım) ama elbette rahat bulduğunuz şeyleri kullanabilirsiniz.

Esas olarak bir kesme noktası oluşturarak, programda ilerleyebilir ve programın tamsayı aşamasında neler elde edebileceğimizi görebiliriz:



Esasen burada olan şey, programın iki numaramı alıp kendi benzersiz hafıza adreslerinde saklamasıdır. Daha sonra sırasıyla edx ve eax kayıtlarına taşınırlar. Bu numaralar daha sonra add eax, edx satırı ile toplanır (veya daha spesifik olarak edx eax üzerine eklenir). Bu toplam daha sonra onaltılık olarak 0x88 ile karşılaştırılır, bu da denary olarak 136’ya dönüştürülür. Eşit değillerse, ana + 241 ‘e atlar ve bu da birkaç işe yaramaz dizeyi yazdırır ve programdan çıkar.

Diğer bir deyişle: İlerlemek için, 136’yı verecek şekilde toplanan 2 sayı bulmamız gerekiyor. Onu 2’ye böldüm, bu da 68’i veriyor. Yani programı yeniden çalıştırmak:

İşe yaramadı! Açıkçası o zaman kaçırdığımız başka bir şey olmalı. Belki de program ana + 241 ‘e atlamamaya karar verdiğinde daha fazla kod vardır? Öğrenelim:


Evet, beklendiği gibi yerine getirmemiz gereken başka bir koşul var. Aslında, yeni kod satırları öncekilerle aynıdır ancak sayıları birbirine eklemek yerine imul ile çarpılır . Bu ürün daha sonra onaltılık birimde 3783 olan 0xec7 ile karşılaştırılır. Ve tabii ki, eşit değillerse, bir kez daha main + 241 ‘e götürülür ve burada programdan atılırız.

Şimdi, 136’yı vermek için toplanan ve 3783’ü vermek için çarpan iki sayıya ihtiyacımız olduğunu biliyoruz. Bunu elde edene kadar farklı sayılar denemeye devam edebilirsiniz ama ben şahsen biraz matematik kullandım ve en hızlısı olduğu için bazı denklemler kurdum:

a+b=136 veab=3783.

Yeniden düzenleme: a=3783/b

Dolayısıyla: 3783 / b + b = 136

Ardından her iki tarafı da b ile çarpabilir ve ikinci dereceden bir denklem elde edebilirsiniz:

b?2-136b+3783=0

Ve b ‘yi elde etmek için çözün, 97 veya 39 olabilir. Bu, a ‘ nın 97 veya 39 da olabileceği anlamına gelir. Yani şimdi tam sayılarımıza sahip olmalıyız !

Öyleyse onu programa bir kez daha eklemeyi deneyelim:

Ve bayrağımız var!

Bu, yeni başlayanlar için hoş bir geri dönüş mücadelesidir, ancak dikkat etmezseniz yine de sizi yakalayabilir!