• 01 TEMMUZ 2020
  • Okunma Sayısı: 193

Olcay ESİR - Karaelmas Malware Hunter Team

olcayesir7@gmail.com


Manual Unpacking bazen hızlı bir şekilde, minimum çaba ile yapılabilirken; bazen de uzun, zorlu bir süreç gerektirebilir. Bir programı manuel olarak unpacklemek için iki yaygın yaklaşım vardır.

- Packing algoritmasını inceleyerek tersine çalıştırmak için bir program yazılabilir. Algoritmayı ters yönde çalıştırarak paketlemenin adımları tersine çevrilir. (Static)

- Packlenmiş programı çalıştırabilir adım adım gözlemleyip OEP’e gelindiğinde dump alarak unpack işlemi tamamlanabilir (Dynamic)

Static Unpack

Bu bölümde örnek olarak Ldpinch zararlısını unpacklemeye çalışacağız. Ldpinch zararlısı manual olarak packlenmiş bir yazılımdır. Static olarak nasıl unpackleneceğini Cutter tersine mühendislik aracı ile ele alalım.

Cutter üzerinde Ldpinch zararlısını incelediğimizde ilk olarak Comments kısmında Code Section’a ait –rwx özelliği daha doğrusu Write yetkisi dikkat çekmektedir. Bu olay, örnek yürütülürken kodun üzerine yazmanın mümkün olduğu anlamına gelmektedir. Güvenlik nedeniyle kod bölümü yalnızca okunur ve çalıştırılabilirdir. Amacımız kodu tekrar okunabilir hale getirmektir. Bunu static olarak başarabilmek için bir unpacker yazılması gerekmektedir.

Cutter’ın graph moduna geçersek Entry0 noktasında dört temel bloğu ve ardından beşinci bloğu göreceğiz.

İkinci ve dördüncü bloklarda bir miktar bellek alanı üzerinde çalışan döngüler görünmektedir. Büyük olasılıkla ilk dört blok açıcıdır. Şimdi blokların her birinin üzerinden geçip ne yaptıklarını tespit etmeye çalışmalıyız.

İlk satırda bl değişkeni 0x88 değerini almaktadır. Toplamda iki satırda neg bl komutuyla karşılaştık. İki kere -1 ile çarpma işlemine alınan bl değişkeninde bulunan değer değişmemektedir. Not bl komutuna iki kere rastlanmaktadır. İki kere kullanılan bu komutta neg komutu gibi bir anlam ifade etmemekte yani değeri değiştirmemektedir. Bunların yanında iki kere kullanılan ror bl , 4 komutu da bl değişkeninde bulunan 0x88 değerini yani ikilik tabanda 01011000 değerini 8 bit sağa kaydırmaktadır. Bu da değerin tekrar eski haline dönmesine sebep olan, değer değiştirmeyen bir koddur.

Eğer gereksiz satırları ortadan kaldıracak olursak;

satırları elimizde kalmaktadır. İlk bloktan edindiğimiz bilgilere göre bl=0x88 ve eax=0x10001080 diyebiliriz.

İlk satırda eax adresinde bulunan değer, bl ile XOR işlemine alınıyor. EAX, 0x10002373 değerine eşit olana kadar döngü devam etmektedir. EAX; iki kere inc , bir kere de dec işlemine alınmaktadır. Sonuç olarak bir kere artırıldığı görülmektedir. Sonuç olarak 0x10001080 – 0x10002373 aralığında tekrarlandığı ve 0x88 değerinin XOR işlemine alındığı görülmektedir. Static Unpackerımızın kodlaması içerisinde yer alacak ilk for bloğumuz buradan yola çıkarak oluşturulabilir.

Bu blokta ilk işlem bh değişkenine 0x54 değerinin atanmasıyla birlikte eax de ilk bloktaki değerine tekrar atandığı görülmektedir.

0x10001080 – 0x10002373 aralığında bir döngü olduğu görülmektedir. Bu alandaki her byte 0x9f ile XOR’lanmaktadır. 0x10002717 adresi tam olarak 0x9f değerinin kodda yazıldığı yerdir. Bh 0x54 ile başladıktan sonra üzerine 0x12 eklenir , 0x68 ile XOR işlemine alınır ve 4 çıkartılır. Elde edilen yeni bh değeri paketlenmiş byteın XORlanması için kullanıldığı anlaşılmaktadır.

Dördüncü blok kendini değiştiren bir kod yapısına sahiptir. Her yinelemede, kod kendisini değiştirir ve paketlenmiş kod bölgesindeki byteların XOR işlemi için yeni bir anahtar hesaplar.

Elde edilen bilgilere dayanarak Unpackerımızı yazabiliriz. Argüman olarak paketlenmiş bellek bölgesinin başlangıç ve bitiş adresini almamız gerekmektedir. Her blokta edindiğimiz bilgileri C dilinde kodlamaya dökersek aşağıdaki gibi bir kod ortaya çıkmaktadır;

Dinamik Unpack

Bir C kodu yazıp derleyelim.

Elimizde iki adet executable packlenmiş halde bulunmaktadır. Packlemiş executableları dinamik olarak unpacklemek için OllyDbg aracını kullanacağız. Örnek 1 ve örnek 2 exelerini OllyDbg yardımıyla açıp OEP’i bulmamız gerekiyor.Bunun için OllyDbg’ın bize sağladığı bir özelliği kullanacağız.

Plugins sekmesinin altında bulunan OllyDump pluginine gelerek Find OEP by Section Hop seçeneğine tıklıyoruz. Bu özellik OEP taraması yapıp bizi OEP noktasına götürecektir. Bu işlem örnek 1 için bir sonuç vermedi.

Normalde bu işlemi yapmak üzere otomatik toollar var. Fakat bu toolların başarısız olması durumunda manual olarak aramak zorunda kalabiliriz. Bu örnek için manual olarak OEP’i bulacağız. En basit yöntem ;unpack edilme sürecinden sonra OEP’e atlanacağı için jump komutlarına odaklanacağız.

Graph modunda uygulamamızı incelediğimizde kuyruk atlaması(Tail jumps) kırmızı renkle belirtildiğini görüyoruz.

Kuyruk atlama noktası orjinal programa programa aktarma yapar. IDA Pro üzerinde bulmuş olduğumuz adrese OllyDbg üzerinde breakpoint koyuyoruz.

Breakpoint tetiklendikten sonra bir adım ilerleterek OEP’e ulaşıyoruz.

Bulmuş olduğumuz OEP noktasından sonra bir dump almamız gerekiyor. Dump almak için OllyDump pluginini kullanacağız. Bulduğum OEP Modify kısmında kendiliğinden yazılıyor.

Dump işlemi bittikten sonra ImpRec programı üzerinde UNPACKLENMEMİŞ exeyi seçiyoruz. OEP yerine dump ederken bulmuş olduğumuz adresi yazıyoruz. Sonrasında IAT AutoSearch butonuna tıklıyoruz. Başarılı olduğunu bir bildirimle birlikte görüyoruz.

Get İmports’a tıkladıktan sonra Fix Dump ile OllDbg üzerinden Dumpını aldığımız exeyi seçiyoruz ve Unpackleme işlemini bitirmiş oluyoruz.

 

TÜM MAKALELER