Archive for Kriptografi

Zararlı Kodun Analizi – Analyzing Malicious Code

// Ağustos 8th, 2008 // No Comments » // Kriptografi

Doküman içerisinde aşağıda verilen yabancı kelimeler karşılıkları ile anılacaktır.
Malicious Code: Zararlı Kod
Virus: Virüs
Trojan Horse: Truva Atı
Worm: Solucan
Packer: Paketleyici
Unpacker: Çözümleyici
Breakpoint: Kesme Noktası
Debug: Hata Ayıklama
Packet Disassembler: Paket Ayırıcı
Malware: Zararlı Yazılım
Packer: Paketleyici
Unpacker: Çözümleyici
Registry: Kayıt Defteri

Bilgisayar ağları ve internet uzun zamandır zararlı kodlar ve art niyetli etkilerinden mustarip. Bu doküman kontrollü bir ortamda Zararlı Kodun Analizi hakkında basit ve pratik bilgi edinilmesi amacıyla hazırlanmıştır.

Zararlı Kod normal bir bilgisayarda çeşitli zararlı aktiviteleri gerçekleştirmek amacıyla yazılan kod olarak tanımlanabilir. Son-kullanıcı verisi veya kişisel bilgi çalmak, bir ağdan diğer makinalara zararlı kod bulaştırmak veya etkilenmiş makinalara spam göndermek örnek olarak gösterilebilir.

Virüsler (Virus), Solucanlar (Worm), Truva Atları (Trojan Horse) ve Botlarıda kapsayan fakat bunlarla sınırlı olmayan bir çok Zararlı Kod kategorisi vardır.

Bu kategorilerden her biri tasarlandıkları amaca göre farklı karakteristik özelliklere sahiplerdir. Amacımız bu tip zararlı kodların analizini en etkili şekilde yapabileceğimiz çeşitli tekniklerden bahsetmektir.

Zararlı Kod Türleri

Aşağıda bazı Zararlı Kod türlerinin basit tanımları verilmiştir:

Virüs:Virüsler kullanıcısının izni olmadan bilgisayarın çalışma yolunu değiştirmek için yazılan basit programlardır. Bir Virüs birisi etkilenmiş dosyayı çalıştırmadığı sürece ağdaki diğer bilgisayarları etkileyemez.

Truva Atı: Bilgisayar yazılım dilinde bir Truva Atı, Virüslerden farklı olarak başka bir iş yapıyor gibi göründüğü halde içerisinde Zararlı Kod bulunduran veya sonradan yükleyen bir programdır (bu Payload veya Trojan olarak da adlandırılır).

Solucan: Bir bilgisayar Solucanı kendisini kopyalayan bir programdır. Kopyalarını diğer kurbanlara (ağdaki diğer bilgisayarlar) bulaştırmak için ağı kullanır ve bunu yapabilmesi için kullanıcı etkisine/davetine gereksinimi yoktur.

Bot: Bir Bot, kontrolöründen direktifler alarak bu direktiflere göre çalışan bir Zararlı Programdır. Yayılmak için Uzak Sistem erişimi, Sosyal Mügendislik e-postaları gönderme gibi çeşitli teknikler kullanırlar ve akabinde Botnet olarak tabir edilen bir Bot Ağı kurarlar. Kullanıma hazır (ele geçirilmiş) bilgisayarlardan oluşan bu şebeke Distributed Denial of Service (DDOS) saldırılarında, zararlı yazılım (malware) yüklemesinde veya diğer kötü aktiviteler için kullanılabilirler.

Zayıf Noktalar

Solucan ve Bot gibi zararlı kodlar çeşitli bilgisayar yazılımlarındaki zayıf noktaları kullanırlar. Bu zayıf noktaların sömürülmesi şifre ve kredi kartı bilgisi gibi önemli verilerin çalınmasıyla veya şantaj ve tehditle para gaspı ile sonuçlanabilir. Birçok botnet yöneticisi etkilenmiş Zombi Makinalardan oluşan ağlarını para karşılığında başkalarının kullanımına sunar.

Bu tip yazılımlar tüm bilgisayar kullanıcıları için çok ciddi güvenlik sorunlarına neden olmaktadır. Birçok organizasyon bu tip yazılımların şirket ağlarında yayılması sonucu milyonlarca dolar kaybetmişlerdir. Örneğin, bir zararlı kod Amerikanın kuzeyinde bir üretim şirketinin tüm programlarını yok ederek şirkete milyonlarca dolar zarar vermekle birlikte şirketin sektördeki pozisyonunu kaybetmesine ve akabinde 80 işçisini uzaklaştırmasına sebep olmuştur.

Neden Analiz?

Zararlı Kodların oluşturulma nedenlerinde olduğu gibi Solucan, Virüs ve diğer zararlı kodların analizi için de sayısız sebep vardır. Zararlı Kod Analizinin temel nedeni bu tip programlar için ulaşılabilir kaynağın olmayışıdır. Bu programları öğrenmenin tek yolu onları analiz etmek ve çalışma prensiplerini anlamaktır. Bir başka nedense birçok araştırmacının yaptığı gibi bir programın gizli olan çalışma yöntemini hata ayıklama programı (debugger) ve disassembler ile inceleyerek açığa çıkartmaktır.

Bu tip kodları analiz etmenin iki tekniği vardır:

- Statik (dead) analiz
- Dinamik (live) analiz

Bu yöntemlerin her ikisini de ilerleyen bölümlerde inceleyeceğiz. Bu analizlerde kullanmak üzere NetSky-P Solucanını seçtik. Bahsi geçen solucan SOPHOS tarafından Mayıs 2007 itibariyle ilk on solucan arasında gösterilmiştir.

Statik (Dead) Analiz

