Hem bir IDA eklentisi hem de bir Python betiği olarak kullanılabilen Nimfilt, paket ve işlev adlarını ayırarak ve dizelere yapılar uygulayarak Nim programlama dili derleyicisi ile derlenen ikili dosyalarda tersine mühendislik yapılmasına yardımcı olur
Nim programlama dili, güçlü derleyicisi ve diğer dillerle kolayca çalışabilmesi nedeniyle kötü amaçlı yazılım geliştiricileri için giderek daha cazip hale geliyor. Nim’in derleyicisi Nim’i JavaScript, C, C++ ve Objective-C’ye derleyebilir ve Windows, Linux, macOS, Android ve iOS gibi başlıca işletim sistemleri için çapraz derleme yapabilir. Ayrıca Nim, yukarıda belirtilen dillerden fonksiyon ve sembollerin içe aktarılmasını ve Windows için dinamik olarak bağlı kütüphanelerden ve Linux için paylaşılan kütüphanelerden içe aktarılmasını destekler. İşletim sistemiyle etkileşimi sorunsuz hale getiren Winim gibi Nim sarmalayıcı modülleri de mevcuttur. Tüm bu özellikler Nim’in bu dilleri kullanan geliştirme hatlarına kolayca entegre edilmesini sağlar ve hem iyi huylu hem de kötü huylu yeni araçların geliştirilmesini destekler.
Bu nedenle ESET Research’ün Nim’de geliştirilen kötü amaçlı yazılımların vahşi doğada sürekli kullanıldığını görmesi şaşırtıcı değil. Sednit’in Nim ile yazılmış kötü amaçlı bir indirici kullandığı 2019 yılında tespit edilmişti. Nim oyununu oynayan ve Nimfilt‘i geliştiren bir diğer kötü şöhretli grup ise Mustang Panda APT grubu. ESET Research, Mustang Panda’nın araç setinde Nim‘i ilk kez Ağustos 2023’te Slovakya’daki bir devlet kurumuna karşı düzenlenen bir kampanyada kullandığını kaydetti. Tespit edilen ve grubun klasik trident Korplug yükleyicisinin bir parçası olarak kullanılan kötü amaçlı DLL, Nim’de yazılmıştı.
Bu tür ikili dosyaların tersine mühendisliğini yapmakla görevli araştırmacılar için Nimfilt, analizi hızlandırmada güçlü bir araçtır. Nimfilt hem komut satırında (işlevselliğinin bir alt kümesi ile) hem de Hex-Rays’in IDA programında bir Python betiği olarak çalıştırılabilirken burada esas olarak IDA için bir Python eklentisi olarak sunulacaktır.
Nimfilt’in IDA’da Başlatılması
IDA ilk açıldığında, IDA plugins dizinindeki tüm eklentileri yükler ve başlatır. Nimfilt’in başlatılması sırasında eklenti, demonte ikilinin Nim derleyicisi ile derlenip derlenmediğini belirlemek için temel sezgisel yöntemler kullanır. Aşağıdaki kontrollerden biri geçilirse Nimfilt bu derleyicinin kullanıldığını belirler:
- İkili, aşağıdaki dizelerin her ikisini de içerir:
- fatal.nim
- sysFatal
- İkili, aşağıdaki iyi bilinen Nim işlev adlarından herhangi birini içerir:
- NimMain
- NimMainInner
- NimMainModule
- İkili dosyada aşağıdaki hata mesajı dizelerinden en az ikisi bulunur:
- @value out of range
- @division by zero
- @over- or underflow
- @index out of bounds
YARA kuralları, bir ELF veya PE dosyasının Nim ile derlenip derlenmediğini belirlemek için benzer kontroller yapan Nimfilt ile birlikte sağlanır. Bu kontroller birlikte şu anda sadece PE dosyalarının .rdata bölümünü io.nim veya fatal.nim dizesi için kontrol eden Detect It Easy gibi diğer araçlar tarafından benimsenen yaklaşımdan çok daha sağlamdır.
Son başlatma adımı olarak, Nimfilt’in AUTO_RUN bayrağı doğru olarak ayarlanmışsa eklenti hemen çalışır. Aksi takdirde Nimfilt, IDA’nın eklentiler menüsünden her zamanki gibi çalıştırılabilir.
Nimfilt ile Demangling
Nim, Nimfilt’in çözebileceği özel bir isim değiştirme şeması kullanır. Bir çalıştırma sırasında, Nimfilt ikili dosyadaki her işlev adını yineleyerek adın bir Nim paketi mi yoksa işlev adı mı olduğunu kontrol eder. Keşfedilen isimler demangled formlarına yeniden adlandırılır.
İlginç bir şekilde, bu isimler PDB yolları ile aynı şekilde geliştiricinin ortamı hakkında bilgi sızdırabilir. Bunun nedeni Nim derleyicisinin dosya yolunu birleştirme sırasında isme eklemesidir. (Nimfilt yolu birleştirme sırasında ortaya çıkarır)
Örneğin üçüncü taraf paketlerdeki fonksiyon adları, birleştirme işlemi sırasında mutlak yollar olarak saklanır. Şekil 2 Nim’in varsayılan paket yöneticisi olan nimble için geliştiricinin yükleme yoluyla birlikte kullanılan nimSHA2 paketinin sürümünü ve sağlama toplamını ortaya çıkaran mutlak bir yol olarak depolanan bir işlev adını gösterir.
python nimfilt.py GET_UINT32_BE__6758Z85sersZ85serOnameZOnimbleZpkgs50Znim837265504548O49O494554555453d57a4852c515056c5452eb5354b51fa5748f5253545748505752cc56fdZnim83726550_u68
C:/Users/User.name/.nimble/pkgs2/nimSHA2-0.1.1-6765d9a04c328c64eb56b3fa90f45690294cc8fd/nimSHA2::GET_UINT32_BE u68
Şekil 2. Üçüncü taraf bir paketten bir işlevin adını ayırma
Tam tersine, Şekil 3 göreli bir yol (yani Nim kurulum yoluna göreli) olarak saklanan standart bir Nim paketindeki bir işlevin adını gösterir.
python nimfilt.py toHex__pureZstrutils_u2067
pure/strutils::toHex u2067
Şekil 3. Standart bir Nim paketinden bir işlevin adını ayırma
Ancak isimler her zaman aynı şekilde karıştırılmamaktadır. Şekil 4 yukarıdaki nimSHA2 paketindeki aynı işlev adının Linux’ta göreli bir yol olarak depolandığını gösterir.
python nimfilt.py GET_UINT32_BE__OOZOOZOOZhomeZalexZOnimbleZpkgs50Znim837265504548O49O494554555453d57a4852c515056c5452eb5354b51fa5748f5253545748505752cc56fdZnim83726550_u49
../../../home/alex/.nimble/pkgs2/nimSHA2-0.1.1-6765d9a04c328c64eb56b3fa90f45690294cc8fd/nimSHA2::GET_UINT32_BE u49
Şekil 4. Linux’ta üçüncü taraf bir paketten bir işlevin adını ayırma
Paket başlatma işlevleri tamamen farklı bir şekilde karıştırılır: Paket adı, işlev adından önce konumlandırılmış bir dosya yolu (dosya uzantısı dahil) olarak saklanır ve ileri eğik çizgiler, kısa çizgiler ve noktalar gibi belirli karakterleri temsil etmek için bir kaçış şeması kullanılır. Nimfilt, demangling işleminin ardından .nim dosya uzantısını kaldırarak paket adını temizler. (Şekil 5)
python nimfilt.py atmdotdotatsdotdotnimbleatspkgsatswinimminus3dot9dot1atswinimatsincatswinbasedotnim_DatInit000
../../.nimble/pkgs/winim-3.9.1/winim/inc/winbase::DatInit000
Şekil 5. Üçüncü taraf bir paketten bir başlatma işlevinin adını ayırma
Şekil 6 yerel paketlerdeki başlatma işlevlerinin adlarının mutlak yollar olarak nasıl saklandığını gösterir.
python nimfilt.py atmCatcatstoolsatsNimatsnimminus2dot0dot0atslibatssystemdotnim_Init000
C:/tools/Nim/nim-2.0.0/lib/system::Init000
Şekil 6. Yerel bir paketten başlatma işlevinin adını ayırma
IDA’da, Nimfilt’in isim ayrıştırma işlemini, fonksiyonları paket adlarına veya yollarına göre düzenlemek için Fonksiyonlar penceresinde dizinlerin oluşturulması izler. (Şekil 7)
Yapıları, Nim Dizelerine Uygulama
Nimfilt’in çalıştırılması sırasında gerçekleştirilen son işlem, Nim dizelerine C tarzı yapılar uygulamaktır. Tıpkı diğer bazı programlama dillerindeki dizgilerin boş sonlandırılmış bayt dizileri yerine nesneler olması gibi Nim’deki dizgiler de öyledir. Şekil 8 ABCDEF dizesinin Nimfilt çalıştırılmadan önce ve sonra IDA’da nasıl göründüğünü gösterir. Demonte formda, Nim tarafından derlenmiş bir ikili dosyanın bazı değişkenlerin geçici adının bir parçası olarak _TM önekini kullandığına dikkat edin; bunlar genellikle Nim dizeleridir.
Nimfilt, .rdata veya .rodata segmentindeki ve diğer salt okunur veri segmentlerindeki her adresi yineleyerek Nim dizelerini arar. Yapılar bulunan dizelere uygulanır; yapı bir uzunluk alanı ve dizedeki karakterlerden oluşan yüke bir işaretçi içerir.
Özet
Nim kaynak kodu, çalıştırılabilir olarak derlenmeye giderken genellikle C veya C++’a çevrilir ancak bu işlem Nim’in tüm izlerini tamamen ortadan kaldırmaz. Nim derleyici kaynak kodunda bir yolculuğa çıkarak, derleme sürecinde izlenen yollardan bazılarını çözdük ve böylece bu çözüme yardımcı olmak için bir Python aracı ve IDA eklentisi olarak Nimfilt’i oluşturabildik.
Kısacası, Nim’de yeni olsanız da olmasanız da Nimfilt’e başvurmak, Nim tarafından derlenmiş ikili dosyalarla tersine mühendislik çalışmalarınızı neredeyse anında daha kolay ve daha odaklı hale getirecektir. Bununla birlikte Nimfilt’in gelişimi hiçbir şekilde durma noktasında değildir; çift karıştırmayı işlemek ve karışık isimlerin biçimlendirilmesini ve paket adlarının gruplandırılmasını iyileştirmek için ek özellikler üzerinde çalışıyoruz.