/* The easy way to calculate address of target symbol */ void fill_offsets_maps(struct process_hook *ph) { char *my_libc = NULL, *daemon_libc = NULL; int32_t dlopen_offset = 0; char *dlopen_mode = NULL; assert(ph); printf("[+] Using /proc/pid/maps method ...\n"); my_libc = find_libc_start(getpid()); if (!my_libc) { printf("[-] Unable to locate my own libc.\n"); return; } dlopen_mode = dlsym(NULL, "__libc_dlopen_mode"); if (dlopen_mode) printf("[+] My __libc_dlopen_mode: %p\n", dlopen_mode); else { printf("[-] Unable to locate my own dlopen address.\n"); return; } dlopen_offset = dlopen_mode - my_libc; daemon_libc = find_libc_start(ph->pid); if (!daemon_libc) { printf("[-] Unable to locate target's libc.\n"); return; } printf("[+] Foreign libc start: %p\n", daemon_libc); ph->dlopen_address = daemon_libc + dlopen_offset; }
int main(int argc, char **argv) { pid_t daemon_pid = -1; char *my_libc = NULL, *daemon_libc = NULL; char *dl_open_address = NULL; char *dlopen_mode = NULL; FILE *pfd = NULL; char buf[128], *space = NULL; /* nm /lib64/libc.so.6|grep __libc_dlopen_mode: 00000000000f2a40 t __libc_dlopen_mode */ size_t dlopen_offset = 0; if (argc < 3) { usage(argv[0]); return 1; } setbuffer(stdout, NULL, 0); my_libc = find_libc_start(getpid()); printf("Trying to obtain __libc_dlopen_mode() address relative to libc start address.\n"); printf("[1] Using my own __libc_dlopen_mode ...\n"); dlopen_mode = dlsym(NULL, "__libc_dlopen_mode"); if (dlopen_mode) dlopen_offset = dlopen_mode - my_libc; if (dlopen_offset == 0 && (pfd = popen("nm /lib64/libc.so.6|grep __libc_dlopen_mode", "r")) != NULL) { printf("[2] Using nm method ... "); fgets(buf, sizeof(buf), pfd); if ((space = strchr(buf, ' ')) != NULL) *space = 0; dlopen_offset = strtoul(buf, NULL, 16); fclose(pfd); } if (dlopen_offset == 0) { printf("failed!\nNo more methods, bailing out.\n"); return 1; } printf("success!\n"); dl_open_address = find_libc_start(getpid()) + dlopen_offset; daemon_pid = (pid_t)atoi(argv[1]); daemon_libc = find_libc_start(daemon_pid); printf("me: {__libc_dlopen_mode:%p, dlopen_offset:%zx}\n=> daemon: {__libc_dlopen_mode:%p, libc:%p}\n", dl_open_address, dlopen_offset, daemon_libc + dlopen_offset, daemon_libc); inject_code(daemon_pid, (size_t)daemon_libc, (size_t)(daemon_libc + dlopen_offset), argv[2]); printf("done!\n"); return 0; }
/* The last chance if nothing above worked */ void fill_offsets_nm(struct process_hook *ph) { FILE *pfd = NULL; char buf[128], *space = NULL, *daemon_libc = NULL; size_t dlopen_offset = 0; assert(ph); printf("[+] Using nm method ...\n"); daemon_libc = find_libc_start(ph->pid); if (!daemon_libc) { printf("[-] Unable to locate foreign libc.\n"); return; } memset(buf, 0, sizeof(buf)); if (((pfd = popen("nm /lib64/libc.so.6|grep __libc_dlopen_mode", "r")) != NULL || (pfd = popen("nm /lib/libc.so.6|grep __libc_dlopen_mode", "r")) != NULL)) { /* to make ubuntu's gcc happy! */ if (!fgets(buf, sizeof(buf), pfd)) ; if ((space = strchr(buf, ' ')) != NULL) *space = 0; dlopen_offset = strtoul(buf, NULL, 16); fclose(pfd); } if (!dlopen_offset) { printf("[-] Unable to locate symbol via nm.\n"); return; } ph->dlopen_address = daemon_libc + dlopen_offset; }