Statik analiz herhangi bir zararlı binary dosyayı incelemek için en güvenli yöntemdir. Bu inceleme tekniği kullandığımızda zararlı programı hiç çalıştırmayacak fakat binary dosyanın içeriğini güvenli bir çekilde tahkik edebilmek için Win32Dasm veya IDA Pro gibi çeşitli ayırıcılar (disassemblers) kullanacağız.

Paketleyiciler ve Çözümleyiciler

MS Windows platformunda PE adıyla bilinen çalıştırılabilir bir genel dosya formatı vardır. MS Windows sisteminde çalıştırılabilir her bir dosya PE dosya formatındadır. Genellikle Zararlı Kod yazılımcıları yazdıkları kodların basit tekniklerle analiz edilemesini zorlaştırmak için çeşitli teknikler kullanırlar.

Zararlı Kod yazarlarının başvurduğu genel bir yöntem Executable Packers olarak bilinen, uygulama boyutunu azaltma ve farklı aldatıcı algoritmalarla içeriği değiştirme yöntemidir. Bu senaryoda normal normal ayrıştırma etkili olmayacaktır. En genel kullanılan dosya paketleyiciler UPX ve ASPack gibi yardımcı uygulamalardır.

Hangi dosya paketleyicinin kullanıldığını tespit etmek için File insPector XL adındaki aracı kullanabiliriz. Adından da anlaşılacağı üzre program genel paketleyici imzalarını kontrol ederek kolayca hangi paketleyicinin kullanıldığını tespit edecek. Sonrasında analiz aşaması için dosyayı çözümlememiz gerekecek, bu konuda da güvenli bir şekilde dosyaları çözümleyebilmek için kullanıma sunulmuş çeşitli araçlar mevcut. PEID ve ProcDump bu araçlardan ikisi.

Bu araçları kullanarak bir çok genel dosya paketlemesini çözümleyebiliriz.

Bazen Zararlı Kod yazılımcıları uygulama içerisindeki imzayı manipüle ederek çözümlemeyi zorlaştırırlar, bu durumda yukarıda bahsedilen araçlarla doğru paketleyici tespit edilemez. Bu problemin üstesinden gelmek için ProcDump gibi araçlar sezgisel analiz özelliğine sahiptir. Bazı durumlarda ise binary dosyayı manuel olarak çözümlememiz gerekir. Manuel çözümleme başlı başına bir konu olduğundan bu dokümanda bu tekniği incelemeyeceğiz.

Öncelikli olarak incelediğimiz dosyanın paketlenmiş olup olmadığına karar vereceğiz. Bunun için file insPEctor XL aracını kullanacağız. Şekil 1.de gördüğünüz gibi dosyanın Ultimate Packer for Executables (UPX) kullanılarak paketlendiğini tespit ediyoruz.


Şekil 1. File İnspector paketleyicinin UPX olduğunu gösteriyor

UPX Sourceforge.net’ten ücretsiz olarak indirilebilecek bir açık kaynak aracıdır. İndirip kurulumunu yaptıktan sonra, Zararlı Yazılımımızın adını değişken olarak tanımlamak suretiyle komut satırından çalıştırarak Şekil 2.de gördüğünüz çıktıyı elde ederiz.


Şekil 2. UPX kullanılarak paketin çözümlenmesi

Ayrıştırma ve String Veri Tespiti

Bir Zararlı Uygulama dosyası gelişimi sırasında programcının iyi kodladığı birçok string içerebilir. Bu stringler hata mesajı veya Zararlı Kodun işlevleştirilmesi ile ilgili olabilir. Örneğin, şayet bir uygulama dosyası e-posta gönderiyorsa bu durumda “RE: İstediğin Eklenti”, “++Virüs Bulunamadı++” ve benzeri farklı başlık satırları için çeşitli stringlere sahip olması muhtemeldir. Dolayısıyla dosya çözümleme sonrasında genel stringleri bulmak için Win32Dasm veya IDA Pro gibi araçlar kullanarak ayrıştırma işlemi yapmamız gerekir. Bu analizler dosyanın işlevleri ile ilgili genel bir fikir sahibi olmamızı sağlayacak. Analizde tespit edebileceğimiz birçok string mevcut. Bu stringler Solucanın gönderdiği e-posta gövdeleri veya başlıkları, dosya eklenti isimleri ve benzeri şeyler olabilir.

Uygulamayı başarıyla çözümlediğimize göre artık ayrıştırma ve sonraki inceleme adımlarına geçebiliriz. Bu uygulamanın statik analizini IDA Pro ayrıştırıcısıyla gerçekleştireceğiz. Ayrıştırma içerisinde ilk önce bakacağımız şey stringler. Bir uygulama içerisindeki stringler (e-posta başlıkları, mesajlar, kayıt defteri girdileri, dosya uzantıları ve dosya isimleri gibi) bize çeşitli bilgiler sağlayabilir. Şekil 3.de NetSky-P Solucanının etkilenmiş

makinadan gönderdiği e-postaların başlıkları görülebilir.


Şekil 3. E-Posta konu başlıkları


Şekil 4. Gönderilen mesajların içeriğindeki çeşitli stringler


Şekil 5. NetSky-P Solucanının gönderdiği eklentili e-postalarda kullandığı uygulama uzantıları


Şekil 6. Etkilenmiş sistemde kullandığı dosya isimleri


Şekil 7. Solucan tarafından kullanılan bazı kayıt defteri girdileri

Şu ana dek topladığımız bilgiler doğrultusunda NetSky-P Solucanının çeşitli başlıklar, dosya isimleri ve uzantılarıyla e-postalar gönderdiğini söyleyebiliriz. Buna ek olarak kayıt defterinde çeşitli girdiler ekleyerek etkilenmiş makinada her açılışta çalışmasını sağladığınıda biliyoruz.

Dinamik (Live) Analiz

