İçindekiler

Hacktrick 2017 Tersine Mühendislik Eğitimi

Giriş

Blog yazmayı uzun süredir düşünüyordum ancak düzenli içerik çıkarma konusundaki endişelerimden dolayı başlayamamıştım. Şimdi ise bu ilk blog yazıma başlamamı sağlayan ve yazımın da konusu olan Hacktrick Siber Güvenlik Konferansı ve Tersine Mühendislik eğitiminden bahsedeceğim (organizasyon, eğitim öncesi eleme sınavı ve eğitim içeriği). Bir sonraki yazımda ise Tersine Mühendislik eğitiminin sonunda yapılan dört soruluk yarışmanın çözümlerinden bahsediyorum. Link yazının sonunda.

Eğitimde ve öncesinde bizimle paylaşılan dosyaları, ayrıca bizden kurmamız istenilen sanal makinenin linkini yazının en sonunda paylaştım.

Sınavlarımdan ve derslerimden dolayı cuma günü olan konferansın ilk gününe gidemedim ancak Mehmet İnce’nin “A 0day Story” başlıklı sunumunu YouTube’dan yapılan canlı yayın sayesinde izleme fırsatım oldu (izlemeyenlere tavsiye edilir). Eğitimler ise cumartesi ve pazar günü yapıldı. Sabahları insanlara çok uygun fiyata simit ve poğaça çeşitleri, öğlen de yine çok uygun fiyata sandviç (2TL sanırım) dağıtıldı. Tüm gün ise ücretsiz çay ve su alabiliyorduk. Tamamen öğrenci dostu bir organizasyondu. Organizasyona çok değinmeden Tersine Mühendislik eğitiminden bahsetmeye başlıyorum 🙂

Sorular

Eğitime alınmadan önce başvuranlar arasında eleme yapabilmek için Robin Dimyanoğlu (eğitmen) tarafından iki tane soru soruldu. Sorular genel olarak Google’dan araştırma yapılarak öğrenilebilecek konulardı o yüzden araştırma yeteneğini ölçmek için yapılmış güzel bir eleme sınavıydı.

Soru 1

İlk soruda bizlere “flag” isimli bir çalıştırılabilir dosya verildi ve bunun çıktısı istendi. İpucu olarak da “ELF Header” anahtar kelimesi verildi. Bu dosyayı çalıştırmayı denediğimde ise bana şu hatayı veriyor:

corrupted flag file

Daha sonra strings flag komutu ile çalıştırılabilir dosyanın içindeki karakterlere baktığımda “Burada birsey yok :)” yazısı ile karşılaştım ve ardından ipucunda olduğu gibi ELF dosyasının header değerlerine bakmaya karar verdim. “readelf -h flag” komutunu çalıştırdıktan sonra “Start of program headers” değeri dikkatimi çekti çünkü çok yüksek bir değere sahipti:

readelf header of the flag

Öncelikle file (veya readelf) komutuyla 32-bit olduğunu öğrendiğim bu çalıştırılabilir dosyanın internetten header değerlerini araştırdım ve aradığım cevabı wikipedia‘dan buldum. 32-bit olan dosyalar için “start of program headers” değeri 0x1C offset’inden (offset: uzaklık/konum) başlıyor ve alması gereken değer 52 bytes (hex: 34). Yukarıdaki resimde de gördüğümüz gibi flag dosyasının değeri ise “4026531840”, bunu hexadecimal değere çevirirsek değer: “F0000000”. Bu noktadan sonra yapılması gereken 0x1C offset’inden başlayan “F0000000” değerini “00000034” hex değeri ile değiştirmek.

hexdump program header flag file

Burada ilk dikkatimizi çeken, hex değerinin “00 00 00 f0” şeklinde yazılmış olması. Bunun sebebi ise i386 ve devamı olan işlemcilerin Little Endian standardında olması. Little Endian nedir bilmeyenler için kısa bir özet geçeceğim, ayrıntılı bilgi zaten internette Türkçe olarak onlarca, İngilizce olarak ise binlerce bulunmakta. Özetle işlemcilerin bellek üzerindeki veriye erişirken veriyi anlamlandırma biçimlerinden kaynaklanır. Little Endian işlemci, bellekteki veriye erişirken bellekteki en küçük adresi registerdaki en anlamsız (least significant) byte ile eşleştirir. Buradan da anlaşılacağı üzere bu değeri “00 00 00 34” ile değil, “34 00 00 00” şeklinde değiştireceğiz. Bunun için hexedit programını kulladım:

fixed hex flag file