Dinamik (Live) Analizde kontrollü bir ortamda uygulamayı çalıştırarak kodun genel işlevselliği ve iç çalışma prensiplerini kontrol etmemiz gerekiyor. Bu bize Statik Analiz işleminde elde ettiğimiz olası yanlış bilgileri elimine etmemizde yardımcı olacak. Bazı Zararlı Program yazarları yazılımlarının doğru bir şekilde tahkik edilmesini engellek veya kısıtlanmış bir sanal makina içerisinde çalıştırıldığında uygulama dizinini değiştirmek için kasıtlı olarak çeşitli string ve fonksiyonlar eklerler; bu tip girişimler Dinamik Analiz sırasında tespit edilebilir.

Bu sebeple MS Windows XP Prefessional (SP2) yüklü iki test sistemi kurmamız gerekiyor. İlk makinede Ollydbg kurarak NetSky-P Solucanının hata ayıklama (debugging) işlemini gerçekleştirecek, diğer sistemde ise ağa bağlanarak Solucanın çeşitli aktivitelerini gerçek zamanlı olarak görüntüleyebileceğiz. Daha sonra her iki bilgisayarda Wireshark’ı, etkilenmiş sistemde ise RegMon ve FileMon’u çalıştıracağız.

Zararlı yazılımla uğraşırken onu karantinada tutmak için çalışma ortamında bazı önlemlerin alınması önemlidir. Çalışmamızda bu amaca uygun olarak diğer ağlara veya internete erişimi olmayan bir ağ seçiyoruz. Birçok kişi bu tip deneyler için uygulamayı bir sanal makina ile sınırlandıran popüler VMWare porgramını kullanıyor. Sonuç olarak deneyin hangi ortamda yapılacağı kişisel bir tercih lakin biz güvenli olanını seçmenizi tavsiye ediyoruz.

Ortam hazırlıkları tamamlandıktan sonra Ollydbg hata ayıklamayı başlatarak NetSky.exe dosyasını yükledik. Bu işlem sonucunda Şekil 8.de gösterilen çeşitli stringlere kesme noktaları (breakpoint) ekleyebiliriz. System\\Current Control Set\\Services\\WksPatch’e kesme noktası ekleyerek OllyDebugger’ı çalıştırıyoruz.

İşlem kesme noktası üzerinde duruyor. Stringler üzerinde dikkatli bir inceleme sonucu daha önce Statik Analiz aşamasında elde ettiğimiz bulguları doğruluyoruz. Şimdi başlangıçta eklediğimiz kesme noktalarını taşıyacak ve GetInternetConnectionState(), RegCreateKeyEx() ve benzeri çeşitli Windows API’lerini izlemek için Animate Over ve diğer çeşitli hata ayıklama özelliklerini (step in, step out gibi) kullanacağız. Bu analizden Solucanın e-posta göndermek için threadlar (iş parçacığı) oluşturduğunu tespit edebiliriz.


Şekil 8. Ollydebugger’da kesme noktaları

Kayıt Defteri Anahtarları

Bir Zararlı kodun kendisini yayması için bir şekilde başlatılmaya ihtiyacı vardır. Bu işlem, Zararlı uygulamanın çalıştırılması, zararlı bir web bağlantısına tıklanması veya Windows kayıt defterinde erişilebilen bir otomatik çalışma ayarı ile olabilir. Modern Zararlı Yazılımlar birçok Sosyal Mühendislik teknikleri

uygularlar. Kullanıcı Zararlı uygulamayı birkez çalıştırdıktan sonra bilgisayar her açıldığında uygulama, kayıt defterine eklediği girdiler sayesinde kendiliğinden çalışır.

Bu tip bir davranışı tespit edebilmek için Sysinternal tarafından kodlanan RegMon programını kullanacağız. Böylece bir program tarafından kullanılan tüm Kayıt Defteri girdilerini görüntülemiş olacağız.

NetSky-P Solucanını incelemek için çalışmasını sağlayıp RegMon kayıtlarından Kayıt Defteri erişimlerini kontrol ediyoruz. Gözlemlediğimiz üzre daha önce bahsettiğimiz çeşitli anahtarlara erişim sağlamaya çalışıyor. Şekil 9.da görüleceği üzre Solucanın HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run anahtarına yeni girdi eklemesi dikkatimizi çekiyor. Windows klasörünü incelediğimizde AV-Bgle.exe ve Base64.tmp adında iki dosya buluyoruz.


Şekil 9. Solucan tarafından oluşturulmuş bir kayıt defteri girdisi

FileMon

Zararlı Kod farklı yerlerde farklı isimler kullanarak kendisini onarabilir veya kopyalayabilir. Aynı zamanda uzak sunucudan backdoor ve benzeri başka dosyalar indirerek bunları etkilenmiş sisteme yerleştirebilir. Bu durumu gözlemleyebilmek için FileMon adındaki aracı kullanacağız.

Analize devam etmek için etkilenmiş test sistemimizi yeniden başlatarak RegMon, FileMon ve Wireshark programlarını tekrar çalıştırıyoruz. FileMon kayıtlarını incelediğimizde bir nokta dikkatimizi çekiyor; sürekli olarak Base64.tmp adında bir dosyaya erişim sağlanıyor. Adından da anlaşılacağı gibi, bu dosyanın Base64 algoritmasında kodlandığı tahmininde bulunabiliriz. Bu durumda zararlı dosyanın NetSky-P olup olmadığını tespit edebilmemiz için base64 dekoderi kullanmamız gerekiyor.


Şekil 10. Base64.tmp FileMon

Şekil 11.de base64 formatında kodlanan dosyanın dekode edilmiş hali görünüyor. İçeriğe bakıldığında hemen göze çarpan bunun bir uygulama dosyası olduğu.

İçerikte Windows platformundaki uygulama dosyalarında satandart bir başlık (header) olan MZ başlığı mevcut.


Şekil 11. Dekode edilmiş dosya

Paket Görüntüleme ve Analiz

Günümüzde bir çok zararlı yazılım ağ üzerindeki diğer makinalara bulaşmaya veya çeşitli amaçları gerçekleştirebilmek için etkilediği sistemlerin botnetlerin bir parçası olmasını sağlamaya çalışıyor. Ayrıca etkiledikleri sistemlerden hesap detayları, kredi kartı bilgileri, şifreler, sörf detayları vb. bir çok bilgi göndermeyi amaçlarlar. Bir de bulaştıkları sistemleri İnternet üzerinde DDoS saldırılarında kullanırlar.

Bu durumda etkilenmiş sistemin ağ trafiğini görüntüleyebilen Wireshark veya benzeri bir Paket Yoklayıcıya (Packet Sniffer) ihtiyacımız var. Bu analizin temel nedeni şayet bu bir botnet koduysa kontrol yönergelerini elde etmek, hangi sunuculardan ne tür dosyalar indirdiği, ne tarz spam gönderdiği gibi çeşitli detayları öğrenmektir.

Sonraki aşamada dekode ettiğimiz dosyayı decoded.exe olarak kayıt ediyoruz ve tahkikat için IDA Pro ile açıyoruz. Analiz sonucu AVBgle.exe dosyasının etkilenmiş sistemin Temporary Internet Files dizinindeki index.dat dosyasını taradığını tespit ediyoruz. Bu bizim açımızdan ilginç bir bulgu, çüknü sonrasında Solucanın dizinde bulduğu e-posta adreslerine düzenli olarak e-postalar gönderdiğini gözlemliyoruz. Bu işlem Şekil 12.de ki Wireshark paket yığınında görünebilir.


Şekil 12. Wireshark e-posta görüntüsü

Bir başka analiz Şekil 13.te görünmektedir.


Şekil 13. DNS sorguları

Bu safhada Solucanın paket analizini yapmaya karar veriyoruz. Gözlemlediğimize göre, Solucan ilk önce Yahoo!, AOL ve Hotmail gibi harici sunucular için çeşitli DNS sorguları gerçekleştiriyor.

Trafiği ayarladıktan sonra daha önce bahsettiğimiz gibi farklı başlık ve dosya isimleri ile e-postalar gönderiyor.


Şekil 14. SMTP verisi

Klonlanma Algoritmasını Çözmek:

Zararlı yazılımın zararlı aktivitelerini gerçekleştirmek için bir ana dosyanın kontrolünde birlikte çalışabilen, aynı kodların (kendi kodlarının) klonlanmasına ihtiyacı vardır. Bu sebeple sürekli olarak dahili ağ ve internet üzerinden başka sistemlere bulaşmaya çalışırlar. Bu amaca ulaşmak için çeşitli tekniklere başvururlar. Bunlardan üç tanesi aşağıda belirtilmiştir:

• Zararlı kodun eklentilendiği bir e-posta göndermek.
• Bilgisayar programlarının bilinen zayıf noktaları veya Zero-day açıklarından yararlanarak sisteme bulaşmak.
• İşletim Sisteminin kendi açığından faydalanarak bulaşmak.

Klonlanma algoritmasını kesin olarak çözebilmemiz için sıkı kontrollü bir ortamda kodu çalıştırmalı ve bir hata ayıklama programı ile incelemeliyiz. Bu tip analizler için Ollydbg aracını kullanıyoruz. Bazı durumlarda yalnızca hata ayıklama programı kullanılarak klonlanma algoritmasını çözmek mümkün olmayabilir.

Bu durumda paket görüntüleme gibi farklı tekniklerden oluşan bir kombinasyon denememiz gerekir, böylelikle zararlı yazılımın bilinen/bilinmeyen açık veya açıklardan yararlanıp yararlanmadığını tespit edebiliriz.

Daha önceki analizlerimiz sonucunda vardığımız kesin bir yargı, NetSky-P Solucanının zararlı kodun eklentilendiği çoklu e-postalar göndererek (mass mailing) kullanıcının bu eklentileri açmasını beklemesidir. Bu solucanlar, gönderdiği e-postaların içeriğinde “Virüs Bulunamadı!” tarzında yazılar bulundurmak gibi acemi kullanıcıların aldanmasını sağlayacak çeşitli sosyal mühendislik teknikleri uygularlar.
Şayet kullanıcı bunun bir aldatmaca olduğunun farkına varamaz ve eklentiyi açarsa sistemine zararlı kodun bulaşması olasıdır.

Sonuç

Zararlı yazılımlar bilgisayar kullanıcıları için her zaman sorun olmuştur. Internetin hızla geliştiği modern dünyada zararlı yazılımlar, web sitesi trafiği oluşturmak, DDoS saldırıları, bilgi hırsızlığı, kişisel bilgilerin pazarlanması ve benzeri amaçlar için yaygın bir şekilde kullanılıyor. Genellikle kodun hızlı bir şekilde yayılmasını sağlamak amacıyla 0day açıkları gibi çeşitli teknikler kullanırlar.

Dokümanda bahsettiğimiz yöntemlerle zararlı kodun iç çalışma prensipleri analiz edilebilir. Fakat bu yenek ve sezgiyi kazanmak zaman, sabır ve kararlılık gerektirir. Bu dokümanda elbette tüm analiz yöntemlerini anlatmadık. Amacımız modern Zararlı yazılımların analiz edilmesi için hangi araç ve tekniklerin kullanıldığı hakkında genel anlamda bilgi sahibi olmanızdı.

Bu dokümanda kullanılan programlar:

• VMWare (Virtualization Software) http://www.vmware.com
• IDA Pro/Freeware (Dissembler) http://www.datarescue.com/
• Ollydbg(Popular Ring 3 Debugger) http://www.ollydbg.de/download.htm
• UPX(Ultimate Packer for Executables) http://upx.sourceforge.net/
• ImpREC(Import Reconstruction for PE files) http://securityxploded.com/download.php#imprec
• Windows Sysinternals(FileMon,RegMon)

http://www.microsoft.com/technet/sysinternals/default.mspx