Program bu açıdan çok kullanışlı, değiştirmek istediğim değerlerin üzerine gelip klavyeden değerleri tuşladım ve F2’ye (ctrl + x de kaydedip çıkmak için) basarak kaydedip çıktım. Ardından dosyayı çalıştırdığımda ise doğru çıktıya (n0p455w0rd) ulaşabildim:

flag file output

Soru 2

İkinci soruyu tam hatırlamamaktayım ancak şuna benzer birşeydi: “Bilgisayarımda birine göndereceğim bir dosya var ve internetim yavaş o yüzden dosyayı sıkıştırıp göndereceğim fakat bulunduğum ağ güvenli değil. Bu durumda dosyayı önce şifreleyip sonra mı sıkıştırmam gerekiyor? yoksa önce sıkıştırıp sonra mı şifrelemem gerekiyor?” Bu soruyu bilmek için tabii sıkıştırma ve şifreleme algoritmalarının nasıl ve neye göre çalıştığını bilmek gerekiyor. Yazı çok uzadığı için ve okunabilirlik düşeceği için bunları özet geçeceğim.

Genel sıkıştırma metodları: The Shannon-Fano Algorithm, Huffman Coding, Arithmetic Coding, Lempel–Ziv (LZ) compression, Entropy Encoding. Bunlar arasında en çok kullanılanlardan biri olan LZ77 algoritmasına değineceğim. Bu algoritmada dosya içerisindeki tekrarlanan verilerin yerini, daha önce sıkıştırılmamış veri akışında mevcut olan verilerin bir kopyasına yapılan referanslarla değiştirerek sıkıştırma yapılır.

Şifreleme algoritmalarında ise entropi diye bir kavram vardır, bu ise rastgeleliğini temsil eder. Entropi ne kadar yüksek ise şifreleme o kadar güvenlidir çünkü şifrelenmiş verilerin rastgeleliği artacağı için dosyadan anlamlı veriler çıkarmak zorlaşır. Yani şifrelenmiş dosyada tekrarlanan veriler neredeyse hiç kalmayacaktır.

Bu bilgilere göre soruyu yeniden okuyup sorumladığımızda kolaylıkla anlayacağız ki sıkıştırma algoritmaları, bir dosyadaki tekrar eden verilerden yola çıkarak sıkıştırma yapar; tekrar eden veri ne kadar çok ise sıkıştırma o kadar fazla. Şifreleme algoritmaları da verilerin rastgeleliğini arttırarak tekrar eden verileri neredeyse sıfıra kadar indirir. Bu nedenle eğer biz bir dosyayı sıkıştırmadan önce şifrelersek dosyadaki tekrar eden veri yapıları artık olmayacağı için sıkıştırma işlemi verimsiz olur ve hatta sıkıştırılan veri, şifrelenmiş veriden daha yüksek boyutta çıkar. Sorunun cevabı: dosyayı şifrelemeden önce sıkıştırıp daha sonra şifrelememiz gerekmektedir.

Sonunda iki soruluk eleme sınavının çözümünü anlatmayı bitirebildim 🙂 Eğitimde bizlere öncelikle OS kavramları ve yapılarından bahsedildi daha sonra CPU, I/O ve hafıza yönetimi anlatıldı. Tabi bunlar çok derin ve iki güne sığdırılamayacak konular ancak eğitim de zaten giriş seviye olduğu için temel seviye güzel bir anlatım oldu. Ben daha çok orada eğitmen olarak gelmiş iki değerli kişinin (Robin Dimyanoğlu ve İsmail Bozkurt) tecrübelerinden faydalanmaya çalıştım. Genel mimariler anlatıldı, özellikle debugger ve disassembler konusuna değindik. Assembly’e giriş yaptık; registers, if/else, döngüler, fonksiyon çağırma, diziler, stack, heap gibi yapılara değindik ve ardından GNU Debugger (GDB) ile uygulamalı Tersine Mühendislik örneklerine başladık.

Eğitim iki gün olmasına rağmen baya zengin içeriğe sahipti çünkü anti-debugging teknikleri, library hooking, statik/dinamik analiz ve ASLR koruması gibi konulara da değinerek birçok uygulama yaptık, hatta keygen bile yazdık. Bu kadar zengin içeriği iki güne sığdırabilmekteki en büyük neden, eğitime katılacak kişilerin eleme sınavı ile alınması, ve eğitmenlerin anlatım başarılarından kaynaklı. Neredeyse hiç takılmadan, konuları uygulamalı işleyerek tıkır tıkır ilerledik.

Bir sonraki yazımda Tersine Mühendislik eğitiminin sonunda “elimizin kirlenmesi” için yapılan dört soruluk yarışmanın çözümlerinden bahsedeceğim, takipte kalın 🙂

Paylaşılanlar