Zararlı Yazılımlarla İlgili Bağlantılar:

www.offensivecomputing.net – Çeşitli zararlı yazılım ve analizleri hakkında bilgi edinebilirsiniz.
www.viruslist.com – Virüs veritabanı, Virüsler hakkında bilgi
http://vx.netlux.org/ – Virüs örnekleri, Virüs Kaynakları
http://hexblog.com/ – IDA Pro güncesi

Kaynak: hakin9 6/07 – Hardik Shah & Anthony L. Williams

Orjinal Doküman:

Tersine Mühendislik – Anti-Cracking Teknikleri

// Ağustos 8th, 2008 // No Comments » // Kriptografi

Bu dokümanda aşağıdaki yabancı kelimeler karşılıkları ile anılacaktır:

– Reverse Engineering: Tersine Mühendislik
- Packer: Paketleyici
- Disassemblers: Ayırıcı
- Debugging: Hata Ayıklama
- Breakpoint: Kesme Noktası

Giriş

Bu doküman bir tersine mühendisin amacına ulaşması için takip edebileceği birçok yöntemin anlaşılması için hazırlanmıştır. Ek olarak, seri numarası ve yetki prosedürleri gibi hassas bilgilerinizin kopyalanmasına karşı yazılımınızı nasıl koruyabileceğinize dair bir dizi tavsiyeler içerir. Bu doküman herhangi birinin ideallerini değiştirmesi için değil, tersine mühendisliğin daha güvenli bir dünya oluşturabileceğine inanan insanlar için yazılmıştır.

Yapılacaklar

- PE paketleyiciler ve kriptoloji araçları
- Online kontroller
- Zararlı Yazılım analizi
- x64 tersine mühendisliği
- Zayıf nokta tespiti ve exploit haline getirme

Tersine Mühendislik Araçları

İnternet üzerinde bir çok tersine mühendislik araçları mevcut, bunların bir kısmı bedava olmakla birlikte bir kısmı da ücret karşılığında sunulmakta. Çok kullanılan bazı Ayırıcı (disassembling) ve Hata Ayıklama (Debuggig) aracı aşağıda sunulmuştur:

- OllyDBG http://www.ollydbg.de
- IDA Pro Disassembler and Debugger http://www.hex-rays.com
- W32Dasm [http://www.google.com] (Eski fakat hayrete düşürecek bazı özellikleri var)
- SoftICE (Nisan 2006’dan beri desteklenmiyor)
- WinDbg http://www.microsoft.com/whdc/devtools/debugging/default.mspx

Ek olarak aşağıda isimleri ve kısa açıklaması verilen bazı programlarda kullanılmakta:

- PROTECTiON iD http://pid.gamecopyworld.com
Windows sistem uygulamalarını bilinen paketleyici/şifreleyici imzalarına göre tarayabilir ve programın derleyicisini tespit edebilir.

- Import REConstructor [http://www.google.com/]
Uygulamaların hasarlı alınan tablolarını onarmada kullanılır.

- System Internals http://technet.microsoft.com/en-us/sysinternals/default.aspx
FileMon, RegMon gibi program davranışlarını görüntüleyebilen programlar. Alternatif olarak bunu bir sandbox içerisinde uygulamak programın tüm aktivite bilgilerinin elde edilmesini sağlar.

Tersine Mühendislik Yöntemleri

Bir tersine mühendisin kullandığı yöntemleri incelemeye başlıyoruz. Bu bölümde kullanılan ayırıcı OllyDBG’nin editlenmiş bir sürümü, orjinal sürümde aynı işlevi başarıyla gerçekleştirebilir.

Örnek Yazılım
Program Adı: Example.v1.0.exe (Serial Check)
Md5sum: 4c78179f07c33e0f9ec8f2b0509bd069
Derleyici: Borland Delphi

Program Analizi

Öncelikle, hangi yöntemi kullanacağımıza karar vermek ve nasıl çalıştığını daha iyi anlayabilmek için programı analiz etmemiz gerekiyor.

Gördüğünüz gibi basit bir program formu mevcut. Ana fonksiyonun bir kullanıcı adı ve seri numarası kontrolü olduğu aşikar. İlk adımımız metin kutusu içerisine rastgele bir veri girerek “Check” tuşuna basmak ve programın vereceği yanıtı gözlemlemek.

Sonucun bize verdiği ipucu: seri numarası kontrolünden evvel bakmamız gereken, girilen verinin programcının koyduğu sınırlar dahilinde olup olmadığını kontrol eden bir fonksiyon.

Sırada uygulamanın çalışma yöntemine ilişkin daha fazla bilgi edinmemizi sağlayacak olan Ayrıştırma ve Hata Ayıklama (Disassembling & Debugging Stage) aşaması var. Bu aşamada bir tersine mühendisin hangi yöntemleri kullanabileceğini anlatacak ve yazılımınızı güçlendirecek bazı öneriler vereceğiz.

Yöntem 1 (String Referansı)

1. Adım:

Sağ Tıklama > Search for > All referenced text strings

2. Adım:

Gördüğünüz gibi, başlangıçta karşılaştığımız mesaj metni diyalog kutusunda görüntüleniyor. İncelemek için metnin üzerine çift tıklıyoruz.

3. Adım:

Program seri numarası zorluk derecesi yüksek bir şekilde kodlanmış olsa dahi, biraz tecrübeli bir tersine mühendis fonksiyonun çağırıldığı yeri tespit edebilir ve program akışını değiştirebilir.

4. Adım:

Şimdi, bu fonksiyonun başlangıcına bir etiket tanımlıyoruz.
Sağ tıklama > Label


Etiket: “Long/Short Error” (Uzun/Kısa Hatası)

5. Adım:

Aşağıda gördüğünüz gibi bu fonksiyon bir birinden bağımsız farklı üç adres tarafından çağrılıyor.

6. Adım:

İlk çağrıya geri izleme yapıyoruz (004571B7)
Sağ tıklama > Go to CALL from 004571B7

Ve başarıyla seri numarası kontrolü algoritmasına ulaşmış oluyoruz.

Öneriler (Yöntem 1)

String Referans yöntemi ile hassas program fonksiyonlarına ulaşılmasını engellemek için bir programcının takip edebileceği adımlar aşağıda sıralanmıştır:

- Stringleri global değişkenler veya daha iyisi arraylar içerisinde tanımlayın ve ihtiyaç olduğunda çağrılmalarını sağlayın.

Sahte Kod Örneği:
array[] myMsges = {’Girdiğiniz seri numarası çok kısa veya çok uzun’,
’Girdiğiniz seri numarası geçersiz’,
’Kayıt olduğunuz için teşekkür ederiz.’}

function registrationCheck():
if(invalid_length) then
sendMessage(myMsges[0])

if(invalid_serial) then
sendMessage(myMsges[1])

if(valid_serial) then
sendMessage(myMsges[2])

Ek olarak, programcı array içerisindeki stringleri ihtiyaç olduğunda çözülmesini sağlayacak şekilde şifreleyebilir (çok kapsamlı bir şifrelemeye gerek yok, basit bir algoritma yeterli olacaktır).

//kodun şifrelenmiş halinin şöyle olacağını var sayalım: ‘dkg$2 kF2 gkfoaplk’
string thank_you = ‘Kayıt olduğunuz için teşekkür ederiz’
for(each letter in thank_you) do
add_5_to_ascii_value(letter)
print thank_you
//program serial kontrolü
If(valid_serial) then
sendMessage(decrypt(‘dkg$2 kF2 gkfoaplk’))

- Stringleri bir dosya veya kayıt defrterinde depolayın.

Yöntem 2 (windows API üzerinde kesme noktaları)

Bu yöntemde MessageBoxA API üzerinde bir kesme noktası kullanacağız. Bazı programlar MessageBoxW, MessageBoxExA veya MessageBoxExW kullanabilir.

1. Adım:

(Ollydbg komut satırını kullanarak)
“bp MessageBoxA” yazın ve Enter’a basın

(Ollydbg penceresinde)
Alt+E basarak “Executable Modules” list (“Çalıştırılabilir Modüller” Listesi)’ne geçin > modülü seçtikten sonra Ctrl+N basın > MessageBoxA bulun > Sağ tıklayın > “Toggle breakpoint on import” seçin

2. Adım:

Programı çalıştırın > Rastgele bir veri girin > Check’e tıklayın
User32, MessageBoxA API de işlem kesildi

3. Adım:

Return’e kadar Ctrl+F9 veya F8 ile programı yürütün

4. Adım:

Fonksiyondan çıkın (F8)

Gördüğünüz gibi Yöntem 1/3.adımla aynı yerde işlemimizi sonlandırdık.

Öneriler (Yöntem 2)

Bir programcı API’ler üzerinde kesme noktaları eklenerek program fonksiyonlarına ulaşılmasını engellemek için API kullanımlarını sınırlandırmalıdır. Programlarınızı minimum API kullanımı ile kodlamak API’lerin yerine kendi oluşturduğunuz mesaj kutularını kullanabilirsiniz.

Yöntem 3 (Stack Tracing)

Tersine mühendisin kullanabileceği bir başka ilginç yöntemde “stack tracing”dir.
CPU tarafından “CALL <procedure>” (çağırma) komutunu uygulandığında, yeni komuta kadar byteları toplanarak Instruction Pointer (EIP) değeri ile stack içine aktarılır. İşlem bitip “RETN” komutuna ulaşıldığında işlemci değeri stack’tan çıkartarak önceki fonksiyona döner.

“CALL 0xF” çalıştığında, “offset 3″teki değer stack içerisine aktarılır

“RETN” çalıştığında “offset 3″ değeri stack’tan çıkartılarak EIP’a yerleştirilir.

1. Adım:

Programı çalıştırın > Rastgele bir veri girin > Check’e tıklayın > Programı durdurun

2. Adım:

“Call stack” penceresini açın

Birbiri tarafından çağırılan bir sürü fonksiyon mevcut. Esasında kullanabileceğimiz program kayıt yordamı MessageBoxExA, fakat öncelikle bu fonksiyonun nereden çağırdığını görmemiz gerekli.

3. Adım:

Sağ tıklama > Follow address in stack

4. Adım:

USER32.MessageBoxExA’dan USER32.7E450747’ye RETURN mevcut.
USER32.7E450747’nin MessageBoxA olduğu çok açık.
(Nedenini anlamadıysanız user32.dll içerisindeki koda bakın)

Bu sebepten aradığımız fonksiyonun yeri:
Example_.00456FA7 (aşağıda işaretlenmiş)

Öneriler (Yöntem 3)

“stack tracing”den korunmak zordur. Bu durumda bir yöntem işe yarayabilir; tüm hassas “CALL” ve “RETN” komutlarını program içerisine “JMP” komutuyla yerleştirmek. Bu işlem “Binary Code Obfuscation” (Binary Kod Gizleme) olarak adlandırılır.
“Code Obfuscation”, orijinal program binary kodunun dönüştürülme tekniğidir, bu sayede statik ayrıştırma ile analiz edilmesi zorlaştırılmış olur. Böylelikle tersine mühendis şaşırtılmış olur, fakat bu yazılımınızı koruyamaz; sadece kodun analiz süresini uzatır.
“Code Obfuscation”daki temel fikir Veri ve Kod bölümlerini karıştırmaktır. Ek olarak, “Obfuscation”da “stack tracing” ve ayrıştırmaya engel olmak için aşağıdaki işlem kodları yerleştirilir:

- CALL ile PUSH, POP, RET ve JMP yer değiştirilir. Yerine PUSH ve RET ile JMP yerleştirilir. Örneğin:

Orijinal Kod (1):
PUSH 0
CALL 7E450747

Değiştirilen Kod (1):
PUSH 0
PUSH EIP + <bytes to next instruction>
JMP 7E450747

Orijinal Kod (2):
MOV EBX,1
RETN

Değiştirilen Kod (2):
POP EAX
JMP EAX

Orijinal Kod (3):
JMP 00456F94

Değiştirilen Kod (3):
PUSH 00456F94
RETN

- JE, JNZ, JL vb. ile JMP yerleştirilmesi her zaman işe yarar. Ek olarak, bu sayede tersine mühendisleri yanıltabilir ve sahte kod bölümlerine yönlendirebilirsiniz.

Orijinal Kod:
JMP 00456F94

Değiştirilmiş Kod:
MOV EAX, 1
CMP EAX, 0
JE <JUNK_CODE>
JNE 00456F94

- Ulaşılamayan bölümlerde parçalı komutlar eklenmeli.

- Offsetlere direk referansları engelleyin (örn: JMP 00456F94). Yanıltmak için basit işlemler kullanın ve sonrasında işlemi çağırın. Örneğin:

MOV EAX, 00456000      ; EAX = 00456000
ADD EAX, 00000F94      ; EAX = 00456F94
JMP EAX           ; JMP 00456F94

Binary Code Patching

Yöntem 1/6. Adım:

Bu seri numara girildiğinde geçerli olup olmadığına karar veren ve kullanıcıyı kayıt işlemini doğrulaması yönünde uyaran esas algoritma.
Başarıyla kodu yamamak ve akışı kontrol etmek için bir çok yok mevcut. Bunu yapmadan önce kodu analiz edip esas hedefi bulmamız gerekiyor.

1. Adım:

Üst tarafa çıkıp fonksiyonun başlangıcına bir kesme noktası ekliyoruz (Kesme noktası eklemek kesmek istediğiniz komutu seçin ve ardından F2 ye basın) > Programı çalıştırın

2. Adım:

Sırayla ilerleyerek her bir kodun ne işe yaradığını anlamaya çalışıyoruz.

Aşağıdaki resimde gördüğünüz gibi, 0045716F offsetindeki CALL komutu kullanıcının “Username:” metin kutusunda girmiş olduğu stringe dönüyor.

Kod Bölümü:

Geçerli Komut:

Stack:

0045718F offseti üzerindeki CALL komutu ise kullanıcının “Serial:” metin kutusuna girmiş olduğu stringe dönüyor.

Kod Bölümü:

Geçerli Komut:

Stack:

Aşağıdaki kod kullanıcı tarafından girilen seri numarasını EAX’a yüklüyor, sonrasında eşit olup olmadığını kontrol ediyor.
Görünen o ki 0045E5A8 ile işaretlenmiş değer (bkz. offset 0045719C) verilen serialin 004571A4 offsetinde EAX’a yüklenen ASCII değeri.

IfIf (EAX == null) {
//do something
}

Kayıt Penceresi:

Gördüğünüz gibi başka bir uzunluk kontrolü var. Bu kez hexadecimal 0×01 (desimal 1) ile mukayese edilen seri numaramızın uzunluğunu ESI barındırıyor (0xA Hexadecimal = 10 Decimal). Şayet seri numaramızın uzunluğu 1’e eşitse “Long/Short Error” çağrılıyor (bkz. Yöntem 1, 4. Adım)

Kod Bölümü:

Kayıt Penceresi:

Aşağıda işaretlenmiş olan kod seri numaranın desimal uzunluğundaki (10) ilk karakteri “1″e eşit olan ASCII 0×31 değeri ile karşılaştırıyor. Uzunluğun nasıl ASCII stringe dönüştürüldüğünü merak ediyorsanız offset 004571C3’ü takip edin sonrasında aşağıdaki döngüye bir göz atın.

Kod Bölümü:

Geçerli İşlem:

Aşağıdaki kısım yukarıdaki ile aynı işi yapıyor fakat ikinci numara için. Bu durumda, ikinci numara ASCII 0×34’e (“4″) eşit olmalı.

Program kodlarının bundan sonraki kısmı şu şekilde olacaktır:

char first = getChar(length,1,?); //İlk karakter
if (first != ‘1’) {
char second = getChar(length,2,?); //İkinci karakter
if(second != ‘4’) {
//Seri no kontrolü devam ediyor
}
else {
sendLongShortError();
}
}
else {
sendLongShortError();
}

Not: “?” karakteri bilinmeyen bir değeri gösteriyor. (Delphi compiler).
Büyük ihtimalle, girdiğimiz seri numarası geçerli uzunluk olan 14 ile eşleşmiyor. F9’a basarak seri numarayı tekrar giriyoruz.

3. Adım:

Aşağıda gösterildiği gibi offset 00457226’deki komutu takip ediyoruz (F7’ye basarak)

4. Adım:

Aşağıdaki koda bir göz atalım

Bu kod esas seri numara kontrolünü çalıştırıyor. Analiz yaparken gördüğünüz üzre offset 0045713C’de olduğu gibi sizi istenen kısımdan uzaklaştıracak bir çok sıçrama noktası var. Çoğu zaman da sizi istenilen sonuca götürecek olan bir çok yöntem vardır. Bunlar kodu analiz etme, yamama, yeniden yapılandırma gibi yöntemlerdir. Bu yazılımda sınırlı sayıda seçeneğimiz var. Sizinde görebildiğiniz gibi, aşağıdaki kod sadece seri numarayı kontrol etme ve sonuca göre uygun mesajı döndürerek kullanıcıya girmiş olduğu verinin başarılı veya başarısız olduğunu bildirme işlevini görüyor.
Aşağıdaki yöntem pratikte mümkün olmayabilir fakat, tersine mühendislerin nasıl çalıştığı konusunda temel bir fikir verecektir.

Yöntem 1 (Branch Patching)

Program akışını yamamanın bir yolu koşullu sapmaları değiştirmektir.
Kullanıcının verdiği seri numaranın geçersiz olduğuna karar veren doğrulama algoritması bir çok yerde mevcut.
Bunlar:

Kontrol 1:

Aşağıdaki binary analizde göründüğü gibi, fonksiyon seri no uzunluğunu ASCII verisine dönüştürüyor, sonrasında ilk karakteri 0×31 hex değeri (ASCII değeri “1″) ile karşılaştırıyor.

Bu kısıma basit bir yama uygulanabilir:
offset 004571DC üzerinde işlem koduna çift tıkla > “JE SHORT 004571E5” ile “JMP SHORT 004571E5”i yer değiştir
Bu işlemin sonucunda 004571DE’deki CALL komutu hiçbir zaman çağrılmayacaktır

Kontrol 2:

Benzer işlem offset 0045721D’de uygulanır

2. adımda binary kod yaması yapıldığında:

char first = getChar(length,1,?); //İlk karakter
if(true) { //bu her zaman true

char second = getChar(length,2,?); //İkinci karakter
if(true) { //bu her zaman true
//seri no kontrolü devam ediyor
}
else {
sendLongShortError(); //Bu hiçbir zaman çağrılmıyor
}
}
else {
sendLongShortError(); //Bu hiçbir zaman çağrılmıyor
}

Kontrol 3:

Koşullu jump ı koşulsuz jump ile yamayın (JMP)

Genellikle işe yarar. Bazen hatalar oluşabilir fakat temel mantığı anladığınızı düşünüyorum.

Yöntem 2 (Fonksiyon Değiştirme)

Basit bir yöntemde aşağıda göründüğü gibi “hata mesajı” fonksiyonunu değiştirip “başarılı” fonksiyonuna yönlendirmektir:

Seri No Oluşturma (Keygening)

Bu kategoride, bir “cracker” (sistem kırıcı) program kodunu analiz eder ve girilen seri numaranın doğru olduğunun kabul edileceği şekilde kayıt algoritmasını yeniden düzenler, her zaman doğru olarak kabul edilecek bir seri no anahtarı oluşturur (önceki kriterleri dikkate almaksızın). Bu Seri No Oluşturma Algoritmalarının yeniden düzenlenmesinde kullanılan bazı teknikler aşağıda sunulmuştur:

Kod Düzenleme

Bir fonksiyonun veya fonksiyon setinin çalışma mantığını anlamak amacıyla yapılan bir algoritma analizi için, tersine mühendis düşük seviye assembly kodlarını yüksek seviyede programlama dili kodları ile değiştirebilir (C, C++ veya .NET, Java gibi).

Örneğin:

Düşük Seviye;

004570AD |> /MOV EDX,DWORD PTR DS:[45E5A4]
004570B3 | |MOVZX EDX,BYTE PTR DS:[EDX+EBX-1]
004570B8 |. |ADD EBP,EDX
004570BA |. |INC EBX
004570BB |. |DEC EAX
004570BC |.^ \\JNZ SHORT Example_.004570AD
004570BE |> MOV EBX,0E
004570C3 |. MOV EAX,Example_.0045E5AC
004570C8 |. MOV EDX,Example_.0045E5BC
004570CD |> /MOVZX ECX,BYTE PTR DS:[EAX]
004570D0 |. |MOV DWORD PTR DS:[EDX],ECX
004570D2 |. |ADD EDX,4
004570D5 |. |INC EAX
004570D6 |. |DEC EBX
004570D7 |.^ \\JNZ SHORT Example_.004570CD
004570D9 |> CMP BYTE PTR DS:[45E5AC],7B

Yüksek Seviye (Java);

String username = getUsername();
int sum = 0;
for(int i = 0;i < username.length(); i++) {
sum += username.charAt(i);
}

String serial = getSerial();
int[] array = new int[255];
if(serial.length()<=255) {
for(int i = 0;i < serial.length(); i++) {
array = serial.charAt(i);
}
}
If(serial.charAt(0) == ‘{‘) {

Code Ripping

Bu yöntemle, bir programın binary kodunu bir başka programa kopyalamak veya assembly kodlamayı destekleyen yüksek seviyeli bir programlama dili içerisinde çalıştırmak için çeşitli teknikler kullanılır. Code Ripping ile önemli ölçüde azalan efor ve zaman sarfiyatı nedeniyle Kod Düzenleme yöntemi pek fazla tercih edilmez.

Örneğin:

Düşük Seviye;

004570AD |> /MOV EDX,DWORD PTR DS:[45E5A4]
004570B3 | |MOVZX EDX,BYTE PTR DS:[EDX+EBX-1]
004570B8 |. |ADD EBP,EDX
004570BA |. |INC EBX
004570BB |. |DEC EAX
004570BC |.^ \\JNZ SHORT Example_.004570AD
004570BE |> MOV EBX,0E
004570C3 |. MOV EAX,Example_.0045E5AC
004570C8 |. MOV EDX,Example_.0045E5BC
004570CD |> /MOVZX ECX,BYTE PTR DS:[EAX]
004570D0 |. |MOV DWORD PTR DS:[EDX],ECX
004570D2 |. |ADD EDX,4
004570D5 |. |INC EAX
004570D6 |. |DEC EBX
004570D7 |.^ \\JNZ SHORT Example_.004570CD
004570D9 |> CMP BYTE PTR DS:[45E5AC],7B

Yüksek Seviye Rip;

getUsername(username);
getPassword(password);
user_length := length(username);
pass_length := length(password);
asm
@loop1:
MOV EAX,user_length
MOV EBX,1
MOV EDX,&username
MOVZX EDX,BYTE [EDX+EBX-1]
ADD EBP,EDX
INC EBX
DEC EAX
JNZ @loop1
end;

Çeviri:
FaRuKS

Kaynak:
Nicolaou George – Charalambous Glafkos
Astalavista.Com